2004-09-23 06:34:27 +02:00
/*
* IWineD3D implementation
*
* Copyright 2002 - 2004 Jason Edmeades
* Copyright 2003 - 2004 Raphael Junqueira
* Copyright 2004 Christian Costa
2005-06-23 13:05:24 +02:00
* Copyright 2005 Oliver Stieber
2008-10-18 19:21:20 +02:00
* Copyright 2007 - 2008 Stefan Dösinger for CodeWeavers
2009-09-16 08:37:15 +02:00
* Copyright 2009 Henri Verbeet for CodeWeavers
2004-09-23 06:34:27 +02:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
2006-05-18 14:49:52 +02:00
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
2004-09-23 06:34:27 +02:00
*/
# include "config.h"
2010-04-05 21:10:15 +02:00
# include <stdio.h>
2004-09-23 06:34:27 +02:00
# include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL ( d3d ) ;
WINE_DECLARE_DEBUG_CHANNEL ( d3d_caps ) ;
2009-03-11 10:15:09 +01:00
# define GLINFO_LOCATION (*gl_info)
2010-01-25 19:51:32 +01:00
# define WINE_DEFAULT_VIDMEM (64 * 1024 * 1024)
2009-03-11 10:15:09 +01:00
2008-03-13 15:14:00 +01:00
/* The d3d device ID */
static const GUID IID_D3DDEVICE_D3DUID = { 0xaeb2cdd4 , 0x6e41 , 0x43ea , { 0x94 , 0x1c , 0x83 , 0x61 , 0xcc , 0x76 , 0x07 , 0x81 } } ;
2007-06-26 23:05:41 +02:00
/* Extension detection */
static const struct {
const char * extension_string ;
GL_SupportedExt extension ;
2007-11-11 13:59:49 +01:00
DWORD version ;
2007-06-26 23:05:41 +02:00
} EXTENSION_MAP [ ] = {
/* APPLE */
2007-11-11 13:59:49 +01:00
{ " GL_APPLE_client_storage " , APPLE_CLIENT_STORAGE , 0 } ,
{ " GL_APPLE_fence " , APPLE_FENCE , 0 } ,
2008-02-13 14:22:40 +01:00
{ " GL_APPLE_float_pixels " , APPLE_FLOAT_PIXELS , 0 } ,
2010-01-02 14:20:59 +01:00
{ " GL_APPLE_flush_buffer_range " , APPLE_FLUSH_BUFFER_RANGE , 0 } ,
2010-01-21 10:38:27 +01:00
{ " GL_APPLE_flush_render " , APPLE_FLUSH_RENDER , 0 } ,
{ " GL_APPLE_ycbcr_422 " , APPLE_YCBCR_422 , 0 } ,
2007-06-26 23:05:41 +02:00
/* ARB */
2008-06-19 00:36:28 +02:00
{ " GL_ARB_color_buffer_float " , ARB_COLOR_BUFFER_FLOAT , 0 } ,
2009-06-08 10:35:05 +02:00
{ " GL_ARB_depth_buffer_float " , ARB_DEPTH_BUFFER_FLOAT , 0 } ,
2009-09-01 09:09:35 +02:00
{ " GL_ARB_depth_clamp " , ARB_DEPTH_CLAMP , 0 } ,
2009-06-05 10:10:47 +02:00
{ " GL_ARB_depth_texture " , ARB_DEPTH_TEXTURE , 0 } ,
2007-11-11 13:59:49 +01:00
{ " GL_ARB_draw_buffers " , ARB_DRAW_BUFFERS , 0 } ,
{ " GL_ARB_fragment_program " , ARB_FRAGMENT_PROGRAM , 0 } ,
{ " GL_ARB_fragment_shader " , ARB_FRAGMENT_SHADER , 0 } ,
2009-09-23 10:05:54 +02:00
{ " GL_ARB_framebuffer_object " , ARB_FRAMEBUFFER_OBJECT , 0 } ,
2009-03-05 12:30:43 +01:00
{ " GL_ARB_geometry_shader4 " , ARB_GEOMETRY_SHADER4 , 0 } ,
2007-11-11 13:59:49 +01:00
{ " GL_ARB_half_float_pixel " , ARB_HALF_FLOAT_PIXEL , 0 } ,
2010-01-21 10:38:27 +01:00
{ " GL_ARB_half_float_vertex " , ARB_HALF_FLOAT_VERTEX , 0 } ,
2007-11-11 13:59:49 +01:00
{ " GL_ARB_imaging " , ARB_IMAGING , 0 } ,
2010-01-28 20:50:55 +01:00
{ " GL_ARB_map_buffer_range " , ARB_MAP_BUFFER_RANGE , 0 } ,
2007-11-11 13:59:49 +01:00
{ " GL_ARB_multisample " , ARB_MULTISAMPLE , 0 } , /* needs GLX_ARB_MULTISAMPLE as well */
{ " GL_ARB_multitexture " , ARB_MULTITEXTURE , 0 } ,
{ " GL_ARB_occlusion_query " , ARB_OCCLUSION_QUERY , 0 } ,
{ " GL_ARB_pixel_buffer_object " , ARB_PIXEL_BUFFER_OBJECT , 0 } ,
{ " GL_ARB_point_parameters " , ARB_POINT_PARAMETERS , 0 } ,
{ " GL_ARB_point_sprite " , ARB_POINT_SPRITE , 0 } ,
2009-09-23 10:05:58 +02:00
{ " GL_ARB_provoking_vertex " , ARB_PROVOKING_VERTEX , 0 } ,
2010-01-21 10:38:27 +01:00
{ " GL_ARB_shader_objects " , ARB_SHADER_OBJECTS , 0 } ,
{ " GL_ARB_shader_texture_lod " , ARB_SHADER_TEXTURE_LOD , 0 } ,
2010-01-27 20:19:39 +01:00
{ " GL_ARB_shading_language_100 " , ARB_SHADING_LANGUAGE_100 , 0 } ,
2010-01-25 19:51:29 +01:00
{ " GL_ARB_sync " , ARB_SYNC , 0 } ,
2007-11-11 13:59:49 +01:00
{ " GL_ARB_texture_border_clamp " , ARB_TEXTURE_BORDER_CLAMP , 0 } ,
{ " GL_ARB_texture_compression " , ARB_TEXTURE_COMPRESSION , 0 } ,
{ " GL_ARB_texture_cube_map " , ARB_TEXTURE_CUBE_MAP , 0 } ,
{ " GL_ARB_texture_env_add " , ARB_TEXTURE_ENV_ADD , 0 } ,
{ " GL_ARB_texture_env_combine " , ARB_TEXTURE_ENV_COMBINE , 0 } ,
{ " GL_ARB_texture_env_dot3 " , ARB_TEXTURE_ENV_DOT3 , 0 } ,
{ " GL_ARB_texture_float " , ARB_TEXTURE_FLOAT , 0 } ,
{ " GL_ARB_texture_mirrored_repeat " , ARB_TEXTURE_MIRRORED_REPEAT , 0 } ,
2008-07-09 01:59:10 +02:00
{ " GL_ARB_texture_non_power_of_two " , ARB_TEXTURE_NON_POWER_OF_TWO , MAKEDWORD_VERSION ( 2 , 0 ) } ,
2007-11-26 23:19:03 +01:00
{ " GL_ARB_texture_rectangle " , ARB_TEXTURE_RECTANGLE , 0 } ,
2008-12-17 23:20:02 +01:00
{ " GL_ARB_texture_rg " , ARB_TEXTURE_RG , 0 } ,
2010-01-25 19:51:31 +01:00
{ " GL_ARB_vertex_array_bgra " , ARB_VERTEX_ARRAY_BGRA , 0 } ,
2007-11-11 13:59:49 +01:00
{ " GL_ARB_vertex_blend " , ARB_VERTEX_BLEND , 0 } ,
{ " GL_ARB_vertex_buffer_object " , ARB_VERTEX_BUFFER_OBJECT , 0 } ,
{ " GL_ARB_vertex_program " , ARB_VERTEX_PROGRAM , 0 } ,
{ " GL_ARB_vertex_shader " , ARB_VERTEX_SHADER , 0 } ,
2010-01-21 10:38:27 +01:00
/* ATI */
{ " GL_ATI_fragment_shader " , ATI_FRAGMENT_SHADER , 0 } ,
{ " GL_ATI_separate_stencil " , ATI_SEPARATE_STENCIL , 0 } ,
{ " GL_ATI_texture_compression_3dc " , ATI_TEXTURE_COMPRESSION_3DC , 0 } ,
{ " GL_ATI_texture_env_combine3 " , ATI_TEXTURE_ENV_COMBINE3 , 0 } ,
{ " GL_ATI_texture_mirror_once " , ATI_TEXTURE_MIRROR_ONCE , 0 } ,
2007-06-26 23:05:41 +02:00
/* EXT */
2008-01-13 00:32:24 +01:00
{ " GL_EXT_blend_color " , EXT_BLEND_COLOR , 0 } ,
2008-02-16 16:42:11 +01:00
{ " GL_EXT_blend_equation_separate " , EXT_BLEND_EQUATION_SEPARATE , 0 } ,
{ " GL_EXT_blend_func_separate " , EXT_BLEND_FUNC_SEPARATE , 0 } ,
2010-01-21 10:38:27 +01:00
{ " GL_EXT_blend_minmax " , EXT_BLEND_MINMAX , 0 } ,
2010-03-25 22:51:23 +01:00
{ " GL_EXT_draw_buffers2 " , EXT_DRAW_BUFFERS2 , 0 } ,
2007-11-11 13:59:49 +01:00
{ " GL_EXT_fog_coord " , EXT_FOG_COORD , 0 } ,
{ " GL_EXT_framebuffer_blit " , EXT_FRAMEBUFFER_BLIT , 0 } ,
2008-10-20 00:15:13 +02:00
{ " GL_EXT_framebuffer_multisample " , EXT_FRAMEBUFFER_MULTISAMPLE , 0 } ,
2007-11-11 13:59:49 +01:00
{ " GL_EXT_framebuffer_object " , EXT_FRAMEBUFFER_OBJECT , 0 } ,
2010-01-21 10:38:27 +01:00
{ " GL_EXT_gpu_program_parameters " , EXT_GPU_PROGRAM_PARAMETERS , 0 } ,
2010-01-24 21:16:10 +01:00
{ " GL_EXT_gpu_shader4 " , EXT_GPU_SHADER4 , 0 } ,
2009-06-05 10:10:48 +02:00
{ " GL_EXT_packed_depth_stencil " , EXT_PACKED_DEPTH_STENCIL , 0 } ,
2007-11-11 13:59:49 +01:00
{ " GL_EXT_paletted_texture " , EXT_PALETTED_TEXTURE , 0 } ,
{ " GL_EXT_point_parameters " , EXT_POINT_PARAMETERS , 0 } ,
2009-08-10 09:30:49 +02:00
{ " GL_EXT_provoking_vertex " , EXT_PROVOKING_VERTEX , 0 } ,
2007-11-11 13:59:49 +01:00
{ " GL_EXT_secondary_color " , EXT_SECONDARY_COLOR , 0 } ,
{ " GL_EXT_stencil_two_side " , EXT_STENCIL_TWO_SIDE , 0 } ,
{ " GL_EXT_stencil_wrap " , EXT_STENCIL_WRAP , 0 } ,
2007-11-06 13:07:33 +01:00
{ " GL_EXT_texture3D " , EXT_TEXTURE3D , MAKEDWORD_VERSION ( 1 , 2 ) } ,
2008-07-23 17:39:04 +02:00
{ " GL_EXT_texture_compression_rgtc " , EXT_TEXTURE_COMPRESSION_RGTC , 0 } ,
2010-01-21 10:38:27 +01:00
{ " GL_EXT_texture_compression_s3tc " , EXT_TEXTURE_COMPRESSION_S3TC , 0 } ,
2007-11-11 13:59:49 +01:00
{ " GL_EXT_texture_env_add " , EXT_TEXTURE_ENV_ADD , 0 } ,
{ " GL_EXT_texture_env_combine " , EXT_TEXTURE_ENV_COMBINE , 0 } ,
{ " GL_EXT_texture_env_dot3 " , EXT_TEXTURE_ENV_DOT3 , 0 } ,
{ " GL_EXT_texture_filter_anisotropic " , EXT_TEXTURE_FILTER_ANISOTROPIC , 0 } ,
{ " GL_EXT_texture_lod_bias " , EXT_TEXTURE_LOD_BIAS , 0 } ,
2010-01-21 10:38:27 +01:00
{ " GL_EXT_texture_sRGB " , EXT_TEXTURE_SRGB , 0 } ,
2009-01-08 10:19:17 +01:00
{ " GL_EXT_vertex_array_bgra " , EXT_VERTEX_ARRAY_BGRA , 0 } ,
2007-06-26 23:05:41 +02:00
/* NV */
2010-01-21 10:38:27 +01:00
{ " GL_NV_depth_clamp " , NV_DEPTH_CLAMP , 0 } ,
2007-11-11 13:59:49 +01:00
{ " GL_NV_fence " , NV_FENCE , 0 } ,
{ " GL_NV_fog_distance " , NV_FOG_DISTANCE , 0 } ,
{ " GL_NV_fragment_program " , NV_FRAGMENT_PROGRAM , 0 } ,
{ " GL_NV_fragment_program2 " , NV_FRAGMENT_PROGRAM2 , 0 } ,
2010-01-21 10:38:27 +01:00
{ " GL_NV_fragment_program_option " , NV_FRAGMENT_PROGRAM_OPTION , 0 } ,
{ " GL_NV_half_float " , NV_HALF_FLOAT , 0 } ,
{ " GL_NV_light_max_exponent " , NV_LIGHT_MAX_EXPONENT , 0 } ,
2007-11-11 13:59:49 +01:00
{ " GL_NV_register_combiners " , NV_REGISTER_COMBINERS , 0 } ,
{ " GL_NV_register_combiners2 " , NV_REGISTER_COMBINERS2 , 0 } ,
{ " GL_NV_texgen_reflection " , NV_TEXGEN_REFLECTION , 0 } ,
{ " GL_NV_texture_env_combine4 " , NV_TEXTURE_ENV_COMBINE4 , 0 } ,
{ " GL_NV_texture_shader " , NV_TEXTURE_SHADER , 0 } ,
{ " GL_NV_texture_shader2 " , NV_TEXTURE_SHADER2 , 0 } ,
{ " GL_NV_vertex_program " , NV_VERTEX_PROGRAM , 0 } ,
{ " GL_NV_vertex_program1_1 " , NV_VERTEX_PROGRAM1_1 , 0 } ,
{ " GL_NV_vertex_program2 " , NV_VERTEX_PROGRAM2 , 0 } ,
2009-05-08 18:02:27 +02:00
{ " GL_NV_vertex_program2_option " , NV_VERTEX_PROGRAM2_OPTION , 0 } ,
2007-11-11 13:59:49 +01:00
{ " GL_NV_vertex_program3 " , NV_VERTEX_PROGRAM3 , 0 } ,
2007-08-31 20:56:15 +02:00
/* SGI */
2007-11-11 13:59:49 +01:00
{ " GL_SGIS_generate_mipmap " , SGIS_GENERATE_MIPMAP , 0 } ,
2007-06-26 23:05:41 +02:00
} ;
2004-09-29 23:26:47 +02:00
/**********************************************************
* Utility functions follow
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-08-27 17:42:40 +02:00
static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat ( IWineD3D * iface , UINT Adapter , WINED3DDEVTYPE DeviceType , WINED3DFORMAT AdapterFormat , DWORD Usage , WINED3DRESOURCETYPE RType , WINED3DFORMAT CheckFormat , WINED3DSURFTYPE SurfaceType ) ;
2008-02-26 10:47:30 +01:00
2009-08-04 08:30:25 +02:00
const struct min_lookup minMipLookup [ ] =
2008-11-26 16:14:40 +01:00
{
2009-08-04 08:30:25 +02:00
/* NONE POINT LINEAR */
2009-08-06 08:12:18 +02:00
{ { GL_NEAREST , GL_NEAREST , GL_NEAREST } } , /* NONE */
2009-08-04 08:30:25 +02:00
{ { GL_NEAREST , GL_NEAREST_MIPMAP_NEAREST , GL_NEAREST_MIPMAP_LINEAR } } , /* POINT*/
{ { GL_LINEAR , GL_LINEAR_MIPMAP_NEAREST , GL_LINEAR_MIPMAP_LINEAR } } , /* LINEAR */
2008-04-06 00:22:08 +02:00
} ;
2005-08-03 13:00:28 +02:00
2009-08-04 08:30:25 +02:00
const struct min_lookup minMipLookup_noFilter [ ] =
2008-11-26 16:14:40 +01:00
{
2009-08-04 08:30:25 +02:00
/* NONE POINT LINEAR */
{ { GL_NEAREST , GL_NEAREST , GL_NEAREST } } , /* NONE */
{ { GL_NEAREST , GL_NEAREST , GL_NEAREST } } , /* POINT */
{ { GL_NEAREST , GL_NEAREST , GL_NEAREST } } , /* LINEAR */
} ;
2009-08-30 21:38:53 +02:00
const struct min_lookup minMipLookup_noMip [ ] =
{
/* NONE POINT LINEAR */
{ { GL_NEAREST , GL_NEAREST , GL_NEAREST } } , /* NONE */
{ { GL_NEAREST , GL_NEAREST , GL_NEAREST } } , /* POINT */
{ { GL_LINEAR , GL_LINEAR , GL_LINEAR } } , /* LINEAR */
} ;
2009-08-04 08:30:25 +02:00
const GLenum magLookup [ ] =
{
2009-08-05 09:01:02 +02:00
/* NONE POINT LINEAR */
GL_NEAREST , GL_NEAREST , GL_LINEAR ,
2009-08-04 08:30:25 +02:00
} ;
const GLenum magLookup_noFilter [ ] =
{
2009-08-05 09:01:02 +02:00
/* NONE POINT LINEAR */
GL_NEAREST , GL_NEAREST , GL_NEAREST ,
2008-04-06 00:37:51 +02:00
} ;
2008-04-06 00:31:39 +02:00
2007-12-19 17:10:02 +01:00
/* drawStridedSlow attributes */
2009-03-27 10:25:56 +01:00
glAttribFunc position_funcs [ WINED3D_FFP_EMIT_COUNT ] ;
glAttribFunc diffuse_funcs [ WINED3D_FFP_EMIT_COUNT ] ;
2009-03-11 10:15:09 +01:00
glAttribFunc specular_func_3ubv ;
2009-03-27 10:25:56 +01:00
glAttribFunc specular_funcs [ WINED3D_FFP_EMIT_COUNT ] ;
glAttribFunc normal_funcs [ WINED3D_FFP_EMIT_COUNT ] ;
glMultiTexCoordFunc multi_texcoord_funcs [ WINED3D_FFP_EMIT_COUNT ] ;
2005-08-03 13:00:28 +02:00
2004-09-29 23:26:47 +02:00
/**
2008-04-23 07:13:32 +02:00
* Note : GL seems to trap if GetDeviceCaps is called before any HWND ' s created ,
* i . e . , there is no GL Context - Get a default rendering context to enable the
* function query some info from GL .
2005-07-13 16:15:54 +02:00
*/
2006-11-23 19:58:41 +01:00
2009-07-03 09:39:18 +02:00
struct wined3d_fake_gl_ctx
{
HDC dc ;
HWND wnd ;
HGLRC gl_ctx ;
2009-10-27 10:10:43 +01:00
HDC restore_dc ;
HGLRC restore_gl_ctx ;
2009-07-03 09:39:18 +02:00
} ;
2006-11-23 19:58:41 +01:00
2009-07-03 09:39:18 +02:00
static void WineD3D_ReleaseFakeGLContext ( struct wined3d_fake_gl_ctx * ctx )
{
TRACE_ ( d3d_caps ) ( " Destroying fake GL context. \n " ) ;
2006-11-23 19:58:41 +01:00
2009-07-03 09:39:18 +02:00
if ( ! pwglMakeCurrent ( NULL , NULL ) )
2009-07-02 10:01:38 +02:00
{
2009-07-03 09:39:18 +02:00
ERR_ ( d3d_caps ) ( " Failed to disable fake GL context. \n " ) ;
2006-11-23 19:58:41 +01:00
}
2009-07-03 09:39:18 +02:00
2009-07-15 12:21:17 +02:00
if ( ! pwglDeleteContext ( ctx - > gl_ctx ) )
{
DWORD err = GetLastError ( ) ;
ERR ( " wglDeleteContext(%p) failed, last error %#x. \n " , ctx - > gl_ctx , err ) ;
}
2009-07-03 09:39:18 +02:00
ReleaseDC ( ctx - > wnd , ctx - > dc ) ;
DestroyWindow ( ctx - > wnd ) ;
2009-10-27 10:10:43 +01:00
if ( ctx - > restore_gl_ctx & & ! pwglMakeCurrent ( ctx - > restore_dc , ctx - > restore_gl_ctx ) )
{
ERR_ ( d3d_caps ) ( " Failed to restore previous GL context. \n " ) ;
}
2004-09-29 23:26:47 +02:00
}
2009-07-03 09:39:18 +02:00
static BOOL WineD3D_CreateFakeGLContext ( struct wined3d_fake_gl_ctx * ctx )
{
2009-07-02 10:01:37 +02:00
PIXELFORMATDESCRIPTOR pfd ;
int iPixelFormat ;
2006-11-23 19:58:41 +01:00
2007-08-07 23:45:00 +02:00
TRACE ( " getting context... \n " ) ;
2006-11-23 19:58:41 +01:00
2009-10-27 10:10:43 +01:00
ctx - > restore_dc = pwglGetCurrentDC ( ) ;
ctx - > restore_gl_ctx = pwglGetCurrentContext ( ) ;
2009-07-02 10:01:37 +02:00
/* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes. */
2009-07-03 09:39:18 +02:00
ctx - > wnd = CreateWindowA ( WINED3D_OPENGL_WINDOW_CLASS_NAME , " WineD3D fake window " ,
2009-07-02 10:01:37 +02:00
WS_OVERLAPPEDWINDOW , 10 , 10 , 10 , 10 , NULL , NULL , NULL , NULL ) ;
2009-07-03 09:39:18 +02:00
if ( ! ctx - > wnd )
2009-07-02 10:01:37 +02:00
{
2009-07-03 09:39:18 +02:00
ERR_ ( d3d_caps ) ( " Failed to create a window. \n " ) ;
2009-07-02 10:01:37 +02:00
goto fail ;
}
2006-11-23 19:58:41 +01:00
2009-07-03 09:39:18 +02:00
ctx - > dc = GetDC ( ctx - > wnd ) ;
if ( ! ctx - > dc )
2009-07-02 10:01:37 +02:00
{
2009-07-03 09:39:18 +02:00
ERR_ ( d3d_caps ) ( " Failed to get a DC. \n " ) ;
2009-07-02 10:01:37 +02:00
goto fail ;
}
2007-08-07 23:45:00 +02:00
2009-07-02 10:01:37 +02:00
/* PixelFormat selection */
ZeroMemory ( & pfd , sizeof ( pfd ) ) ;
pfd . nSize = sizeof ( pfd ) ;
pfd . nVersion = 1 ;
pfd . dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW ; /* PFD_GENERIC_ACCELERATED */
pfd . iPixelType = PFD_TYPE_RGBA ;
pfd . cColorBits = 32 ;
pfd . iLayerType = PFD_MAIN_PLANE ;
2009-07-03 09:39:18 +02:00
iPixelFormat = ChoosePixelFormat ( ctx - > dc , & pfd ) ;
2009-07-02 10:01:37 +02:00
if ( ! iPixelFormat )
{
/* If this happens something is very wrong as ChoosePixelFormat barely fails. */
2009-07-03 09:39:18 +02:00
ERR_ ( d3d_caps ) ( " Can't find a suitable iPixelFormat. \n " ) ;
2009-07-02 10:01:37 +02:00
goto fail ;
}
2009-07-03 09:39:18 +02:00
DescribePixelFormat ( ctx - > dc , iPixelFormat , sizeof ( pfd ) , & pfd ) ;
SetPixelFormat ( ctx - > dc , iPixelFormat , & pfd ) ;
2009-07-02 10:01:37 +02:00
/* Create a GL context. */
2009-07-03 09:39:18 +02:00
ctx - > gl_ctx = pwglCreateContext ( ctx - > dc ) ;
if ( ! ctx - > gl_ctx )
2009-07-02 10:01:37 +02:00
{
WARN_ ( d3d_caps ) ( " Error creating default context for capabilities initialization. \n " ) ;
goto fail ;
}
2006-11-23 19:58:41 +01:00
2009-07-02 10:01:37 +02:00
/* Make it the current GL context. */
2009-07-22 14:03:36 +02:00
if ( ! context_set_current ( NULL ) )
{
ERR_ ( d3d_caps ) ( " Failed to clear current D3D context. \n " ) ;
}
2009-07-03 09:39:18 +02:00
if ( ! pwglMakeCurrent ( ctx - > dc , ctx - > gl_ctx ) )
2009-07-02 10:01:37 +02:00
{
ERR_ ( d3d_caps ) ( " Failed to make fake GL context current. \n " ) ;
goto fail ;
2004-09-29 23:26:47 +02:00
}
2006-11-23 19:58:41 +01:00
return TRUE ;
2009-07-03 09:39:18 +02:00
fail :
if ( ctx - > gl_ctx ) pwglDeleteContext ( ctx - > gl_ctx ) ;
ctx - > gl_ctx = NULL ;
if ( ctx - > dc ) ReleaseDC ( ctx - > wnd , ctx - > dc ) ;
ctx - > dc = NULL ;
if ( ctx - > wnd ) DestroyWindow ( ctx - > wnd ) ;
ctx - > wnd = NULL ;
2009-10-27 10:10:43 +01:00
if ( ctx - > restore_gl_ctx & & ! pwglMakeCurrent ( ctx - > restore_dc , ctx - > restore_gl_ctx ) )
{
ERR_ ( d3d_caps ) ( " Failed to restore previous GL context. \n " ) ;
}
2009-07-03 09:39:18 +02:00
2006-11-23 19:58:41 +01:00
return FALSE ;
2004-09-29 23:26:47 +02:00
}
2007-09-23 00:46:21 +02:00
/* Adjust the amount of used texture memory */
2010-04-20 22:38:39 +02:00
long WineD3DAdapterChangeGLRam ( IWineD3DDeviceImpl * device , long glram )
2009-10-21 10:33:58 +02:00
{
2010-04-20 22:38:39 +02:00
struct wined3d_adapter * adapter = device - > adapter ;
2007-09-23 00:46:21 +02:00
2009-03-11 10:15:09 +01:00
adapter - > UsedTextureRam + = glram ;
TRACE ( " Adjusted gl ram by %ld to %d \n " , glram , adapter - > UsedTextureRam ) ;
return adapter - > UsedTextureRam ;
2007-09-23 00:46:21 +02:00
}
2007-08-07 23:45:00 +02:00
2009-10-21 10:33:59 +02:00
static void wined3d_adapter_cleanup ( struct wined3d_adapter * adapter )
{
HeapFree ( GetProcessHeap ( ) , 0 , adapter - > gl_info . gl_formats ) ;
HeapFree ( GetProcessHeap ( ) , 0 , adapter - > cfgs ) ;
}
2005-03-02 14:44:58 +01:00
/**********************************************************
* IUnknown parts follows
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_QueryInterface ( IWineD3D * iface , REFIID riid , LPVOID * ppobj )
2005-03-02 14:44:58 +01:00
{
IWineD3DDeviceImpl * This = ( IWineD3DDeviceImpl * ) iface ;
2005-07-13 16:15:54 +02:00
2005-03-02 14:44:58 +01:00
TRACE ( " (%p)->(%s,%p) \n " , This , debugstr_guid ( riid ) , ppobj ) ;
2005-07-13 16:15:54 +02:00
if ( IsEqualGUID ( riid , & IID_IUnknown )
2006-02-06 11:32:41 +01:00
| | IsEqualGUID ( riid , & IID_IWineD3DBase )
2005-03-02 14:44:58 +01:00
| | IsEqualGUID ( riid , & IID_IWineD3DDevice ) ) {
IUnknown_AddRef ( iface ) ;
* ppobj = This ;
2006-04-25 23:59:12 +02:00
return S_OK ;
2005-03-02 14:44:58 +01:00
}
2006-04-25 23:59:12 +02:00
* ppobj = NULL ;
2005-03-02 14:44:58 +01:00
return E_NOINTERFACE ;
}
2006-06-10 13:15:32 +02:00
static ULONG WINAPI IWineD3DImpl_AddRef ( IWineD3D * iface ) {
2005-03-02 14:44:58 +01:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
ULONG refCount = InterlockedIncrement ( & This - > ref ) ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : AddRef increasing from %d \n " , This , refCount - 1 ) ;
2005-03-02 14:44:58 +01:00
return refCount ;
}
2006-06-10 13:15:32 +02:00
static ULONG WINAPI IWineD3DImpl_Release ( IWineD3D * iface ) {
2005-03-02 14:44:58 +01:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
ULONG ref ;
2006-10-01 05:20:10 +02:00
TRACE ( " (%p) : Releasing from %d \n " , This , This - > ref ) ;
2005-03-02 14:44:58 +01:00
ref = InterlockedDecrement ( & This - > ref ) ;
if ( ref = = 0 ) {
2009-03-11 10:15:10 +01:00
unsigned int i ;
for ( i = 0 ; i < This - > adapter_count ; + + i )
{
2009-10-21 10:33:59 +02:00
wined3d_adapter_cleanup ( & This - > adapters [ i ] ) ;
2009-03-11 10:15:10 +01:00
}
2005-03-02 14:44:58 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , This ) ;
}
2005-07-13 16:15:54 +02:00
2005-03-02 14:44:58 +01:00
return ref ;
}
/**********************************************************
* IWineD3D parts follows
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-05-14 19:40:56 +02:00
/* GL locking is done by the caller */
2009-07-17 10:34:01 +02:00
static inline BOOL test_arb_vs_offset_limit ( const struct wined3d_gl_info * gl_info )
2008-11-28 15:30:11 +01:00
{
2007-11-07 19:57:49 +01:00
GLuint prog ;
BOOL ret = FALSE ;
const char * testcode =
" !!ARBvp1.0 \n "
" PARAM C[66] = { program.env[0..65] }; \n "
" ADDRESS A0; "
2008-02-11 01:53:53 +01:00
" PARAM zero = {0.0, 0.0, 0.0, 0.0}; \n "
" ARL A0.x, zero.x; \n "
2007-11-07 19:57:49 +01:00
" MOV result.position, C[A0.x + 65]; \n "
" END \n " ;
while ( glGetError ( ) ) ;
GL_EXTCALL ( glGenProgramsARB ( 1 , & prog ) ) ;
if ( ! prog ) {
ERR ( " Failed to create an ARB offset limit test program \n " ) ;
}
GL_EXTCALL ( glBindProgramARB ( GL_VERTEX_PROGRAM_ARB , prog ) ) ;
GL_EXTCALL ( glProgramStringARB ( GL_VERTEX_PROGRAM_ARB , GL_PROGRAM_FORMAT_ASCII_ARB ,
strlen ( testcode ) , testcode ) ) ;
if ( glGetError ( ) ! = 0 ) {
TRACE ( " OpenGL implementation does not allow indirect addressing offsets > 63 \n " ) ;
TRACE ( " error: %s \n " , debugstr_a ( ( const char * ) glGetString ( GL_PROGRAM_ERROR_STRING_ARB ) ) ) ;
ret = TRUE ;
} else TRACE ( " OpenGL implementation allows offsets > 63 \n " ) ;
GL_EXTCALL ( glBindProgramARB ( GL_VERTEX_PROGRAM_ARB , 0 ) ) ;
GL_EXTCALL ( glDeleteProgramsARB ( 1 , & prog ) ) ;
2009-07-07 11:08:02 +02:00
checkGLcall ( " ARB vp offset limit test cleanup " ) ;
2007-11-07 19:57:49 +01:00
return ret ;
}
2007-11-11 13:59:49 +01:00
static DWORD ver_for_ext ( GL_SupportedExt ext )
{
unsigned int i ;
for ( i = 0 ; i < ( sizeof ( EXTENSION_MAP ) / sizeof ( * EXTENSION_MAP ) ) ; + + i ) {
if ( EXTENSION_MAP [ i ] . extension = = ext ) {
return EXTENSION_MAP [ i ] . version ;
}
}
return 0 ;
}
2009-10-27 10:10:39 +01:00
static BOOL match_ati_r300_to_500 ( const struct wined3d_gl_info * gl_info , const char * gl_renderer ,
2010-03-03 08:16:26 +01:00
enum wined3d_gl_vendor gl_vendor , enum wined3d_pci_vendor card_vendor , enum wined3d_pci_device device )
2009-07-06 10:08:42 +02:00
{
2010-03-01 19:26:04 +01:00
if ( card_vendor ! = HW_VENDOR_ATI ) return FALSE ;
2009-10-27 10:10:39 +01:00
if ( device = = CARD_ATI_RADEON_9500 ) return TRUE ;
if ( device = = CARD_ATI_RADEON_X700 ) return TRUE ;
if ( device = = CARD_ATI_RADEON_X1600 ) return TRUE ;
2009-07-06 10:08:42 +02:00
return FALSE ;
}
2005-11-30 12:02:45 +01:00
2009-10-27 10:10:39 +01:00
static BOOL match_geforce5 ( const struct wined3d_gl_info * gl_info , const char * gl_renderer ,
2010-03-03 08:16:26 +01:00
enum wined3d_gl_vendor gl_vendor , enum wined3d_pci_vendor card_vendor , enum wined3d_pci_device device )
2009-07-06 10:08:42 +02:00
{
2010-03-01 19:26:04 +01:00
if ( card_vendor = = HW_VENDOR_NVIDIA )
2009-07-03 09:39:22 +02:00
{
2009-10-27 10:10:39 +01:00
if ( device = = CARD_NVIDIA_GEFORCEFX_5800 | | device = = CARD_NVIDIA_GEFORCEFX_5600 )
2009-07-06 10:08:42 +02:00
{
return TRUE ;
}
2004-09-29 23:26:47 +02:00
}
2009-07-06 10:08:42 +02:00
return FALSE ;
}
2005-07-10 19:48:07 +02:00
2009-10-27 10:10:39 +01:00
static BOOL match_apple ( const struct wined3d_gl_info * gl_info , const char * gl_renderer ,
2010-03-03 08:16:26 +01:00
enum wined3d_gl_vendor gl_vendor , enum wined3d_pci_vendor card_vendor , enum wined3d_pci_device device )
2009-07-06 10:08:42 +02:00
{
/* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
* the opengl 1.2 + core , while other extensions are advertised , but software emulated . So try to
* detect the Apple OpenGL implementation to apply some extension fixups afterwards .
*
* Detecting this isn ' t really easy . The vendor string doesn ' t mention Apple . Compile - time checks
* aren ' t sufficient either because a Linux binary may display on a macos X server via remote X11 .
* So try to detect the GL implementation by looking at certain Apple extensions . Some extensions
* like client storage might be supported on other implementations too , but GL_APPLE_flush_render
* is specific to the Mac OS X window management , and GL_APPLE_ycbcr_422 is QuickTime specific . So
* the chance that other implementations support them is rather small since Win32 QuickTime uses
2010-03-03 08:16:26 +01:00
* DirectDraw , not OpenGL .
*
* This test has been moved into wined3d_guess_gl_vendor ( )
*/
if ( gl_vendor = = GL_VENDOR_APPLE )
2009-07-03 09:39:22 +02:00
{
2009-07-06 10:08:42 +02:00
return TRUE ;
2009-07-03 09:39:22 +02:00
}
2010-03-03 08:16:26 +01:00
return FALSE ;
2009-07-06 10:08:42 +02:00
}
2005-07-10 19:48:07 +02:00
2009-07-06 10:08:42 +02:00
/* Context activation is done by the caller. */
2009-07-17 10:34:01 +02:00
static void test_pbo_functionality ( struct wined3d_gl_info * gl_info )
2009-07-06 10:08:42 +02:00
{
/* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
* but glTexSubImage from a PBO fails miserably , with the first line repeated over
* all the texture . This function detects this bug by its symptom and disables PBOs
* if the test fails .
*
* The test uploads a 4 x4 texture via the PBO in the " native " format GL_BGRA ,
* GL_UNSIGNED_INT_8_8_8_8_REV . This format triggers the bug , and it is what we use
* for D3DFMT_A8R8G8B8 . Then the texture is read back without any PBO and the data
* read back is compared to the original . If they are equal PBOs are assumed to work ,
* otherwise the PBO extension is disabled . */
GLuint texture , pbo ;
static const unsigned int pattern [ ] =
2009-07-03 09:39:22 +02:00
{
2009-07-06 10:08:42 +02:00
0x00000000 , 0x000000ff , 0x0000ff00 , 0x40ff0000 ,
0x80ffffff , 0x40ffff00 , 0x00ff00ff , 0x0000ffff ,
0x00ffff00 , 0x00ff00ff , 0x0000ffff , 0x000000ff ,
0x80ff00ff , 0x0000ffff , 0x00ff00ff , 0x40ff00ff
} ;
unsigned int check [ sizeof ( pattern ) / sizeof ( pattern [ 0 ] ) ] ;
2005-07-10 19:48:07 +02:00
2009-07-06 10:08:42 +02:00
/* No PBO -> No point in testing them. */
if ( ! gl_info - > supported [ ARB_PIXEL_BUFFER_OBJECT ] ) return ;
2009-07-03 09:39:22 +02:00
2009-07-06 10:08:42 +02:00
ENTER_GL ( ) ;
2008-02-05 22:49:14 +01:00
2009-07-06 10:08:42 +02:00
while ( glGetError ( ) ) ;
glGenTextures ( 1 , & texture ) ;
glBindTexture ( GL_TEXTURE_2D , texture ) ;
2009-07-03 09:39:22 +02:00
2009-07-06 10:08:42 +02:00
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAX_LEVEL , 0 ) ;
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA8 , 4 , 4 , 0 , GL_BGRA , GL_UNSIGNED_INT_8_8_8_8_REV , 0 ) ;
2009-07-07 11:08:02 +02:00
checkGLcall ( " Specifying the PBO test texture " ) ;
2006-01-19 12:39:37 +01:00
2009-07-06 10:08:42 +02:00
GL_EXTCALL ( glGenBuffersARB ( 1 , & pbo ) ) ;
GL_EXTCALL ( glBindBufferARB ( GL_PIXEL_UNPACK_BUFFER_ARB , pbo ) ) ;
GL_EXTCALL ( glBufferDataARB ( GL_PIXEL_UNPACK_BUFFER_ARB , sizeof ( pattern ) , pattern , GL_STREAM_DRAW_ARB ) ) ;
2009-07-07 11:08:02 +02:00
checkGLcall ( " Specifying the PBO test pbo " ) ;
2006-01-19 12:39:37 +01:00
2009-07-06 10:08:42 +02:00
glTexSubImage2D ( GL_TEXTURE_2D , 0 , 0 , 0 , 4 , 4 , GL_BGRA , GL_UNSIGNED_INT_8_8_8_8_REV , NULL ) ;
2009-07-07 11:08:02 +02:00
checkGLcall ( " Loading the PBO test texture " ) ;
2006-01-19 12:39:37 +01:00
2009-07-06 10:08:42 +02:00
GL_EXTCALL ( glBindBufferARB ( GL_PIXEL_UNPACK_BUFFER_ARB , 0 ) ) ;
2009-08-26 11:44:34 +02:00
wglFinish ( ) ; /* just to be sure */
2006-01-19 12:39:37 +01:00
2009-07-06 10:08:42 +02:00
memset ( check , 0 , sizeof ( check ) ) ;
glGetTexImage ( GL_TEXTURE_2D , 0 , GL_BGRA , GL_UNSIGNED_INT_8_8_8_8_REV , check ) ;
2009-07-07 11:08:02 +02:00
checkGLcall ( " Reading back the PBO test texture " ) ;
2005-07-13 16:15:54 +02:00
2009-07-06 10:08:42 +02:00
glDeleteTextures ( 1 , & texture ) ;
GL_EXTCALL ( glDeleteBuffersARB ( 1 , & pbo ) ) ;
2009-07-07 11:08:02 +02:00
checkGLcall ( " PBO test cleanup " ) ;
2006-01-19 12:39:37 +01:00
2009-07-06 10:08:42 +02:00
LEAVE_GL ( ) ;
2005-07-13 16:15:54 +02:00
2009-07-06 10:08:42 +02:00
if ( memcmp ( check , pattern , sizeof ( check ) ) )
{
WARN_ ( d3d_caps ) ( " PBO test failed, read back data doesn't match original. \n " ) ;
WARN_ ( d3d_caps ) ( " Disabling PBOs. This may result in slower performance. \n " ) ;
gl_info - > supported [ ARB_PIXEL_BUFFER_OBJECT ] = FALSE ;
}
else
{
TRACE_ ( d3d_caps ) ( " PBO test successful. \n " ) ;
}
}
2009-07-03 09:39:22 +02:00
2009-10-27 10:10:39 +01:00
static BOOL match_apple_intel ( const struct wined3d_gl_info * gl_info , const char * gl_renderer ,
2010-03-03 08:16:26 +01:00
enum wined3d_gl_vendor gl_vendor , enum wined3d_pci_vendor card_vendor , enum wined3d_pci_device device )
2009-07-06 10:08:42 +02:00
{
2010-03-03 08:16:28 +01:00
return ( card_vendor = = HW_VENDOR_INTEL ) & & ( gl_vendor = = GL_VENDOR_APPLE ) ;
2009-07-06 10:08:42 +02:00
}
2005-07-13 16:15:54 +02:00
2009-10-27 10:10:39 +01:00
static BOOL match_apple_nonr500ati ( const struct wined3d_gl_info * gl_info , const char * gl_renderer ,
2010-03-03 08:16:26 +01:00
enum wined3d_gl_vendor gl_vendor , enum wined3d_pci_vendor card_vendor , enum wined3d_pci_device device )
2009-07-06 10:08:42 +02:00
{
2010-03-03 08:16:28 +01:00
if ( gl_vendor ! = GL_VENDOR_APPLE ) return FALSE ;
2010-03-01 19:26:04 +01:00
if ( card_vendor ! = HW_VENDOR_ATI ) return FALSE ;
2009-10-27 10:10:39 +01:00
if ( device = = CARD_ATI_RADEON_X1600 ) return FALSE ;
2009-07-06 10:08:42 +02:00
return TRUE ;
}
2005-07-13 16:15:54 +02:00
2009-10-27 10:10:39 +01:00
static BOOL match_fglrx ( const struct wined3d_gl_info * gl_info , const char * gl_renderer ,
2010-03-03 08:16:26 +01:00
enum wined3d_gl_vendor gl_vendor , enum wined3d_pci_vendor card_vendor , enum wined3d_pci_device device )
2009-07-06 10:08:42 +02:00
{
2010-04-04 19:51:41 +02:00
return gl_vendor = = GL_VENDOR_FGLRX ;
2010-03-03 08:16:28 +01:00
2009-07-06 10:08:42 +02:00
}
2007-11-30 16:51:32 +01:00
2009-10-27 10:10:39 +01:00
static BOOL match_dx10_capable ( const struct wined3d_gl_info * gl_info , const char * gl_renderer ,
2010-03-03 08:16:26 +01:00
enum wined3d_gl_vendor gl_vendor , enum wined3d_pci_vendor card_vendor , enum wined3d_pci_device device )
2009-07-06 10:08:42 +02:00
{
/* DX9 cards support 40 single float varyings in hardware, most drivers report 32. ATI misreports
* 44 varyings . So assume that if we have more than 44 varyings we have a dx10 card .
* This detection is for the gl_ClipPos varying quirk . If a d3d9 card really supports more than 44
* varyings and we subtract one in dx9 shaders its not going to hurt us because the dx9 limit is
* hardcoded
*
* dx10 cards usually have 64 varyings */
2009-10-29 10:37:10 +01:00
return gl_info - > limits . glsl_varyings > 44 ;
2009-07-06 10:08:42 +02:00
}
2007-11-30 16:51:32 +01:00
2009-07-10 11:28:49 +02:00
/* A GL context is provided by the caller */
2009-10-27 10:10:39 +01:00
static BOOL match_allows_spec_alpha ( const struct wined3d_gl_info * gl_info , const char * gl_renderer ,
2010-03-03 08:16:26 +01:00
enum wined3d_gl_vendor gl_vendor , enum wined3d_pci_vendor card_vendor , enum wined3d_pci_device device )
2009-07-10 11:28:49 +02:00
{
GLenum error ;
DWORD data [ 16 ] ;
2009-10-29 10:37:11 +01:00
if ( ! gl_info - > supported [ EXT_SECONDARY_COLOR ] ) return FALSE ;
2009-07-10 11:28:49 +02:00
ENTER_GL ( ) ;
while ( glGetError ( ) ) ;
GL_EXTCALL ( glSecondaryColorPointerEXT ) ( 4 , GL_UNSIGNED_BYTE , 4 , data ) ;
error = glGetError ( ) ;
LEAVE_GL ( ) ;
if ( error = = GL_NO_ERROR )
{
TRACE ( " GL Implementation accepts 4 component specular color pointers \n " ) ;
return TRUE ;
}
else
{
TRACE ( " GL implementation does not accept 4 component specular colors, error %s \n " ,
debug_glerror ( error ) ) ;
return FALSE ;
}
}
2009-10-27 10:10:39 +01:00
static BOOL match_apple_nvts ( const struct wined3d_gl_info * gl_info , const char * gl_renderer ,
2010-03-03 08:16:26 +01:00
enum wined3d_gl_vendor gl_vendor , enum wined3d_pci_vendor card_vendor , enum wined3d_pci_device device )
2009-09-28 12:24:00 +02:00
{
2010-03-03 08:16:26 +01:00
if ( ! match_apple ( gl_info , gl_renderer , gl_vendor , card_vendor , device ) ) return FALSE ;
2009-10-29 10:37:11 +01:00
return gl_info - > supported [ NV_TEXTURE_SHADER ] ;
2009-09-28 12:24:00 +02:00
}
2009-09-28 12:30:48 +02:00
/* A GL context is provided by the caller */
2009-10-27 10:10:39 +01:00
static BOOL match_broken_nv_clip ( const struct wined3d_gl_info * gl_info , const char * gl_renderer ,
2010-03-03 08:16:26 +01:00
enum wined3d_gl_vendor gl_vendor , enum wined3d_pci_vendor card_vendor , enum wined3d_pci_device device )
2009-09-28 12:30:48 +02:00
{
GLuint prog ;
BOOL ret = FALSE ;
GLint pos ;
const char * testcode =
" !!ARBvp1.0 \n "
" OPTION NV_vertex_program2; \n "
" MOV result.clip[0], 0.0; \n "
" MOV result.position, 0.0; \n "
" END \n " ;
2009-10-29 10:37:11 +01:00
if ( ! gl_info - > supported [ NV_VERTEX_PROGRAM2_OPTION ] ) return FALSE ;
2009-09-28 12:30:48 +02:00
ENTER_GL ( ) ;
while ( glGetError ( ) ) ;
GL_EXTCALL ( glGenProgramsARB ( 1 , & prog ) ) ;
if ( ! prog )
{
2009-09-29 17:43:44 +02:00
ERR ( " Failed to create the NVvp clip test program \n " ) ;
2009-09-28 12:30:48 +02:00
LEAVE_GL ( ) ;
return FALSE ;
}
GL_EXTCALL ( glBindProgramARB ( GL_VERTEX_PROGRAM_ARB , prog ) ) ;
GL_EXTCALL ( glProgramStringARB ( GL_VERTEX_PROGRAM_ARB , GL_PROGRAM_FORMAT_ASCII_ARB ,
strlen ( testcode ) , testcode ) ) ;
glGetIntegerv ( GL_PROGRAM_ERROR_POSITION_ARB , & pos ) ;
if ( pos ! = - 1 )
{
WARN ( " GL_NV_vertex_program2_option result.clip[] test failed \n " ) ;
TRACE ( " error: %s \n " , debugstr_a ( ( const char * ) glGetString ( GL_PROGRAM_ERROR_STRING_ARB ) ) ) ;
ret = TRUE ;
while ( glGetError ( ) ) ;
}
else TRACE ( " GL_NV_vertex_program2_option result.clip[] test passed \n " ) ;
GL_EXTCALL ( glBindProgramARB ( GL_VERTEX_PROGRAM_ARB , 0 ) ) ;
GL_EXTCALL ( glDeleteProgramsARB ( 1 , & prog ) ) ;
checkGLcall ( " GL_NV_vertex_program2_option result.clip[] test cleanup " ) ;
LEAVE_GL ( ) ;
return ret ;
}
2010-03-25 22:51:21 +01:00
/* Context activation is done by the caller. */
2010-03-17 21:59:51 +01:00
static BOOL match_fbo_tex_update ( const struct wined3d_gl_info * gl_info , const char * gl_renderer ,
enum wined3d_gl_vendor gl_vendor , enum wined3d_pci_vendor card_vendor , enum wined3d_pci_device device )
{
char data [ 4 * 4 * 4 ] ;
GLuint tex , fbo ;
GLenum status ;
if ( wined3d_settings . offscreen_rendering_mode ! = ORM_FBO ) return FALSE ;
memset ( data , 0xcc , sizeof ( data ) ) ;
2010-03-25 22:51:21 +01:00
ENTER_GL ( ) ;
2010-03-17 21:59:51 +01:00
glGenTextures ( 1 , & tex ) ;
glBindTexture ( GL_TEXTURE_2D , tex ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST ) ;
glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST ) ;
glTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA8 , 4 , 4 , 0 , GL_BGRA , GL_UNSIGNED_INT_8_8_8_8_REV , NULL ) ;
checkGLcall ( " glTexImage2D " ) ;
gl_info - > fbo_ops . glGenFramebuffers ( 1 , & fbo ) ;
gl_info - > fbo_ops . glBindFramebuffer ( GL_FRAMEBUFFER , fbo ) ;
gl_info - > fbo_ops . glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 , GL_TEXTURE_2D , tex , 0 ) ;
checkGLcall ( " glFramebufferTexture2D " ) ;
status = gl_info - > fbo_ops . glCheckFramebufferStatus ( GL_FRAMEBUFFER ) ;
if ( status ! = GL_FRAMEBUFFER_COMPLETE ) ERR ( " FBO status %#x \n " , status ) ;
checkGLcall ( " glCheckFramebufferStatus " ) ;
memset ( data , 0x11 , sizeof ( data ) ) ;
glTexSubImage2D ( GL_TEXTURE_2D , 0 , 0 , 0 , 4 , 4 , GL_BGRA , GL_UNSIGNED_INT_8_8_8_8_REV , data ) ;
checkGLcall ( " glTexSubImage2D " ) ;
glClearColor ( 0.996 , 0.729 , 0.745 , 0.792 ) ;
glClear ( GL_COLOR_BUFFER_BIT ) ;
checkGLcall ( " glClear " ) ;
glGetTexImage ( GL_TEXTURE_2D , 0 , GL_BGRA , GL_UNSIGNED_INT_8_8_8_8_REV , data ) ;
checkGLcall ( " glGetTexImage " ) ;
gl_info - > fbo_ops . glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 , GL_TEXTURE_2D , 0 , 0 ) ;
gl_info - > fbo_ops . glBindFramebuffer ( GL_FRAMEBUFFER , 0 ) ;
glBindTexture ( GL_TEXTURE_2D , 0 ) ;
checkGLcall ( " glBindTexture " ) ;
gl_info - > fbo_ops . glDeleteFramebuffers ( 1 , & fbo ) ;
glDeleteTextures ( 1 , & tex ) ;
checkGLcall ( " glDeleteTextures " ) ;
2010-03-25 22:51:21 +01:00
LEAVE_GL ( ) ;
2010-03-17 21:59:51 +01:00
return * ( DWORD * ) data = = 0x11111111 ;
}
2009-07-17 10:34:01 +02:00
static void quirk_arb_constants ( struct wined3d_gl_info * gl_info )
2009-07-06 10:08:42 +02:00
{
2009-10-29 10:37:10 +01:00
TRACE_ ( d3d_caps ) ( " Using ARB vs constant limit(=%u) for GLSL. \n " , gl_info - > limits . arb_vs_native_constants ) ;
gl_info - > limits . glsl_vs_float_constants = gl_info - > limits . arb_vs_native_constants ;
TRACE_ ( d3d_caps ) ( " Using ARB ps constant limit(=%u) for GLSL. \n " , gl_info - > limits . arb_ps_native_constants ) ;
gl_info - > limits . glsl_ps_float_constants = gl_info - > limits . arb_ps_native_constants ;
2009-07-06 10:08:42 +02:00
}
2009-07-17 10:34:01 +02:00
static void quirk_apple_glsl_constants ( struct wined3d_gl_info * gl_info )
2009-07-06 10:08:42 +02:00
{
quirk_arb_constants ( gl_info ) ;
/* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms.
* Beyond that the general uniform isn ' t optimal , so reserve a number of uniforms . 12 vec4 ' s should
* allow 48 different offsets or other helper immediate values . */
TRACE_ ( d3d_caps ) ( " Reserving 12 GLSL constants for compiler private use. \n " ) ;
gl_info - > reserved_glsl_constants = max ( gl_info - > reserved_glsl_constants , 12 ) ;
}
/* fglrx crashes with a very bad kernel panic if GL_POINT_SPRITE_ARB is set to GL_COORD_REPLACE_ARB
* on more than one texture unit . This means that the d3d9 visual point size test will cause a
* kernel panic on any machine running fglrx 9.3 ( latest that supports r300 to r500 cards ) . This
* quirk only enables point sprites on the first texture unit . This keeps point sprites working in
* most games , but avoids the crash
*
* A more sophisticated way would be to find all units that need texture coordinates and enable
* point sprites for one if only one is found , and software emulate point sprites in drawStridedSlow
* if more than one unit needs texture coordinates ( This requires software ffp and vertex shaders though )
*
* Note that disabling the extension entirely does not gain predictability because there is no point
* sprite capability flag in d3d , so the potential rendering bugs are the same if we disable the extension . */
2009-07-17 10:34:01 +02:00
static void quirk_one_point_sprite ( struct wined3d_gl_info * gl_info )
2009-07-06 10:08:42 +02:00
{
if ( gl_info - > supported [ ARB_POINT_SPRITE ] )
{
TRACE ( " Limiting point sprites to one texture unit. \n " ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . point_sprite_units = 1 ;
2009-07-06 10:08:42 +02:00
}
}
2009-07-17 10:34:01 +02:00
static void quirk_ati_dx9 ( struct wined3d_gl_info * gl_info )
2009-07-06 10:08:42 +02:00
{
quirk_arb_constants ( gl_info ) ;
/* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
* these cards only support GL_ARB_texture_rectangle ( D3DPTEXTURECAPS_NONPOW2CONDITIONAL ) .
* If real NP2 textures are used , the driver falls back to software . We could just remove the
* extension and use GL_ARB_texture_rectangle instead , but texture_rectangle is inconventient
* due to the non - normalized texture coordinates . Thus set an internal extension flag ,
* GL_WINE_normalized_texrect , which signals the code that it can use non power of two textures
* as per GL_ARB_texture_non_power_of_two , but has to stick to the texture_rectangle limits .
*
* fglrx doesn ' t advertise GL_ARB_texture_non_power_of_two , but it advertises opengl 2.0 which
* has this extension promoted to core . The extension loading code sets this extension supported
* due to that , so this code works on fglrx as well . */
2009-08-02 15:12:26 +02:00
if ( gl_info - > supported [ ARB_TEXTURE_NON_POWER_OF_TWO ] )
{
TRACE ( " GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing. \n " ) ;
gl_info - > supported [ ARB_TEXTURE_NON_POWER_OF_TWO ] = FALSE ;
gl_info - > supported [ WINE_NORMALIZED_TEXRECT ] = TRUE ;
}
2009-07-06 10:08:42 +02:00
/* fglrx has the same structural issues as the one described in quirk_apple_glsl_constants, although
* it is generally more efficient . Reserve just 8 constants . */
TRACE_ ( d3d_caps ) ( " Reserving 8 GLSL constants for compiler private use. \n " ) ;
gl_info - > reserved_glsl_constants = max ( gl_info - > reserved_glsl_constants , 8 ) ;
}
2009-07-17 10:34:01 +02:00
static void quirk_no_np2 ( struct wined3d_gl_info * gl_info )
2009-07-06 10:08:42 +02:00
{
/* The nVidia GeForceFX series reports OpenGL 2.0 capabilities with the latest drivers versions, but
* doesn ' t explicitly advertise the ARB_tex_npot extension in the GL extension string .
* This usually means that ARB_tex_npot is supported in hardware as long as the application is staying
* within the limits enforced by the ARB_texture_rectangle extension . This however is not true for the
* FX series , which instantly falls back to a slower software path as soon as ARB_tex_npot is used .
* We therefore completely remove ARB_tex_npot from the list of supported extensions .
*
* Note that wine_normalized_texrect can ' t be used in this case because internally it uses ARB_tex_npot ,
* triggering the software fallback . There is not much we can do here apart from disabling the
* software - emulated extension and reenable ARB_tex_rect ( which was previously disabled
* in IWineD3DImpl_FillGLCaps ) .
* This fixup removes performance problems on both the FX 5900 and FX 5700 ( e . g . for framebuffer
* post - processing effects in the game " Max Payne 2 " ) .
* The behaviour can be verified through a simple test app attached in bugreport # 14724. */
TRACE ( " GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing. \n " ) ;
gl_info - > supported [ ARB_TEXTURE_NON_POWER_OF_TWO ] = FALSE ;
gl_info - > supported [ ARB_TEXTURE_RECTANGLE ] = TRUE ;
}
2009-07-17 10:34:01 +02:00
static void quirk_texcoord_w ( struct wined3d_gl_info * gl_info )
2009-07-06 10:08:42 +02:00
{
/* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
* with fixed function fragment processing . Ideally this flag should be detected with a test shader
* and OpenGL feedback mode , but some GL implementations ( MacOS ATI at least , probably all MacOS ones )
* do not like vertex shaders in feedback mode and return an error , even though it should be valid
* according to the spec .
*
* We don ' t want to enable this on all cards , as it adds an extra instruction per texcoord used . This
* makes the shader slower and eats instruction slots which should be available to the d3d app .
*
* ATI Radeon HD 2 xxx cards on MacOS have the issue . Instead of checking for the buggy cards , blacklist
* all radeon cards on Macs and whitelist the good ones . That way we ' re prepared for the future . If
* this workaround is activated on cards that do not need it , it won ' t break things , just affect
* performance negatively . */
TRACE ( " Enabling vertex texture coord fixes in vertex shaders. \n " ) ;
gl_info - > quirks | = WINED3D_QUIRK_SET_TEXCOORD_W ;
}
2009-07-17 10:34:01 +02:00
static void quirk_clip_varying ( struct wined3d_gl_info * gl_info )
2009-07-06 10:08:42 +02:00
{
gl_info - > quirks | = WINED3D_QUIRK_GLSL_CLIP_VARYING ;
}
2009-07-17 10:34:01 +02:00
static void quirk_allows_specular_alpha ( struct wined3d_gl_info * gl_info )
2009-07-10 11:28:49 +02:00
{
gl_info - > quirks | = WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA ;
}
2009-09-28 12:24:00 +02:00
static void quirk_apple_nvts ( struct wined3d_gl_info * gl_info )
{
gl_info - > supported [ NV_TEXTURE_SHADER ] = FALSE ;
gl_info - > supported [ NV_TEXTURE_SHADER2 ] = FALSE ;
}
2009-09-28 12:30:48 +02:00
static void quirk_disable_nvvp_clip ( struct wined3d_gl_info * gl_info )
{
gl_info - > quirks | = WINED3D_QUIRK_NV_CLIP_BROKEN ;
}
2010-03-17 21:59:51 +01:00
static void quirk_fbo_tex_update ( struct wined3d_gl_info * gl_info )
{
gl_info - > quirks | = WINED3D_QUIRK_FBO_TEX_UPDATE ;
}
2009-07-06 10:08:42 +02:00
struct driver_quirk
{
2009-10-27 10:10:39 +01:00
BOOL ( * match ) ( const struct wined3d_gl_info * gl_info , const char * gl_renderer ,
2010-03-03 08:16:26 +01:00
enum wined3d_gl_vendor gl_vendor , enum wined3d_pci_vendor card_vendor , enum wined3d_pci_device device ) ;
2009-07-17 10:34:01 +02:00
void ( * apply ) ( struct wined3d_gl_info * gl_info ) ;
2009-07-06 10:08:42 +02:00
const char * description ;
} ;
2009-09-11 19:01:18 +02:00
static const struct driver_quirk quirk_table [ ] =
2009-07-06 10:08:42 +02:00
{
{
match_ati_r300_to_500 ,
quirk_ati_dx9 ,
" ATI GLSL constant and normalized texrect quirk "
} ,
/* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
* used it falls back to software . While the compiler can detect if the shader uses all declared
* uniforms , the optimization fails if the shader uses relative addressing . So any GLSL shader
* using relative addressing falls back to software .
*
* ARB vp gives the correct amount of uniforms , so use it instead of GLSL . */
{
match_apple ,
quirk_apple_glsl_constants ,
" Apple GLSL uniform override "
} ,
{
match_geforce5 ,
quirk_no_np2 ,
" Geforce 5 NP2 disable "
} ,
{
match_apple_intel ,
quirk_texcoord_w ,
" Init texcoord .w for Apple Intel GPU driver "
} ,
{
match_apple_nonr500ati ,
quirk_texcoord_w ,
" Init texcoord .w for Apple ATI >= r600 GPU driver "
} ,
{
match_fglrx ,
quirk_one_point_sprite ,
" Fglrx point sprite crash workaround "
} ,
{
match_dx10_capable ,
quirk_clip_varying ,
" Reserved varying for gl_ClipPos "
2009-07-10 11:28:49 +02:00
} ,
{
/* GL_EXT_secondary_color does not allow 4 component secondary colors, but most
* GL implementations accept it . The Mac GL is the only implementation known to
* reject it .
*
* If we can pass 4 component specular colors , do it , because ( a ) we don ' t have
* to screw around with the data , and ( b ) the D3D fixed function vertex pipeline
* passes specular alpha to the pixel shader if any is used . Otherwise the
* specular alpha is used to pass the fog coordinate , which we pass to opengl
* via GL_EXT_fog_coord .
*/
match_allows_spec_alpha ,
quirk_allows_specular_alpha ,
" Allow specular alpha quirk "
2009-09-28 12:24:00 +02:00
} ,
{
/* The pixel formats provided by GL_NV_texture_shader are broken on OSX
* ( rdar : //5682521).
*/
match_apple_nvts ,
quirk_apple_nvts ,
" Apple NV_texture_shader disable "
} ,
2009-09-28 12:30:48 +02:00
{
match_broken_nv_clip ,
quirk_disable_nvvp_clip ,
" Apple NV_vertex_program clip bug quirk "
} ,
2010-03-17 21:59:51 +01:00
{
match_fbo_tex_update ,
quirk_fbo_tex_update ,
" FBO rebind for attachment updates "
} ,
2009-07-06 10:08:42 +02:00
} ;
/* Certain applications (Steam) complain if we report an outdated driver version. In general,
* reporting a driver version is moot because we are not the Windows driver , and we have different
* bugs , features , etc .
*
2009-11-12 10:26:53 +01:00
* The driver version has the form " x.y.z.w " .
*
* " x " is the Windows version the driver is meant for :
* 4 - > 95 / 98 / NT4
* 5 - > 2000
* 6 - > 2000 / XP
* 7 - > Vista
* 8 - > Win 7
*
* " y " is the Direct3D level the driver supports :
* 11 - > d3d6
* 12 - > d3d7
* 13 - > d3d8
* 14 - > d3d9
* 15 - > d3d10
*
* " z " is unknown , possibly vendor specific .
*
* " w " is the vendor specific driver version .
*/
2009-07-06 10:08:42 +02:00
struct driver_version_information
{
2010-03-03 08:16:28 +01:00
WORD vendor ; /* reported PCI card vendor ID */
2009-07-06 10:08:42 +02:00
WORD card ; /* reported PCI card device ID */
const char * description ; /* Description of the card e.g. NVIDIA RIVA TNT */
2009-11-12 10:26:53 +01:00
WORD d3d_level ; /* driver hiword to report */
2009-07-06 10:08:42 +02:00
WORD lopart_hi , lopart_lo ; /* driver loword to report */
} ;
static const struct driver_version_information driver_version_table [ ] =
{
/* Nvidia drivers. Geforce6 and newer cards are supported by the current driver (180.x)
* GeforceFX support is up to 173. x , - driver uses numbering x . y .11 .7341 for 173.41 where x is the windows revision ( 6 = 2000 / xp , 7 = vista ) , y is unknown
* Geforce2MX / 3 / 4 up to 96. x - driver uses numbering 9.6 .8 .9 for 96.89
* TNT / Geforce1 / 2 up to 71. x - driver uses numbering 7.1 .8 .6 for 71.86
*
* All version numbers used below are from the Linux nvidia drivers . */
2010-03-01 19:26:04 +01:00
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_RIVA_TNT , " NVIDIA RIVA TNT " , 1 , 8 , 6 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_RIVA_TNT2 , " NVIDIA RIVA TNT2/TNT2 Pro " , 1 , 8 , 6 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE , " NVIDIA GeForce 256 " , 1 , 8 , 6 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE2_MX , " NVIDIA GeForce2 MX/MX 400 " , 6 , 4 , 3 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE2 , " NVIDIA GeForce2 GTS/GeForce2 Pro " , 1 , 8 , 6 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE3 , " NVIDIA GeForce3 " , 6 , 10 , 9371 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE4_MX , " NVIDIA GeForce4 MX 460 " , 6 , 10 , 9371 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE4_TI4200 , " NVIDIA GeForce4 Ti 4200 " , 6 , 10 , 9371 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCEFX_5200 , " NVIDIA GeForce FX 5200 " , 15 , 11 , 7516 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCEFX_5600 , " NVIDIA GeForce FX 5600 " , 15 , 11 , 7516 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCEFX_5800 , " NVIDIA GeForce FX 5800 " , 15 , 11 , 7516 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_6200 , " NVIDIA GeForce 6200 " , 15 , 11 , 8618 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_6600GT , " NVIDIA GeForce 6600 GT " , 15 , 11 , 8618 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_6800 , " NVIDIA GeForce 6800 " , 15 , 11 , 8618 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_7300 , " NVIDIA GeForce Go 7300 " , 15 , 11 , 8585 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_7400 , " NVIDIA GeForce Go 7400 " , 15 , 11 , 8585 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_7600 , " NVIDIA GeForce 7600 GT " , 15 , 11 , 8618 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_7800GT , " NVIDIA GeForce 7800 GT " , 15 , 11 , 8618 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_8300GS , " NVIDIA GeForce 8300 GS " , 15 , 11 , 8618 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_8600GT , " NVIDIA GeForce 8600 GT " , 15 , 11 , 8618 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_8600MGT , " NVIDIA GeForce 8600M GT " , 15 , 11 , 8585 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_8800GTS , " NVIDIA GeForce 8800 GTS " , 15 , 11 , 8618 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_9200 , " NVIDIA GeForce 9200 " , 15 , 11 , 8618 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_9400GT , " NVIDIA GeForce 9400 GT " , 15 , 11 , 8618 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_9500GT , " NVIDIA GeForce 9500 GT " , 15 , 11 , 8618 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_9600GT , " NVIDIA GeForce 9600 GT " , 15 , 11 , 8618 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_9800GT , " NVIDIA GeForce 9800 GT " , 15 , 11 , 8618 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_GTX260 , " NVIDIA GeForce GTX 260 " , 15 , 11 , 8618 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_GTX275 , " NVIDIA GeForce GTX 275 " , 15 , 11 , 8618 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_GTX280 , " NVIDIA GeForce GTX 280 " , 15 , 11 , 8618 } ,
{ HW_VENDOR_NVIDIA , CARD_NVIDIA_GEFORCE_GT240 , " NVIDIA GeForce GT 240 " , 15 , 11 , 8618 } ,
2009-07-06 10:08:42 +02:00
/* ATI cards. The driver versions are somewhat similar, but not quite the same. Let's hardcode. */
2010-03-01 19:26:04 +01:00
{ HW_VENDOR_ATI , CARD_ATI_RADEON_9500 , " ATI Radeon 9500 " , 14 , 10 , 6764 } ,
{ HW_VENDOR_ATI , CARD_ATI_RADEON_X700 , " ATI Radeon X700 SE " , 14 , 10 , 6764 } ,
{ HW_VENDOR_ATI , CARD_ATI_RADEON_X1600 , " ATI Radeon X1600 Series " , 14 , 10 , 6764 } ,
2010-04-16 08:49:40 +02:00
{ HW_VENDOR_ATI , CARD_ATI_RADEON_HD2350 , " ATI Mobility Radeon HD 2350 " , 14 , 10 , 6764 } ,
2010-03-01 19:26:04 +01:00
{ HW_VENDOR_ATI , CARD_ATI_RADEON_HD2600 , " ATI Mobility Radeon HD 2600 " , 14 , 10 , 6764 } ,
{ HW_VENDOR_ATI , CARD_ATI_RADEON_HD2900 , " ATI Radeon HD 2900 XT " , 14 , 10 , 6764 } ,
{ HW_VENDOR_ATI , CARD_ATI_RADEON_HD4350 , " ATI Radeon HD 4350 " , 14 , 10 , 6764 } ,
{ HW_VENDOR_ATI , CARD_ATI_RADEON_HD4600 , " ATI Radeon HD 4600 Series " , 14 , 10 , 6764 } ,
{ HW_VENDOR_ATI , CARD_ATI_RADEON_HD4700 , " ATI Radeon HD 4700 Series " , 14 , 10 , 6764 } ,
{ HW_VENDOR_ATI , CARD_ATI_RADEON_HD4800 , " ATI Radeon HD 4800 Series " , 14 , 10 , 6764 } ,
{ HW_VENDOR_ATI , CARD_ATI_RADEON_HD5700 , " ATI Radeon HD 5700 Series " , 14 , 10 , 8681 } ,
{ HW_VENDOR_ATI , CARD_ATI_RADEON_HD5800 , " ATI Radeon HD 5800 Series " , 14 , 10 , 8681 } ,
2009-07-06 10:08:42 +02:00
/* TODO: Add information about legacy ATI hardware, Intel and other cards. */
} ;
2009-10-27 10:10:39 +01:00
static void init_driver_info ( struct wined3d_driver_info * driver_info ,
2010-03-03 08:16:28 +01:00
enum wined3d_pci_vendor vendor , enum wined3d_pci_device device )
2009-10-26 10:12:16 +01:00
{
2009-11-12 10:26:53 +01:00
OSVERSIONINFOW os_version ;
WORD driver_os_version ;
2009-10-26 10:12:16 +01:00
unsigned int i ;
2009-10-27 10:10:40 +01:00
if ( wined3d_settings . pci_vendor_id ! = PCI_VENDOR_NONE )
{
TRACE_ ( d3d_caps ) ( " Overriding PCI vendor ID with: %04x \n " , wined3d_settings . pci_vendor_id ) ;
2010-03-03 08:16:28 +01:00
vendor = wined3d_settings . pci_vendor_id ;
2009-10-27 10:10:40 +01:00
}
2010-03-03 08:16:28 +01:00
driver_info - > vendor = vendor ;
2009-10-27 10:10:40 +01:00
if ( wined3d_settings . pci_device_id ! = PCI_DEVICE_NONE )
{
TRACE_ ( d3d_caps ) ( " Overriding PCI device ID with: %04x \n " , wined3d_settings . pci_device_id ) ;
device = wined3d_settings . pci_device_id ;
}
2009-10-27 10:10:39 +01:00
driver_info - > device = device ;
2009-10-27 10:10:40 +01:00
2010-03-03 08:16:28 +01:00
switch ( vendor )
2009-10-27 10:10:41 +01:00
{
2010-03-01 19:26:04 +01:00
case HW_VENDOR_ATI :
2009-10-27 10:10:41 +01:00
driver_info - > name = " ati2dvag.dll " ;
break ;
2010-03-01 19:26:04 +01:00
case HW_VENDOR_NVIDIA :
2009-10-27 10:10:41 +01:00
driver_info - > name = " nv4_disp.dll " ;
break ;
2010-03-03 08:16:28 +01:00
case HW_VENDOR_INTEL :
2009-10-27 10:10:41 +01:00
default :
2010-03-03 08:16:28 +01:00
FIXME_ ( d3d_caps ) ( " Unhandled vendor %04x. \n " , vendor ) ;
2009-10-27 10:10:41 +01:00
driver_info - > name = " Display " ;
break ;
}
2009-11-12 10:26:53 +01:00
memset ( & os_version , 0 , sizeof ( os_version ) ) ;
os_version . dwOSVersionInfoSize = sizeof ( os_version ) ;
if ( ! GetVersionExW ( & os_version ) )
{
ERR ( " Failed to get OS version, reporting 2000/XP. \n " ) ;
driver_os_version = 6 ;
}
else
{
TRACE ( " OS version %u.%u. \n " , os_version . dwMajorVersion , os_version . dwMinorVersion ) ;
switch ( os_version . dwMajorVersion )
{
case 4 :
driver_os_version = 4 ;
break ;
case 5 :
driver_os_version = 6 ;
break ;
case 6 :
if ( os_version . dwMinorVersion = = 0 )
{
driver_os_version = 7 ;
}
else
{
if ( os_version . dwMinorVersion > 1 )
{
FIXME ( " Unhandled OS version %u.%u, reporting Win 7. \n " ,
os_version . dwMajorVersion , os_version . dwMinorVersion ) ;
}
driver_os_version = 8 ;
}
break ;
default :
FIXME ( " Unhandled OS version %u.%u, reporting 2000/XP. \n " ,
os_version . dwMajorVersion , os_version . dwMinorVersion ) ;
driver_os_version = 6 ;
break ;
}
}
2009-10-26 10:12:16 +01:00
driver_info - > description = " Direct3D HAL " ;
2009-11-12 10:26:53 +01:00
driver_info - > version_high = MAKEDWORD_VERSION ( driver_os_version , 15 ) ;
2009-10-26 10:12:16 +01:00
driver_info - > version_low = MAKEDWORD_VERSION ( 8 , 6 ) ; /* Nvidia RIVA TNT, arbitrary */
for ( i = 0 ; i < ( sizeof ( driver_version_table ) / sizeof ( driver_version_table [ 0 ] ) ) ; + + i )
{
2010-03-03 08:16:28 +01:00
if ( vendor = = driver_version_table [ i ] . vendor & & device = = driver_version_table [ i ] . card )
2009-10-26 10:12:16 +01:00
{
2010-03-03 08:16:28 +01:00
TRACE_ ( d3d_caps ) ( " Found card %04x:%04x in driver DB. \n " , vendor , device ) ;
2009-10-26 10:12:16 +01:00
driver_info - > description = driver_version_table [ i ] . description ;
2009-11-12 10:26:53 +01:00
driver_info - > version_high = MAKEDWORD_VERSION ( driver_os_version , driver_version_table [ i ] . d3d_level ) ;
2009-10-26 10:12:16 +01:00
driver_info - > version_low = MAKEDWORD_VERSION ( driver_version_table [ i ] . lopart_hi ,
driver_version_table [ i ] . lopart_lo ) ;
break ;
}
}
TRACE_ ( d3d_caps ) ( " Reporting (fake) driver version 0x%08x-0x%08x. \n " ,
driver_info - > version_high , driver_info - > version_low ) ;
}
2009-07-06 10:08:42 +02:00
/* Context activation is done by the caller. */
2009-10-27 10:10:39 +01:00
static void fixup_extensions ( struct wined3d_gl_info * gl_info , const char * gl_renderer ,
2010-03-03 08:16:26 +01:00
enum wined3d_gl_vendor gl_vendor , enum wined3d_pci_vendor card_vendor , enum wined3d_pci_device device )
2009-07-06 10:08:42 +02:00
{
unsigned int i ;
for ( i = 0 ; i < ( sizeof ( quirk_table ) / sizeof ( * quirk_table ) ) ; + + i )
{
2010-03-03 08:16:26 +01:00
if ( ! quirk_table [ i ] . match ( gl_info , gl_renderer , gl_vendor , card_vendor , device ) ) continue ;
2009-07-06 10:08:42 +02:00
TRACE_ ( d3d_caps ) ( " Applying driver quirk \" %s \" . \n " , quirk_table [ i ] . description ) ;
quirk_table [ i ] . apply ( gl_info ) ;
}
/* Find out if PBOs work as they are supposed to. */
test_pbo_functionality ( gl_info ) ;
}
2009-08-14 09:23:22 +02:00
static DWORD wined3d_parse_gl_version ( const char * gl_version )
{
const char * ptr = gl_version ;
int major , minor ;
major = atoi ( ptr ) ;
if ( major < = 0 ) ERR_ ( d3d_caps ) ( " Invalid opengl major version: %d. \n " , major ) ;
while ( isdigit ( * ptr ) ) + + ptr ;
if ( * ptr + + ! = ' . ' ) ERR_ ( d3d_caps ) ( " Invalid opengl version string: %s. \n " , debugstr_a ( gl_version ) ) ;
minor = atoi ( ptr ) ;
TRACE_ ( d3d_caps ) ( " Found OpenGL version: %d.%d. \n " , major , minor ) ;
return MAKEDWORD_VERSION ( major , minor ) ;
}
2010-03-03 08:16:26 +01:00
static enum wined3d_gl_vendor wined3d_guess_gl_vendor ( struct wined3d_gl_info * gl_info , const char * gl_vendor_string , const char * gl_renderer )
{
/* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
* the opengl 1.2 + core , while other extensions are advertised , but software emulated . So try to
* detect the Apple OpenGL implementation to apply some extension fixups afterwards .
*
* Detecting this isn ' t really easy . The vendor string doesn ' t mention Apple . Compile - time checks
* aren ' t sufficient either because a Linux binary may display on a macos X server via remote X11 .
* So try to detect the GL implementation by looking at certain Apple extensions . Some extensions
* like client storage might be supported on other implementations too , but GL_APPLE_flush_render
* is specific to the Mac OS X window management , and GL_APPLE_ycbcr_422 is QuickTime specific . So
* the chance that other implementations support them is rather small since Win32 QuickTime uses
* DirectDraw , not OpenGL . */
if ( gl_info - > supported [ APPLE_FENCE ]
& & gl_info - > supported [ APPLE_CLIENT_STORAGE ]
& & gl_info - > supported [ APPLE_FLUSH_RENDER ]
& & gl_info - > supported [ APPLE_YCBCR_422 ] )
return GL_VENDOR_APPLE ;
if ( strstr ( gl_vendor_string , " NVIDIA " ) )
return GL_VENDOR_NVIDIA ;
if ( strstr ( gl_vendor_string , " ATI " ) )
2010-04-04 19:51:41 +02:00
return GL_VENDOR_FGLRX ;
2010-03-03 08:16:26 +01:00
if ( strstr ( gl_vendor_string , " Intel(R) " )
| | strstr ( gl_renderer , " Intel(R) " )
| | strstr ( gl_vendor_string , " Intel Inc. " ) )
return GL_VENDOR_INTEL ;
if ( strstr ( gl_vendor_string , " Mesa " )
2010-03-01 19:31:00 +01:00
| | strstr ( gl_vendor_string , " Advanced Micro Devices, Inc. " )
2010-03-03 08:16:26 +01:00
| | strstr ( gl_vendor_string , " DRI R300 Project " )
2010-03-01 19:31:00 +01:00
| | strstr ( gl_vendor_string , " X.Org R300 Project " )
2010-03-03 08:16:26 +01:00
| | strstr ( gl_vendor_string , " Tungsten Graphics, Inc " )
| | strstr ( gl_vendor_string , " VMware, Inc. " )
2010-03-01 19:31:00 +01:00
| | strstr ( gl_renderer , " Mesa " )
| | strstr ( gl_renderer , " Gallium " ) )
2010-03-03 08:16:26 +01:00
return GL_VENDOR_MESA ;
2010-04-04 19:51:41 +02:00
FIXME_ ( d3d_caps ) ( " Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_UNKNOWN. \n " ,
debugstr_a ( gl_vendor_string ) ) ;
2010-03-03 08:16:26 +01:00
2010-04-04 19:51:41 +02:00
return GL_VENDOR_UNKNOWN ;
2010-03-03 08:16:26 +01:00
}
2010-03-01 19:26:04 +01:00
static enum wined3d_pci_vendor wined3d_guess_card_vendor ( const char * gl_vendor_string , const char * gl_renderer )
2009-08-14 09:23:21 +02:00
{
2010-03-01 19:26:04 +01:00
if ( strstr ( gl_vendor_string , " NVIDIA " ) )
return HW_VENDOR_NVIDIA ;
2009-08-14 09:23:21 +02:00
2010-03-03 08:16:26 +01:00
if ( strstr ( gl_vendor_string , " ATI " )
2010-03-01 19:31:00 +01:00
| | strstr ( gl_vendor_string , " Advanced Micro Devices, Inc. " )
2010-03-05 11:30:04 +01:00
| | strstr ( gl_vendor_string , " X.Org R300 Project " )
2010-03-03 08:16:26 +01:00
| | strstr ( gl_vendor_string , " DRI R300 Project " ) )
2010-03-01 19:26:04 +01:00
return HW_VENDOR_ATI ;
2009-08-14 09:23:21 +02:00
2010-03-01 19:26:04 +01:00
if ( strstr ( gl_vendor_string , " Intel(R) " )
2009-08-14 09:23:21 +02:00
| | strstr ( gl_renderer , " Intel(R) " )
2010-03-01 19:26:04 +01:00
| | strstr ( gl_vendor_string , " Intel Inc. " ) )
return HW_VENDOR_INTEL ;
2009-08-14 09:23:21 +02:00
2010-03-01 19:26:04 +01:00
if ( strstr ( gl_vendor_string , " Mesa " )
| | strstr ( gl_vendor_string , " Tungsten Graphics, Inc " )
| | strstr ( gl_vendor_string , " VMware, Inc. " ) )
2010-04-04 19:51:40 +02:00
return HW_VENDOR_SOFTWARE ;
2009-08-14 09:23:21 +02:00
2010-03-03 08:16:28 +01:00
FIXME_ ( d3d_caps ) ( " Received unrecognized GL_VENDOR %s. Returning HW_VENDOR_NVIDIA. \n " , debugstr_a ( gl_vendor_string ) ) ;
2009-08-14 09:23:21 +02:00
2010-03-03 08:16:28 +01:00
return HW_VENDOR_NVIDIA ;
2009-08-14 09:23:21 +02:00
}
2010-03-03 08:16:28 +01:00
2010-03-01 19:29:32 +01:00
2010-04-04 19:51:39 +02:00
static enum wined3d_pci_device select_card_nvidia_binary ( const struct wined3d_gl_info * gl_info ,
2010-04-01 11:34:49 +02:00
const char * gl_renderer , unsigned int * vidmem )
2010-03-01 19:29:32 +01:00
{
2010-04-14 14:19:19 +02:00
if ( WINE_D3D10_CAPABLE ( gl_info ) )
2010-03-01 19:29:32 +01:00
{
/* Geforce 200 - highend */
if ( strstr ( gl_renderer , " GTX 280 " )
| | strstr ( gl_renderer , " GTX 285 " )
| | strstr ( gl_renderer , " GTX 295 " ) )
{
* vidmem = 1024 ;
return CARD_NVIDIA_GEFORCE_GTX280 ;
}
/* Geforce 200 - midend high */
if ( strstr ( gl_renderer , " GTX 275 " ) )
{
* vidmem = 896 ;
return CARD_NVIDIA_GEFORCE_GTX275 ;
}
/* Geforce 200 - midend */
if ( strstr ( gl_renderer , " GTX 260 " ) )
{
* vidmem = 1024 ;
return CARD_NVIDIA_GEFORCE_GTX260 ;
}
/* Geforce 200 - midend */
if ( strstr ( gl_renderer , " GT 240 " ) )
{
* vidmem = 512 ;
return CARD_NVIDIA_GEFORCE_GT240 ;
}
/* Geforce9 - highend / Geforce 200 - midend (GTS 150/250 are based on the same core) */
if ( strstr ( gl_renderer , " 9800 " )
| | strstr ( gl_renderer , " GTS 150 " )
| | strstr ( gl_renderer , " GTS 250 " ) )
{
* vidmem = 512 ;
return CARD_NVIDIA_GEFORCE_9800GT ;
}
/* Geforce9 - midend */
if ( strstr ( gl_renderer , " 9600 " ) )
{
* vidmem = 384 ; /* The 9600GSO has 384MB, the 9600GT has 512-1024MB */
return CARD_NVIDIA_GEFORCE_9600GT ;
}
/* Geforce9 - midend low / Geforce 200 - low */
if ( strstr ( gl_renderer , " 9500 " )
| | strstr ( gl_renderer , " GT 120 " )
| | strstr ( gl_renderer , " GT 130 " ) )
{
* vidmem = 256 ; /* The 9500GT has 256-1024MB */
return CARD_NVIDIA_GEFORCE_9500GT ;
}
/* Geforce9 - lowend */
if ( strstr ( gl_renderer , " 9400 " ) )
{
* vidmem = 256 ; /* The 9400GT has 256-1024MB */
return CARD_NVIDIA_GEFORCE_9400GT ;
}
/* Geforce9 - lowend low */
if ( strstr ( gl_renderer , " 9100 " )
| | strstr ( gl_renderer , " 9200 " )
| | strstr ( gl_renderer , " 9300 " )
| | strstr ( gl_renderer , " G 100 " ) )
{
* vidmem = 256 ; /* The 9100-9300 cards have 256MB */
return CARD_NVIDIA_GEFORCE_9200 ;
}
/* Geforce8 - highend */
if ( strstr ( gl_renderer , " 8800 " ) )
{
* vidmem = 320 ; /* The 8800GTS uses 320MB, a 8800GTX can have 768MB */
return CARD_NVIDIA_GEFORCE_8800GTS ;
}
/* Geforce8 - midend mobile */
if ( strstr ( gl_renderer , " 8600 M " ) )
{
* vidmem = 512 ;
return CARD_NVIDIA_GEFORCE_8600MGT ;
}
/* Geforce8 - midend */
if ( strstr ( gl_renderer , " 8600 " )
| | strstr ( gl_renderer , " 8700 " ) )
{
* vidmem = 256 ;
return CARD_NVIDIA_GEFORCE_8600GT ;
}
/* Geforce8 - lowend */
if ( strstr ( gl_renderer , " 8100 " )
| | strstr ( gl_renderer , " 8200 " )
| | strstr ( gl_renderer , " 8300 " )
| | strstr ( gl_renderer , " 8400 " )
| | strstr ( gl_renderer , " 8500 " ) )
{
* vidmem = 128 ; /* 128-256MB for a 8300, 256-512MB for a 8400 */
return CARD_NVIDIA_GEFORCE_8300GS ;
}
2010-04-14 14:19:19 +02:00
/* Geforce8-compatible fall back if the GPU is not in the list yet */
* vidmem = 128 ;
return CARD_NVIDIA_GEFORCE_8300GS ;
}
/* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
* shader capabilities , so we use the shader capabilities to distinguish between FX and 6 xxx / 7 xxx .
*/
if ( WINE_D3D9_CAPABLE ( gl_info ) & & gl_info - > supported [ NV_VERTEX_PROGRAM3 ] )
{
2010-03-01 19:29:32 +01:00
/* Geforce7 - highend */
if ( strstr ( gl_renderer , " 7800 " )
| | strstr ( gl_renderer , " 7900 " )
| | strstr ( gl_renderer , " 7950 " )
| | strstr ( gl_renderer , " Quadro FX 4 " )
| | strstr ( gl_renderer , " Quadro FX 5 " ) )
{
* vidmem = 256 ; /* A 7800GT uses 256MB while highend 7900 cards can use 512MB */
return CARD_NVIDIA_GEFORCE_7800GT ;
}
/* Geforce7 midend */
if ( strstr ( gl_renderer , " 7600 " )
| | strstr ( gl_renderer , " 7700 " ) )
{
* vidmem = 256 ; /* The 7600 uses 256-512MB */
return CARD_NVIDIA_GEFORCE_7600 ;
}
/* Geforce7 lower medium */
if ( strstr ( gl_renderer , " 7400 " ) )
{
* vidmem = 256 ; /* The 7400 uses 256-512MB */
return CARD_NVIDIA_GEFORCE_7400 ;
}
/* Geforce7 lowend */
if ( strstr ( gl_renderer , " 7300 " ) )
{
* vidmem = 256 ; /* Mac Pros with this card have 256 MB */
return CARD_NVIDIA_GEFORCE_7300 ;
}
/* Geforce6 highend */
if ( strstr ( gl_renderer , " 6800 " ) )
{
* vidmem = 128 ; /* The 6800 uses 128-256MB, the 7600 uses 256-512MB */
return CARD_NVIDIA_GEFORCE_6800 ;
}
/* Geforce6 - midend */
if ( strstr ( gl_renderer , " 6600 " )
| | strstr ( gl_renderer , " 6610 " )
| | strstr ( gl_renderer , " 6700 " ) )
{
* vidmem = 128 ; /* A 6600GT has 128-256MB */
return CARD_NVIDIA_GEFORCE_6600GT ;
}
/* Geforce6/7 lowend */
* vidmem = 64 ; /* */
return CARD_NVIDIA_GEFORCE_6200 ; /* Geforce 6100/6150/6200/7300/7400/7500 */
}
if ( WINE_D3D9_CAPABLE ( gl_info ) )
{
/* GeforceFX - highend */
if ( strstr ( gl_renderer , " 5800 " )
| | strstr ( gl_renderer , " 5900 " )
| | strstr ( gl_renderer , " 5950 " )
| | strstr ( gl_renderer , " Quadro FX " ) )
{
* vidmem = 256 ; /* 5800-5900 cards use 256MB */
return CARD_NVIDIA_GEFORCEFX_5800 ;
}
/* GeforceFX - midend */
if ( strstr ( gl_renderer , " 5600 " )
| | strstr ( gl_renderer , " 5650 " )
| | strstr ( gl_renderer , " 5700 " )
| | strstr ( gl_renderer , " 5750 " ) )
{
* vidmem = 128 ; /* A 5600 uses 128-256MB */
return CARD_NVIDIA_GEFORCEFX_5600 ;
}
/* GeforceFX - lowend */
* vidmem = 64 ; /* Normal FX5200 cards use 64-256MB; laptop (non-standard) can have less */
return CARD_NVIDIA_GEFORCEFX_5200 ; /* GeforceFX 5100/5200/5250/5300/5500 */
}
if ( WINE_D3D8_CAPABLE ( gl_info ) )
{
if ( strstr ( gl_renderer , " GeForce4 Ti " ) | | strstr ( gl_renderer , " Quadro4 " ) )
{
* vidmem = 64 ; /* Geforce4 Ti cards have 64-128MB */
return CARD_NVIDIA_GEFORCE4_TI4200 ; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
}
* vidmem = 64 ; /* Geforce3 cards have 64-128MB */
return CARD_NVIDIA_GEFORCE3 ; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
}
if ( WINE_D3D7_CAPABLE ( gl_info ) )
{
if ( strstr ( gl_renderer , " GeForce4 MX " ) )
{
/* Most Geforce4MX GPUs have at least 64MB of memory, some
* early models had 32 MB but most have 64 MB or even 128 MB . */
* vidmem = 64 ;
return CARD_NVIDIA_GEFORCE4_MX ; /* MX420/MX440/MX460/MX4000 */
}
if ( strstr ( gl_renderer , " GeForce2 MX " ) | | strstr ( gl_renderer , " Quadro2 MXR " ) )
{
* vidmem = 32 ; /* Geforce2MX GPUs have 32-64MB of video memory */
return CARD_NVIDIA_GEFORCE2_MX ; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
}
if ( strstr ( gl_renderer , " GeForce2 " ) | | strstr ( gl_renderer , " Quadro2 " ) )
{
* vidmem = 32 ; /* Geforce2 GPUs have 32-64MB of video memory */
return CARD_NVIDIA_GEFORCE2 ; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
}
/* Most Geforce1 cards have 32MB, there are also some rare 16
* and 64 MB ( Dell ) models . */
* vidmem = 32 ;
return CARD_NVIDIA_GEFORCE ; /* Geforce 256/DDR, Quadro */
}
if ( strstr ( gl_renderer , " TNT2 " ) )
{
* vidmem = 32 ; /* Most TNT2 boards have 32MB, though there are 16MB boards too */
return CARD_NVIDIA_RIVA_TNT2 ; /* Riva TNT2 standard/M64/Pro/Ultra */
}
* vidmem = 16 ; /* Most TNT boards have 16MB, some rare models have 8MB */
return CARD_NVIDIA_RIVA_TNT ; /* Riva TNT, Vanta */
}
2010-04-04 19:51:39 +02:00
static enum wined3d_pci_device select_card_ati_binary ( const struct wined3d_gl_info * gl_info ,
2010-04-01 11:34:49 +02:00
const char * gl_renderer , unsigned int * vidmem )
2010-03-01 19:29:32 +01:00
{
/* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
*
* Beware : renderer string do not match exact card model ,
* eg HD 4800 is returned for multiple cards , even for RV790 based ones . */
2010-04-16 08:49:41 +02:00
if ( WINE_D3D10_CAPABLE ( gl_info ) )
2010-03-01 19:29:32 +01:00
{
/* Radeon EG CYPRESS XT / PRO HD5800 - highend */
if ( strstr ( gl_renderer , " HD 5800 " ) /* Radeon EG CYPRESS HD58xx generic renderer string */
| | strstr ( gl_renderer , " HD 5850 " ) /* Radeon EG CYPRESS XT */
| | strstr ( gl_renderer , " HD 5870 " ) ) /* Radeon EG CYPRESS PRO */
{
* vidmem = 1024 ; /* note: HD58xx cards use 1024MB */
return CARD_ATI_RADEON_HD5800 ;
}
/* Radeon EG JUNIPER XT / LE HD5700 - midend */
if ( strstr ( gl_renderer , " HD 5700 " ) /* Radeon EG JUNIPER HD57xx generic renderer string */
| | strstr ( gl_renderer , " HD 5750 " ) /* Radeon EG JUNIPER LE */
| | strstr ( gl_renderer , " HD 5770 " ) ) /* Radeon EG JUNIPER XT */
{
* vidmem = 512 ; /* note: HD5770 cards use 1024MB and HD5750 cards use 512MB or 1024MB */
return CARD_ATI_RADEON_HD5700 ;
}
/* Radeon R7xx HD4800 - highend */
if ( strstr ( gl_renderer , " HD 4800 " ) /* Radeon RV7xx HD48xx generic renderer string */
| | strstr ( gl_renderer , " HD 4830 " ) /* Radeon RV770 */
| | strstr ( gl_renderer , " HD 4850 " ) /* Radeon RV770 */
| | strstr ( gl_renderer , " HD 4870 " ) /* Radeon RV770 */
| | strstr ( gl_renderer , " HD 4890 " ) ) /* Radeon RV790 */
{
* vidmem = 512 ; /* note: HD4890 cards use 1024MB */
return CARD_ATI_RADEON_HD4800 ;
}
/* Radeon R740 HD4700 - midend */
if ( strstr ( gl_renderer , " HD 4700 " ) /* Radeon RV770 */
| | strstr ( gl_renderer , " HD 4770 " ) ) /* Radeon RV740 */
{
* vidmem = 512 ;
return CARD_ATI_RADEON_HD4700 ;
}
/* Radeon R730 HD4600 - midend */
if ( strstr ( gl_renderer , " HD 4600 " ) /* Radeon RV730 */
| | strstr ( gl_renderer , " HD 4650 " ) /* Radeon RV730 */
| | strstr ( gl_renderer , " HD 4670 " ) ) /* Radeon RV730 */
{
* vidmem = 512 ;
return CARD_ATI_RADEON_HD4600 ;
}
/* Radeon R710 HD4500/HD4350 - lowend */
if ( strstr ( gl_renderer , " HD 4350 " ) /* Radeon RV710 */
| | strstr ( gl_renderer , " HD 4550 " ) ) /* Radeon RV710 */
{
* vidmem = 256 ;
return CARD_ATI_RADEON_HD4350 ;
}
/* Radeon R6xx HD2900/HD3800 - highend */
if ( strstr ( gl_renderer , " HD 2900 " )
| | strstr ( gl_renderer , " HD 3870 " )
| | strstr ( gl_renderer , " HD 3850 " ) )
{
* vidmem = 512 ; /* HD2900/HD3800 uses 256-1024MB */
return CARD_ATI_RADEON_HD2900 ;
}
/* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
if ( strstr ( gl_renderer , " HD 2600 " )
| | strstr ( gl_renderer , " HD 3830 " )
| | strstr ( gl_renderer , " HD 3690 " )
| | strstr ( gl_renderer , " HD 3650 " ) )
{
* vidmem = 256 ; /* HD2600/HD3600 uses 256-512MB */
return CARD_ATI_RADEON_HD2600 ;
}
2010-04-16 08:49:40 +02:00
/* Radeon R6xx HD2350/HD2400/HD3400 - lowend
* Note HD2300 = DX9 , HD2350 = DX10 */
if ( strstr ( gl_renderer , " HD 2350 " )
2010-03-01 19:29:32 +01:00
| | strstr ( gl_renderer , " HD 2400 " )
| | strstr ( gl_renderer , " HD 3470 " )
| | strstr ( gl_renderer , " HD 3450 " )
| | strstr ( gl_renderer , " HD 3430 " )
| | strstr ( gl_renderer , " HD 3400 " ) )
{
2010-04-16 08:49:40 +02:00
* vidmem = 256 ; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */
return CARD_ATI_RADEON_HD2350 ;
2010-03-01 19:29:32 +01:00
}
/* Radeon R6xx/R7xx integrated */
if ( strstr ( gl_renderer , " HD 3100 " )
| | strstr ( gl_renderer , " HD 3200 " )
| | strstr ( gl_renderer , " HD 3300 " ) )
{
* vidmem = 128 ; /* 128MB */
return CARD_ATI_RADEON_HD3200 ;
}
2010-04-16 08:49:41 +02:00
/* Default for when no GPU has been found */
* vidmem = 128 ; /* 128MB */
return CARD_ATI_RADEON_HD3200 ;
}
if ( WINE_D3D8_CAPABLE ( gl_info ) )
{
2010-03-01 19:29:32 +01:00
/* Radeon R5xx */
if ( strstr ( gl_renderer , " X1600 " )
| | strstr ( gl_renderer , " X1650 " )
| | strstr ( gl_renderer , " X1800 " )
| | strstr ( gl_renderer , " X1900 " )
| | strstr ( gl_renderer , " X1950 " ) )
{
* vidmem = 128 ; /* X1600 uses 128-256MB, >=X1800 uses 256MB */
return CARD_ATI_RADEON_X1600 ;
}
2010-04-16 08:49:40 +02:00
/* Radeon R4xx + X1300/X1400/X1450/X1550/X2300/X2500/HD2300 (lowend R5xx)
* Note X2300 / X2500 / HD2300 are R5xx GPUs with a 2 xxx naming but they are still DX9 - only */
2010-03-01 19:29:32 +01:00
if ( strstr ( gl_renderer , " X700 " )
| | strstr ( gl_renderer , " X800 " )
| | strstr ( gl_renderer , " X850 " )
| | strstr ( gl_renderer , " X1300 " )
| | strstr ( gl_renderer , " X1400 " )
| | strstr ( gl_renderer , " X1450 " )
2010-04-16 08:49:40 +02:00
| | strstr ( gl_renderer , " X1550 " )
| | strstr ( gl_renderer , " X2300 " )
| | strstr ( gl_renderer , " X2500 " )
| | strstr ( gl_renderer , " HD 2300 " )
)
2010-03-01 19:29:32 +01:00
{
* vidmem = 128 ; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
return CARD_ATI_RADEON_X700 ;
}
/* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
if ( strstr ( gl_renderer , " Radeon Xpress " ) )
{
* vidmem = 64 ; /* Shared RAM, BIOS configurable, 64-256M */
return CARD_ATI_RADEON_XPRESS_200M ;
}
/* Radeon R3xx */
* vidmem = 64 ; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
return CARD_ATI_RADEON_9500 ; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
}
if ( WINE_D3D8_CAPABLE ( gl_info ) )
{
* vidmem = 64 ; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
return CARD_ATI_RADEON_8500 ; /* Radeon 8500/9000/9100/9200/9300 */
}
if ( WINE_D3D7_CAPABLE ( gl_info ) )
{
* vidmem = 32 ; /* There are models with up to 64MB */
return CARD_ATI_RADEON_7200 ; /* Radeon 7000/7100/7200/7500 */
}
* vidmem = 16 ; /* There are 16-32MB models */
return CARD_ATI_RAGE_128PRO ;
}
2010-04-04 19:51:39 +02:00
static enum wined3d_pci_device select_card_intel_binary ( const struct wined3d_gl_info * gl_info ,
2010-04-01 11:34:49 +02:00
const char * gl_renderer , unsigned int * vidmem )
2010-03-01 19:29:32 +01:00
{
if ( strstr ( gl_renderer , " X3100 " ) )
{
/* MacOS calls the card GMA X3100, Google findings also suggest the name GM965 */
* vidmem = 128 ;
return CARD_INTEL_X3100 ;
}
if ( strstr ( gl_renderer , " GMA 950 " ) | | strstr ( gl_renderer , " 945GM " ) )
{
/* MacOS calls the card GMA 950, but everywhere else the PCI ID is named 945GM */
* vidmem = 64 ;
return CARD_INTEL_I945GM ;
}
if ( strstr ( gl_renderer , " 915GM " ) ) return CARD_INTEL_I915GM ;
if ( strstr ( gl_renderer , " 915G " ) ) return CARD_INTEL_I915G ;
if ( strstr ( gl_renderer , " 865G " ) ) return CARD_INTEL_I865G ;
if ( strstr ( gl_renderer , " 855G " ) ) return CARD_INTEL_I855G ;
if ( strstr ( gl_renderer , " 830G " ) ) return CARD_INTEL_I830G ;
return CARD_INTEL_I915G ;
}
2010-04-04 19:51:39 +02:00
static enum wined3d_pci_device select_card_ati_mesa ( const struct wined3d_gl_info * gl_info ,
2010-04-01 11:34:49 +02:00
const char * gl_renderer , unsigned int * vidmem )
2010-03-01 19:31:00 +01:00
{
/* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
*
* Beware : renderer string do not match exact card model ,
* eg HD 4800 is returned for multiple cards , even for RV790 based ones . */
if ( strstr ( gl_renderer , " Gallium " ) )
{
/* Radeon R7xx HD4800 - highend */
if ( strstr ( gl_renderer , " R700 " ) /* Radeon R7xx HD48xx generic renderer string */
| | strstr ( gl_renderer , " RV770 " ) /* Radeon RV770 */
| | strstr ( gl_renderer , " RV790 " ) ) /* Radeon RV790 */
{
* vidmem = 512 ; /* note: HD4890 cards use 1024MB */
return CARD_ATI_RADEON_HD4800 ;
}
/* Radeon R740 HD4700 - midend */
if ( strstr ( gl_renderer , " RV740 " ) ) /* Radeon RV740 */
{
* vidmem = 512 ;
return CARD_ATI_RADEON_HD4700 ;
}
/* Radeon R730 HD4600 - midend */
if ( strstr ( gl_renderer , " RV730 " ) ) /* Radeon RV730 */
{
* vidmem = 512 ;
return CARD_ATI_RADEON_HD4600 ;
}
/* Radeon R710 HD4500/HD4350 - lowend */
if ( strstr ( gl_renderer , " RV710 " ) ) /* Radeon RV710 */
{
* vidmem = 256 ;
return CARD_ATI_RADEON_HD4350 ;
}
/* Radeon R6xx HD2900/HD3800 - highend */
if ( strstr ( gl_renderer , " R600 " )
| | strstr ( gl_renderer , " RV670 " )
| | strstr ( gl_renderer , " R680 " ) )
{
* vidmem = 512 ; /* HD2900/HD3800 uses 256-1024MB */
return CARD_ATI_RADEON_HD2900 ;
}
/* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
if ( strstr ( gl_renderer , " RV630 " )
| | strstr ( gl_renderer , " RV635 " ) )
{
* vidmem = 256 ; /* HD2600/HD3600 uses 256-512MB */
return CARD_ATI_RADEON_HD2600 ;
}
2010-04-16 08:49:40 +02:00
/* Radeon R6xx HD2350/HD2400/HD3400 - lowend */
2010-03-01 19:31:00 +01:00
if ( strstr ( gl_renderer , " RV610 " )
| | strstr ( gl_renderer , " RV620 " ) )
{
2010-04-16 08:49:40 +02:00
* vidmem = 256 ; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */
return CARD_ATI_RADEON_HD2350 ;
2010-03-01 19:31:00 +01:00
}
/* Radeon R6xx/R7xx integrated */
if ( strstr ( gl_renderer , " RS780 " )
| | strstr ( gl_renderer , " RS880 " ) )
{
* vidmem = 128 ; /* 128MB */
return CARD_ATI_RADEON_HD3200 ;
}
/* Radeon R5xx */
if ( strstr ( gl_renderer , " RV530 " )
| | strstr ( gl_renderer , " RV535 " )
| | strstr ( gl_renderer , " RV560 " )
| | strstr ( gl_renderer , " R520 " )
| | strstr ( gl_renderer , " RV570 " )
| | strstr ( gl_renderer , " R580 " ) )
{
* vidmem = 128 ; /* X1600 uses 128-256MB, >=X1800 uses 256MB */
return CARD_ATI_RADEON_X1600 ;
}
/* Radeon R4xx + X1300/X1400/X1450/X1550/X2300 (lowend R5xx) */
if ( strstr ( gl_renderer , " R410 " )
| | strstr ( gl_renderer , " R420 " )
| | strstr ( gl_renderer , " R423 " )
| | strstr ( gl_renderer , " R430 " )
| | strstr ( gl_renderer , " R480 " )
| | strstr ( gl_renderer , " R481 " )
| | strstr ( gl_renderer , " RV410 " )
| | strstr ( gl_renderer , " RV515 " )
| | strstr ( gl_renderer , " RV516 " ) )
{
* vidmem = 128 ; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
return CARD_ATI_RADEON_X700 ;
}
/* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
if ( strstr ( gl_renderer , " RS400 " )
| | strstr ( gl_renderer , " RS480 " )
| | strstr ( gl_renderer , " RS482 " )
| | strstr ( gl_renderer , " RS485 " )
| | strstr ( gl_renderer , " RS600 " )
| | strstr ( gl_renderer , " RS690 " )
| | strstr ( gl_renderer , " RS740 " ) )
{
* vidmem = 64 ; /* Shared RAM, BIOS configurable, 64-256M */
return CARD_ATI_RADEON_XPRESS_200M ;
}
/* Radeon R3xx */
if ( strstr ( gl_renderer , " R300 " )
| | strstr ( gl_renderer , " RV350 " )
| | strstr ( gl_renderer , " RV351 " )
| | strstr ( gl_renderer , " RV360 " )
| | strstr ( gl_renderer , " RV370 " )
| | strstr ( gl_renderer , " R350 " )
| | strstr ( gl_renderer , " R360 " ) )
{
* vidmem = 64 ; /* Radeon 9500 uses 64MB, higher models use up to 256MB */
return CARD_ATI_RADEON_9500 ; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
}
}
if ( WINE_D3D9_CAPABLE ( gl_info ) )
{
/* Radeon R7xx HD4800 - highend */
if ( strstr ( gl_renderer , " (R700 " ) /* Radeon R7xx HD48xx generic renderer string */
| | strstr ( gl_renderer , " (RV770 " ) /* Radeon RV770 */
| | strstr ( gl_renderer , " (RV790 " ) ) /* Radeon RV790 */
{
* vidmem = 512 ; /* note: HD4890 cards use 1024MB */
return CARD_ATI_RADEON_HD4800 ;
}
/* Radeon R740 HD4700 - midend */
if ( strstr ( gl_renderer , " (RV740 " ) ) /* Radeon RV740 */
{
* vidmem = 512 ;
return CARD_ATI_RADEON_HD4700 ;
}
/* Radeon R730 HD4600 - midend */
if ( strstr ( gl_renderer , " (RV730 " ) ) /* Radeon RV730 */
{
* vidmem = 512 ;
return CARD_ATI_RADEON_HD4600 ;
}
/* Radeon R710 HD4500/HD4350 - lowend */
if ( strstr ( gl_renderer , " (RV710 " ) ) /* Radeon RV710 */
{
* vidmem = 256 ;
return CARD_ATI_RADEON_HD4350 ;
}
/* Radeon R6xx HD2900/HD3800 - highend */
if ( strstr ( gl_renderer , " (R600 " )
| | strstr ( gl_renderer , " (RV670 " )
| | strstr ( gl_renderer , " (R680 " ) )
{
* vidmem = 512 ; /* HD2900/HD3800 uses 256-1024MB */
return CARD_ATI_RADEON_HD2900 ;
}
/* Radeon R6xx HD2600/HD3600 - midend; HD3830 is China-only midend */
if ( strstr ( gl_renderer , " (RV630 " )
| | strstr ( gl_renderer , " (RV635 " ) )
{
* vidmem = 256 ; /* HD2600/HD3600 uses 256-512MB */
return CARD_ATI_RADEON_HD2600 ;
}
/* Radeon R6xx HD2300/HD2400/HD3400 - lowend */
if ( strstr ( gl_renderer , " (RV610 " )
| | strstr ( gl_renderer , " (RV620 " ) )
{
2010-04-16 08:49:40 +02:00
* vidmem = 256 ; /* HD2350/2400 use 256MB, HD34xx use 256-512MB */
return CARD_ATI_RADEON_HD2350 ;
2010-03-01 19:31:00 +01:00
}
/* Radeon R6xx/R7xx integrated */
if ( strstr ( gl_renderer , " (RS780 " )
| | strstr ( gl_renderer , " (RS880 " ) )
{
* vidmem = 128 ; /* 128MB */
return CARD_ATI_RADEON_HD3200 ;
}
}
if ( WINE_D3D8_CAPABLE ( gl_info ) )
{
* vidmem = 64 ; /* 8500/9000 cards use mostly 64MB, though there are 32MB and 128MB models */
return CARD_ATI_RADEON_8500 ; /* Radeon 8500/9000/9100/9200/9300 */
}
if ( WINE_D3D7_CAPABLE ( gl_info ) )
{
* vidmem = 32 ; /* There are models with up to 64MB */
return CARD_ATI_RADEON_7200 ; /* Radeon 7000/7100/7200/7500 */
}
* vidmem = 16 ; /* There are 16-32MB models */
return CARD_ATI_RAGE_128PRO ;
}
2010-04-04 19:51:39 +02:00
static enum wined3d_pci_device select_card_nvidia_mesa ( const struct wined3d_gl_info * gl_info ,
2010-04-01 11:34:49 +02:00
const char * gl_renderer , unsigned int * vidmem )
2010-03-01 19:31:00 +01:00
{
FIXME_ ( d3d_caps ) ( " Card selection not handled for Mesa Nouveau driver \n " ) ;
if ( WINE_D3D9_CAPABLE ( gl_info ) ) return CARD_NVIDIA_GEFORCEFX_5600 ;
if ( WINE_D3D8_CAPABLE ( gl_info ) ) return CARD_NVIDIA_GEFORCE3 ;
if ( WINE_D3D7_CAPABLE ( gl_info ) ) return CARD_NVIDIA_GEFORCE ;
if ( WINE_D3D6_CAPABLE ( gl_info ) ) return CARD_NVIDIA_RIVA_TNT ;
return CARD_NVIDIA_RIVA_128 ;
}
2010-04-04 19:51:39 +02:00
static enum wined3d_pci_device select_card_intel_mesa ( const struct wined3d_gl_info * gl_info ,
2010-04-01 11:34:49 +02:00
const char * gl_renderer , unsigned int * vidmem )
2010-03-01 19:31:00 +01:00
{
FIXME_ ( d3d_caps ) ( " Card selection not handled for Mesa Intel driver \n " ) ;
return CARD_INTEL_I915G ;
}
2010-03-01 19:29:32 +01:00
struct vendor_card_selection
{
enum wined3d_gl_vendor gl_vendor ;
enum wined3d_pci_vendor card_vendor ;
const char * description ; /* Description of the card selector i.e. Apple OS/X Intel */
enum wined3d_pci_device ( * select_card ) ( const struct wined3d_gl_info * gl_info , const char * gl_renderer ,
unsigned int * vidmem ) ;
} ;
static const struct vendor_card_selection vendor_card_select_table [ ] =
{
{ GL_VENDOR_NVIDIA , HW_VENDOR_NVIDIA , " Nvidia binary driver " , select_card_nvidia_binary } ,
{ GL_VENDOR_APPLE , HW_VENDOR_NVIDIA , " Apple OSX NVidia binary driver " , select_card_nvidia_binary } ,
{ GL_VENDOR_APPLE , HW_VENDOR_ATI , " Apple OSX AMD/ATI binary driver " , select_card_ati_binary } ,
{ GL_VENDOR_APPLE , HW_VENDOR_INTEL , " Apple OSX Intel binary driver " , select_card_intel_binary } ,
2010-04-04 19:51:41 +02:00
{ GL_VENDOR_FGLRX , HW_VENDOR_ATI , " AMD/ATI binary driver " , select_card_ati_binary } ,
2010-03-01 19:31:00 +01:00
{ GL_VENDOR_MESA , HW_VENDOR_ATI , " Mesa AMD/ATI driver " , select_card_ati_mesa } ,
{ GL_VENDOR_MESA , HW_VENDOR_NVIDIA , " Mesa Nouveau driver " , select_card_nvidia_mesa } ,
{ GL_VENDOR_MESA , HW_VENDOR_INTEL , " Mesa Intel driver " , select_card_intel_mesa }
2010-03-01 19:29:32 +01:00
} ;
2009-10-27 10:10:39 +01:00
static enum wined3d_pci_device wined3d_guess_card ( const struct wined3d_gl_info * gl_info , const char * gl_renderer ,
2010-03-03 08:16:28 +01:00
enum wined3d_gl_vendor * gl_vendor , enum wined3d_pci_vendor * card_vendor , unsigned int * vidmem )
2009-08-14 09:23:24 +02:00
{
2010-03-01 19:29:32 +01:00
/* Above is a list of Nvidia and ATI GPUs. Both vendors have dozens of
2009-08-14 09:23:24 +02:00
* different GPUs with roughly the same features . In most cases GPUs from a
* certain family differ in clockspeeds , the amount of video memory and the
* number of shader pipelines .
*
* A Direct3D device object contains the PCI id ( vendor + device ) of the
* videocard which is used for rendering . Various applications use this
* information to get a rough estimation of the features of the card and
* some might use it for enabling 3 d effects only on certain types of
* videocards . In some cases games might even use it to work around bugs
* which happen on certain videocards / driver combinations . The problem is
* that OpenGL only exposes a rendering string containing the name of the
* videocard and not the PCI id .
*
* Various games depend on the PCI id , so somehow we need to provide one .
* A simple option is to parse the renderer string and translate this to
* the right PCI id . This is a lot of work because there are more than 200
* GPUs just for Nvidia . Various cards share the same renderer string , so
* the amount of code might be ' small ' but there are quite a number of
* exceptions which would make this a pain to maintain . Another way would
* be to query the PCI id from the operating system ( assuming this is the
* videocard which is used for rendering which is not always the case ) .
* This would work but it is not very portable . Second it would not work
* well in , let ' s say , a remote X situation in which the amount of 3 d
* features which can be used is limited .
*
* As said most games only use the PCI id to get an indication of the
* capabilities of the card . It doesn ' t really matter if the given id is
* the correct one if we return the id of a card with similar 3 d features .
*
* The code below checks the OpenGL capabilities of a videocard and matches
* that to a certain level of Direct3D functionality . Once a card passes
* the Direct3D9 check , we know that the card ( in case of Nvidia ) is at
* least a GeforceFX . To give a better estimate we do a basic check on the
* renderer string but if that won ' t pass we return a default card . This
* way is better than maintaining a full card database as even without a
* full database we can return a card with similar features . Second the
* size of the database can be made quite small because when you know what
* type of 3 d functionality a card has , you know to which GPU family the
* GPU must belong . Because of this you only have to check a small part of
* the renderer string to distinguishes between different models from that
* family .
*
* The code also selects a default amount of video memory which we will
* use for an estimation of the amount of free texture memory . In case of
* real D3D the amount of texture memory includes video memory and system
* memory ( to be specific AGP memory or in case of PCIE TurboCache /
* HyperMemory ) . We don ' t know how much system memory can be addressed by
* the system but we can make a reasonable estimation about the amount of
* video memory . If the value is slightly wrong it doesn ' t matter as we
* didn ' t include AGP - like memory which makes the amount of addressable
* memory higher and second OpenGL isn ' t that critical it moves to system
* memory behind our backs if really needed . Note that the amount of video
* memory can be overruled using a registry setting . */
2010-03-01 19:29:32 +01:00
int i ;
2009-08-14 09:23:24 +02:00
2010-03-01 19:29:32 +01:00
for ( i = 0 ; i < ( sizeof ( vendor_card_select_table ) / sizeof ( * vendor_card_select_table ) ) ; + + i )
{
if ( ( vendor_card_select_table [ i ] . gl_vendor ! = * gl_vendor )
| | ( vendor_card_select_table [ i ] . card_vendor ! = * card_vendor ) )
continue ;
TRACE_ ( d3d_caps ) ( " Applying card_selector \" %s \" . \n " , vendor_card_select_table [ i ] . description ) ;
return vendor_card_select_table [ i ] . select_card ( gl_info , gl_renderer , vidmem ) ;
2009-08-14 09:23:24 +02:00
}
2010-03-01 19:29:32 +01:00
FIXME_ ( d3d_caps ) ( " No card selector available for GL vendor %d and card vendor %04x. \n " ,
* gl_vendor , * card_vendor ) ;
/* Default to generic Nvidia hardware based on the supported OpenGL extensions. The choice
* for Nvidia was because the hardware and drivers they make are of good quality . This makes
* them a good generic choice . */
* card_vendor = HW_VENDOR_NVIDIA ;
if ( WINE_D3D9_CAPABLE ( gl_info ) ) return CARD_NVIDIA_GEFORCEFX_5600 ;
if ( WINE_D3D8_CAPABLE ( gl_info ) ) return CARD_NVIDIA_GEFORCE3 ;
if ( WINE_D3D7_CAPABLE ( gl_info ) ) return CARD_NVIDIA_GEFORCE ;
if ( WINE_D3D6_CAPABLE ( gl_info ) ) return CARD_NVIDIA_RIVA_TNT ;
return CARD_NVIDIA_RIVA_128 ;
2009-08-14 09:23:24 +02:00
}
2010-02-02 12:06:56 +01:00
static const struct fragment_pipeline * select_fragment_implementation ( struct wined3d_adapter * adapter )
{
const struct wined3d_gl_info * gl_info = & adapter - > gl_info ;
int vs_selected_mode , ps_selected_mode ;
select_shader_mode ( gl_info , & ps_selected_mode , & vs_selected_mode ) ;
if ( ( ps_selected_mode = = SHADER_ARB | | ps_selected_mode = = SHADER_GLSL )
& & gl_info - > supported [ ARB_FRAGMENT_PROGRAM ] ) return & arbfp_fragment_pipeline ;
else if ( ps_selected_mode = = SHADER_ATI ) return & atifs_fragment_pipeline ;
else if ( gl_info - > supported [ NV_REGISTER_COMBINERS ]
& & gl_info - > supported [ NV_TEXTURE_SHADER2 ] ) return & nvts_fragment_pipeline ;
else if ( gl_info - > supported [ NV_REGISTER_COMBINERS ] ) return & nvrc_fragment_pipeline ;
else return & ffp_fragment_pipeline ;
}
2010-02-02 12:06:57 +01:00
static const shader_backend_t * select_shader_backend ( struct wined3d_adapter * adapter )
{
int vs_selected_mode , ps_selected_mode ;
select_shader_mode ( & adapter - > gl_info , & ps_selected_mode , & vs_selected_mode ) ;
if ( vs_selected_mode = = SHADER_GLSL | | ps_selected_mode = = SHADER_GLSL ) return & glsl_shader_backend ;
if ( vs_selected_mode = = SHADER_ARB | | ps_selected_mode = = SHADER_ARB ) return & arb_program_shader_backend ;
return & none_shader_backend ;
}
2010-02-03 11:02:20 +01:00
static const struct blit_shader * select_blit_implementation ( struct wined3d_adapter * adapter )
{
const struct wined3d_gl_info * gl_info = & adapter - > gl_info ;
int vs_selected_mode , ps_selected_mode ;
select_shader_mode ( gl_info , & ps_selected_mode , & vs_selected_mode ) ;
if ( ( ps_selected_mode = = SHADER_ARB | | ps_selected_mode = = SHADER_GLSL )
& & gl_info - > supported [ ARB_FRAGMENT_PROGRAM ] ) return & arbfp_blit ;
else return & ffp_blit ;
}
2009-07-06 10:08:42 +02:00
/* Context activation is done by the caller. */
2010-02-02 12:06:56 +01:00
static BOOL IWineD3DImpl_FillGLCaps ( struct wined3d_adapter * adapter )
2009-07-17 10:34:01 +02:00
{
2010-02-02 12:06:56 +01:00
struct wined3d_driver_info * driver_info = & adapter - > driver_info ;
struct wined3d_gl_info * gl_info = & adapter - > gl_info ;
2009-07-06 10:08:42 +02:00
const char * GL_Extensions = NULL ;
const char * WGL_Extensions = NULL ;
2010-03-04 18:51:31 +01:00
const char * gl_vendor_str , * gl_renderer_str , * gl_version_str ;
2010-02-04 18:30:05 +01:00
struct fragment_caps fragment_caps ;
2010-03-03 08:16:26 +01:00
enum wined3d_gl_vendor gl_vendor ;
2010-03-01 19:26:04 +01:00
enum wined3d_pci_vendor card_vendor ;
2009-10-27 10:10:39 +01:00
enum wined3d_pci_device device ;
2009-07-06 10:08:42 +02:00
GLint gl_max ;
GLfloat gl_floatv [ 2 ] ;
unsigned i ;
HDC hdc ;
unsigned int vidmem = 0 ;
DWORD gl_version ;
size_t len ;
TRACE_ ( d3d_caps ) ( " (%p) \n " , gl_info ) ;
ENTER_GL ( ) ;
2010-03-04 18:51:31 +01:00
gl_renderer_str = ( const char * ) glGetString ( GL_RENDERER ) ;
TRACE_ ( d3d_caps ) ( " GL_RENDERER: %s. \n " , debugstr_a ( gl_renderer_str ) ) ;
if ( ! gl_renderer_str )
2009-07-06 10:08:42 +02:00
{
2009-09-02 09:27:56 +02:00
LEAVE_GL ( ) ;
2009-07-06 10:08:42 +02:00
ERR_ ( d3d_caps ) ( " Received a NULL GL_RENDERER. \n " ) ;
return FALSE ;
}
2010-03-04 18:51:31 +01:00
gl_vendor_str = ( const char * ) glGetString ( GL_VENDOR ) ;
TRACE_ ( d3d_caps ) ( " GL_VENDOR: %s. \n " , debugstr_a ( gl_vendor_str ) ) ;
if ( ! gl_vendor_str )
2009-07-06 10:08:42 +02:00
{
2009-09-02 09:27:56 +02:00
LEAVE_GL ( ) ;
2009-07-06 10:08:42 +02:00
ERR_ ( d3d_caps ) ( " Received a NULL GL_VENDOR. \n " ) ;
return FALSE ;
}
/* Parse the GL_VERSION field into major and minor information */
2010-03-04 18:51:31 +01:00
gl_version_str = ( const char * ) glGetString ( GL_VERSION ) ;
TRACE_ ( d3d_caps ) ( " GL_VERSION: %s. \n " , debugstr_a ( gl_version_str ) ) ;
if ( ! gl_version_str )
2009-07-06 10:08:42 +02:00
{
2009-09-02 09:27:56 +02:00
LEAVE_GL ( ) ;
2009-07-06 10:08:42 +02:00
ERR_ ( d3d_caps ) ( " Received a NULL GL_VERSION. \n " ) ;
return FALSE ;
}
2010-03-04 18:51:31 +01:00
gl_version = wined3d_parse_gl_version ( gl_version_str ) ;
2009-07-03 09:39:22 +02:00
2004-09-29 23:26:47 +02:00
/*
* Initialize openGL extension related variables
* with Default values
*/
2008-07-11 22:58:34 +02:00
memset ( gl_info - > supported , 0 , sizeof ( gl_info - > supported ) ) ;
2010-04-13 20:46:27 +02:00
gl_info - > limits . blends = 1 ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . buffers = 1 ;
gl_info - > limits . textures = 1 ;
gl_info - > limits . fragment_samplers = 1 ;
gl_info - > limits . vertex_samplers = 0 ;
gl_info - > limits . combined_samplers = gl_info - > limits . fragment_samplers + gl_info - > limits . vertex_samplers ;
gl_info - > limits . sampler_stages = 1 ;
gl_info - > limits . glsl_vs_float_constants = 0 ;
gl_info - > limits . glsl_ps_float_constants = 0 ;
gl_info - > limits . arb_vs_float_constants = 0 ;
gl_info - > limits . arb_vs_native_constants = 0 ;
gl_info - > limits . arb_vs_instructions = 0 ;
gl_info - > limits . arb_vs_temps = 0 ;
gl_info - > limits . arb_ps_float_constants = 0 ;
gl_info - > limits . arb_ps_local_constants = 0 ;
gl_info - > limits . arb_ps_instructions = 0 ;
gl_info - > limits . arb_ps_temps = 0 ;
2004-09-29 23:26:47 +02:00
/* Retrieve opengl defaults */
glGetIntegerv ( GL_MAX_CLIP_PLANES , & gl_max ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . clipplanes = min ( WINED3DMAXUSERCLIPPLANES , gl_max ) ;
2004-09-29 23:26:47 +02:00
TRACE_ ( d3d_caps ) ( " ClipPlanes support - num Planes=%d \n " , gl_max ) ;
glGetIntegerv ( GL_MAX_LIGHTS , & gl_max ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . lights = gl_max ;
2004-09-29 23:26:47 +02:00
TRACE_ ( d3d_caps ) ( " Lights support - max lights=%d \n " , gl_max ) ;
2005-07-10 19:48:07 +02:00
glGetIntegerv ( GL_MAX_TEXTURE_SIZE , & gl_max ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . texture_size = gl_max ;
2005-07-10 19:48:07 +02:00
TRACE_ ( d3d_caps ) ( " Maximum texture size support - max texture size=%d \n " , gl_max ) ;
2009-01-09 10:23:42 +01:00
glGetFloatv ( GL_ALIASED_POINT_SIZE_RANGE , gl_floatv ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . pointsize_min = gl_floatv [ 0 ] ;
gl_info - > limits . pointsize_max = gl_floatv [ 1 ] ;
2006-08-06 13:53:19 +02:00
TRACE_ ( d3d_caps ) ( " Maximum point size support - max point size=%f \n " , gl_floatv [ 1 ] ) ;
2005-07-10 19:48:07 +02:00
2009-07-03 09:39:22 +02:00
/* Parse the gl supported features, in theory enabling parts of our code appropriately. */
GL_Extensions = ( const char * ) glGetString ( GL_EXTENSIONS ) ;
if ( ! GL_Extensions )
{
2009-09-02 09:27:56 +02:00
LEAVE_GL ( ) ;
2009-07-03 09:39:22 +02:00
ERR_ ( d3d_caps ) ( " Received a NULL GL_EXTENSIONS. \n " ) ;
return FALSE ;
}
2009-09-02 09:27:56 +02:00
LEAVE_GL ( ) ;
2005-07-13 16:15:54 +02:00
TRACE_ ( d3d_caps ) ( " GL_Extensions reported: \n " ) ;
2009-07-03 09:39:22 +02:00
gl_info - > supported [ WINED3D_GL_EXT_NONE ] = TRUE ;
2009-06-04 10:16:21 +02:00
2009-07-03 09:39:22 +02:00
while ( * GL_Extensions )
{
const char * start ;
char current_ext [ 256 ] ;
2004-09-29 23:26:47 +02:00
2009-07-03 09:39:22 +02:00
while ( isspace ( * GL_Extensions ) ) + + GL_Extensions ;
start = GL_Extensions ;
while ( ! isspace ( * GL_Extensions ) & & * GL_Extensions ) + + GL_Extensions ;
2007-08-08 18:57:39 +02:00
2009-07-03 09:39:22 +02:00
len = GL_Extensions - start ;
if ( ! len | | len > = sizeof ( current_ext ) ) continue ;
2007-08-08 18:57:39 +02:00
2009-07-03 09:39:22 +02:00
memcpy ( current_ext , start , len ) ;
current_ext [ len ] = ' \0 ' ;
2009-08-14 09:23:20 +02:00
TRACE_ ( d3d_caps ) ( " - %s \n " , debugstr_a ( current_ext ) ) ;
2004-09-29 23:26:47 +02:00
2009-07-03 09:39:22 +02:00
for ( i = 0 ; i < ( sizeof ( EXTENSION_MAP ) / sizeof ( * EXTENSION_MAP ) ) ; + + i )
{
if ( ! strcmp ( current_ext , EXTENSION_MAP [ i ] . extension_string ) )
{
TRACE_ ( d3d_caps ) ( " FOUND: %s support. \n " , EXTENSION_MAP [ i ] . extension_string ) ;
gl_info - > supported [ EXTENSION_MAP [ i ] . extension ] = TRUE ;
break ;
2007-06-26 23:05:41 +02:00
}
}
2009-07-03 09:39:22 +02:00
}
2008-07-03 05:08:10 +02:00
2009-07-03 09:39:22 +02:00
/* Now work out what GL support this card really has */
# define USE_GL_FUNC(type, pfn, ext, replace) \
{ \
DWORD ver = ver_for_ext ( ext ) ; \
if ( gl_info - > supported [ ext ] ) gl_info - > pfn = ( type ) pwglGetProcAddress ( # pfn ) ; \
2009-07-06 10:08:40 +02:00
else if ( ver & & ver < = gl_version ) gl_info - > pfn = ( type ) pwglGetProcAddress ( # replace ) ; \
2009-07-03 09:39:22 +02:00
else gl_info - > pfn = NULL ; \
}
GL_EXT_FUNCS_GEN ;
2007-11-11 13:59:49 +01:00
# undef USE_GL_FUNC
2009-07-03 09:39:22 +02:00
# define USE_GL_FUNC(type, pfn, ext, replace) gl_info->pfn = (type)pwglGetProcAddress(#pfn);
WGL_EXT_FUNCS_GEN ;
2007-11-06 01:25:30 +01:00
# undef USE_GL_FUNC
2007-06-26 23:05:41 +02:00
2009-07-03 09:39:22 +02:00
ENTER_GL ( ) ;
2007-11-06 13:20:27 +01:00
2009-07-03 09:39:22 +02:00
/* Now mark all the extensions supported which are included in the opengl core version. Do this *after*
* loading the functions , otherwise the code above will load the extension entry points instead of the
* core functions , which may not work . */
for ( i = 0 ; i < ( sizeof ( EXTENSION_MAP ) / sizeof ( * EXTENSION_MAP ) ) ; + + i )
{
if ( ! gl_info - > supported [ EXTENSION_MAP [ i ] . extension ]
2009-07-06 10:08:40 +02:00
& & EXTENSION_MAP [ i ] . version < = gl_version & & EXTENSION_MAP [ i ] . version )
2009-07-03 09:39:22 +02:00
{
TRACE_ ( d3d_caps ) ( " GL CORE: %s support. \n " , EXTENSION_MAP [ i ] . extension_string ) ;
gl_info - > supported [ EXTENSION_MAP [ i ] . extension ] = TRUE ;
2007-06-26 23:05:41 +02:00
}
2009-07-03 09:39:22 +02:00
}
if ( gl_info - > supported [ APPLE_FENCE ] )
{
/* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
* The apple extension interacts with some other apple exts . Disable the NV
* extension if the apple one is support to prevent confusion in other parts
* of the code . */
gl_info - > supported [ NV_FENCE ] = FALSE ;
}
if ( gl_info - > supported [ APPLE_FLOAT_PIXELS ] )
{
/* GL_APPLE_float_pixels == GL_ARB_texture_float + GL_ARB_half_float_pixel
*
* The enums are the same :
* GL_RGBA16F_ARB = GL_RGBA_FLOAT16_APPLE = 0x881A
* GL_RGB16F_ARB = GL_RGB_FLOAT16_APPLE = 0x881B
* GL_RGBA32F_ARB = GL_RGBA_FLOAT32_APPLE = 0x8814
* GL_RGB32F_ARB = GL_RGB_FLOAT32_APPLE = 0x8815
* GL_HALF_FLOAT_ARB = GL_HALF_APPLE = 0x140B
*/
if ( ! gl_info - > supported [ ARB_TEXTURE_FLOAT ] )
{
TRACE_ ( d3d_caps ) ( " IMPLIED: GL_ARB_texture_float support(from GL_APPLE_float_pixels. \n " ) ;
gl_info - > supported [ ARB_TEXTURE_FLOAT ] = TRUE ;
2007-06-26 23:05:41 +02:00
}
2009-07-03 09:39:22 +02:00
if ( ! gl_info - > supported [ ARB_HALF_FLOAT_PIXEL ] )
{
TRACE_ ( d3d_caps ) ( " IMPLIED: GL_ARB_half_float_pixel support(from GL_APPLE_float_pixels. \n " ) ;
gl_info - > supported [ ARB_HALF_FLOAT_PIXEL ] = TRUE ;
2007-06-26 23:05:41 +02:00
}
2009-07-03 09:39:22 +02:00
}
2010-01-28 20:50:55 +01:00
if ( gl_info - > supported [ ARB_MAP_BUFFER_RANGE ] )
{
/* GL_ARB_map_buffer_range and GL_APPLE_flush_buffer_range provide the same
* functionality . Prefer the ARB extension */
gl_info - > supported [ APPLE_FLUSH_BUFFER_RANGE ] = FALSE ;
}
2009-07-03 09:39:22 +02:00
if ( gl_info - > supported [ ARB_TEXTURE_CUBE_MAP ] )
{
TRACE_ ( d3d_caps ) ( " IMPLIED: NVIDIA (NV) Texture Gen Reflection support. \n " ) ;
gl_info - > supported [ NV_TEXGEN_REFLECTION ] = TRUE ;
}
2009-09-01 09:09:35 +02:00
if ( ! gl_info - > supported [ ARB_DEPTH_CLAMP ] & & gl_info - > supported [ NV_DEPTH_CLAMP ] )
{
TRACE_ ( d3d_caps ) ( " IMPLIED: ARB_depth_clamp support (by NV_depth_clamp). \n " ) ;
gl_info - > supported [ ARB_DEPTH_CLAMP ] = TRUE ;
}
2010-01-25 19:51:31 +01:00
if ( ! gl_info - > supported [ ARB_VERTEX_ARRAY_BGRA ] & & gl_info - > supported [ EXT_VERTEX_ARRAY_BGRA ] )
{
TRACE_ ( d3d_caps ) ( " IMPLIED: ARB_vertex_array_bgra support (by EXT_vertex_array_bgra). \n " ) ;
gl_info - > supported [ ARB_VERTEX_ARRAY_BGRA ] = TRUE ;
}
2009-07-03 09:39:22 +02:00
if ( gl_info - > supported [ NV_TEXTURE_SHADER2 ] )
{
if ( gl_info - > supported [ NV_REGISTER_COMBINERS ] )
{
/* Also disable ATI_FRAGMENT_SHADER if register combiners and texture_shader2
* are supported . The nv extensions provide the same functionality as the
* ATI one , and a bit more ( signed pixelformats ) . */
gl_info - > supported [ ATI_FRAGMENT_SHADER ] = FALSE ;
2007-06-26 23:05:41 +02:00
}
2009-07-03 09:39:22 +02:00
}
2010-02-04 18:30:05 +01:00
if ( gl_info - > supported [ NV_REGISTER_COMBINERS ] )
{
glGetIntegerv ( GL_MAX_GENERAL_COMBINERS_NV , & gl_max ) ;
gl_info - > limits . general_combiners = gl_max ;
TRACE_ ( d3d_caps ) ( " Max general combiners: %d. \n " , gl_max ) ;
}
2009-07-03 09:39:22 +02:00
if ( gl_info - > supported [ ARB_DRAW_BUFFERS ] )
{
glGetIntegerv ( GL_MAX_DRAW_BUFFERS_ARB , & gl_max ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . buffers = gl_max ;
2009-07-03 09:39:22 +02:00
TRACE_ ( d3d_caps ) ( " Max draw buffers: %u. \n " , gl_max ) ;
}
if ( gl_info - > supported [ ARB_MULTITEXTURE ] )
{
glGetIntegerv ( GL_MAX_TEXTURE_UNITS_ARB , & gl_max ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . textures = min ( MAX_TEXTURES , gl_max ) ;
TRACE_ ( d3d_caps ) ( " Max textures: %d. \n " , gl_info - > limits . textures ) ;
2009-07-03 09:39:22 +02:00
if ( gl_info - > supported [ ARB_FRAGMENT_PROGRAM ] )
{
GLint tmp ;
glGetIntegerv ( GL_MAX_TEXTURE_IMAGE_UNITS_ARB , & tmp ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . fragment_samplers = min ( MAX_FRAGMENT_SAMPLERS , tmp ) ;
2007-11-26 23:19:03 +01:00
}
2009-07-03 09:39:22 +02:00
else
{
2009-10-29 10:37:10 +01:00
gl_info - > limits . fragment_samplers = max ( gl_info - > limits . fragment_samplers , gl_max ) ;
2008-03-22 14:31:52 +01:00
}
2009-10-29 10:37:10 +01:00
TRACE_ ( d3d_caps ) ( " Max fragment samplers: %d. \n " , gl_info - > limits . fragment_samplers ) ;
2009-07-03 09:39:22 +02:00
if ( gl_info - > supported [ ARB_VERTEX_SHADER ] )
{
GLint tmp ;
glGetIntegerv ( GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB , & tmp ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . vertex_samplers = tmp ;
2009-07-03 09:39:22 +02:00
glGetIntegerv ( GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB , & tmp ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . combined_samplers = tmp ;
2009-07-03 09:39:22 +02:00
/* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
* is known at shader link time . In a vertex shader + pixel shader combination this isn ' t
* an issue because then the sampler setup only depends on the two shaders . If a pixel
* shader is used with fixed function vertex processing we ' re fine too because fixed function
* vertex processing doesn ' t use any samplers . If fixed function fragment processing is
* used we have to make sure that all vertex sampler setups are valid together with all
* possible fixed function fragment processing setups . This is true if vsamplers + MAX_TEXTURES
* < = max_samplers . This is true on all d3d9 cards that support vtf ( gf 6 and gf7 cards ) .
* dx9 radeon cards do not support vertex texture fetch . DX10 cards have 128 samplers , and
* dx9 is limited to 8 fixed function texture stages and 4 vertex samplers . DX10 does not have
* a fixed function pipeline anymore .
*
* So this is just a check to check that our assumption holds true . If not , write a warning
* and reduce the number of vertex samplers or probably disable vertex texture fetch . */
2009-10-29 10:37:10 +01:00
if ( gl_info - > limits . vertex_samplers & & gl_info - > limits . combined_samplers < 12
& & MAX_TEXTURES + gl_info - > limits . vertex_samplers > gl_info - > limits . combined_samplers )
2009-07-03 09:39:22 +02:00
{
FIXME ( " OpenGL implementation supports %u vertex samplers and %u total samplers. \n " ,
2009-10-29 10:37:10 +01:00
gl_info - > limits . vertex_samplers , gl_info - > limits . combined_samplers ) ;
2009-07-03 09:39:22 +02:00
FIXME ( " Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers. \n " ) ;
2009-10-29 10:37:10 +01:00
if ( gl_info - > limits . combined_samplers > MAX_TEXTURES )
gl_info - > limits . vertex_samplers = gl_info - > limits . combined_samplers - MAX_TEXTURES ;
2009-07-03 09:39:22 +02:00
else
2009-10-29 10:37:10 +01:00
gl_info - > limits . vertex_samplers = 0 ;
2009-07-03 09:39:22 +02:00
}
2009-04-06 19:07:51 +02:00
}
2009-07-03 09:39:22 +02:00
else
{
2009-10-29 10:37:10 +01:00
gl_info - > limits . combined_samplers = gl_info - > limits . fragment_samplers ;
2009-05-06 19:36:08 +02:00
}
2009-10-29 10:37:10 +01:00
TRACE_ ( d3d_caps ) ( " Max vertex samplers: %u. \n " , gl_info - > limits . vertex_samplers ) ;
TRACE_ ( d3d_caps ) ( " Max combined samplers: %u. \n " , gl_info - > limits . combined_samplers ) ;
2009-07-03 09:39:22 +02:00
}
if ( gl_info - > supported [ ARB_VERTEX_BLEND ] )
{
glGetIntegerv ( GL_MAX_VERTEX_UNITS_ARB , & gl_max ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . blends = gl_max ;
TRACE_ ( d3d_caps ) ( " Max blends: %u. \n " , gl_info - > limits . blends ) ;
2009-07-03 09:39:22 +02:00
}
if ( gl_info - > supported [ EXT_TEXTURE3D ] )
{
glGetIntegerv ( GL_MAX_3D_TEXTURE_SIZE_EXT , & gl_max ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . texture3d_size = gl_max ;
TRACE_ ( d3d_caps ) ( " Max texture3D size: %d. \n " , gl_info - > limits . texture3d_size ) ;
2009-07-03 09:39:22 +02:00
}
if ( gl_info - > supported [ EXT_TEXTURE_FILTER_ANISOTROPIC ] )
{
glGetIntegerv ( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT , & gl_max ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . anisotropy = gl_max ;
TRACE_ ( d3d_caps ) ( " Max anisotropy: %d. \n " , gl_info - > limits . anisotropy ) ;
2009-07-03 09:39:22 +02:00
}
if ( gl_info - > supported [ ARB_FRAGMENT_PROGRAM ] )
{
GL_EXTCALL ( glGetProgramivARB ( GL_FRAGMENT_PROGRAM_ARB , GL_MAX_PROGRAM_ENV_PARAMETERS_ARB , & gl_max ) ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . arb_ps_float_constants = gl_max ;
TRACE_ ( d3d_caps ) ( " Max ARB_FRAGMENT_PROGRAM float constants: %d. \n " , gl_info - > limits . arb_ps_float_constants ) ;
2009-10-07 22:10:44 +02:00
GL_EXTCALL ( glGetProgramivARB ( GL_FRAGMENT_PROGRAM_ARB , GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB , & gl_max ) ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . arb_ps_native_constants = gl_max ;
TRACE_ ( d3d_caps ) ( " Max ARB_FRAGMENT_PROGRAM native float constants: %d. \n " ,
gl_info - > limits . arb_ps_native_constants ) ;
2009-07-03 09:39:22 +02:00
GL_EXTCALL ( glGetProgramivARB ( GL_FRAGMENT_PROGRAM_ARB , GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB , & gl_max ) ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . arb_ps_temps = gl_max ;
TRACE_ ( d3d_caps ) ( " Max ARB_FRAGMENT_PROGRAM native temporaries: %d. \n " , gl_info - > limits . arb_ps_temps ) ;
2009-07-03 09:39:22 +02:00
GL_EXTCALL ( glGetProgramivARB ( GL_FRAGMENT_PROGRAM_ARB , GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB , & gl_max ) ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . arb_ps_instructions = gl_max ;
TRACE_ ( d3d_caps ) ( " Max ARB_FRAGMENT_PROGRAM native instructions: %d. \n " , gl_info - > limits . arb_ps_instructions ) ;
2009-08-24 16:03:13 +02:00
GL_EXTCALL ( glGetProgramivARB ( GL_FRAGMENT_PROGRAM_ARB , GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB , & gl_max ) ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . arb_ps_local_constants = gl_max ;
TRACE_ ( d3d_caps ) ( " Max ARB_FRAGMENT_PROGRAM local parameters: %d. \n " , gl_info - > limits . arb_ps_instructions ) ;
2009-07-03 09:39:22 +02:00
}
if ( gl_info - > supported [ ARB_VERTEX_PROGRAM ] )
{
GL_EXTCALL ( glGetProgramivARB ( GL_VERTEX_PROGRAM_ARB , GL_MAX_PROGRAM_ENV_PARAMETERS_ARB , & gl_max ) ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . arb_vs_float_constants = gl_max ;
TRACE_ ( d3d_caps ) ( " Max ARB_VERTEX_PROGRAM float constants: %d. \n " , gl_info - > limits . arb_vs_float_constants ) ;
2009-10-07 22:10:44 +02:00
GL_EXTCALL ( glGetProgramivARB ( GL_VERTEX_PROGRAM_ARB , GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB , & gl_max ) ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . arb_vs_native_constants = gl_max ;
TRACE_ ( d3d_caps ) ( " Max ARB_VERTEX_PROGRAM native float constants: %d. \n " ,
gl_info - > limits . arb_vs_native_constants ) ;
2009-07-03 09:39:22 +02:00
GL_EXTCALL ( glGetProgramivARB ( GL_VERTEX_PROGRAM_ARB , GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB , & gl_max ) ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . arb_vs_temps = gl_max ;
TRACE_ ( d3d_caps ) ( " Max ARB_VERTEX_PROGRAM native temporaries: %d. \n " , gl_info - > limits . arb_vs_temps ) ;
2009-07-03 09:39:22 +02:00
GL_EXTCALL ( glGetProgramivARB ( GL_VERTEX_PROGRAM_ARB , GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB , & gl_max ) ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . arb_vs_instructions = gl_max ;
TRACE_ ( d3d_caps ) ( " Max ARB_VERTEX_PROGRAM native instructions: %d. \n " , gl_info - > limits . arb_vs_instructions ) ;
2009-07-03 09:39:22 +02:00
if ( test_arb_vs_offset_limit ( gl_info ) ) gl_info - > quirks | = WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT ;
}
if ( gl_info - > supported [ ARB_VERTEX_SHADER ] )
{
glGetIntegerv ( GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB , & gl_max ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . glsl_vs_float_constants = gl_max / 4 ;
TRACE_ ( d3d_caps ) ( " Max ARB_VERTEX_SHADER float constants: %u. \n " , gl_info - > limits . glsl_vs_float_constants ) ;
2009-07-03 09:39:22 +02:00
}
if ( gl_info - > supported [ ARB_FRAGMENT_SHADER ] )
{
glGetIntegerv ( GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB , & gl_max ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . glsl_ps_float_constants = gl_max / 4 ;
TRACE_ ( d3d_caps ) ( " Max ARB_FRAGMENT_SHADER float constants: %u. \n " , gl_info - > limits . glsl_ps_float_constants ) ;
2009-07-03 09:39:22 +02:00
glGetIntegerv ( GL_MAX_VARYING_FLOATS_ARB , & gl_max ) ;
2009-10-29 10:37:10 +01:00
gl_info - > limits . glsl_varyings = gl_max ;
2009-07-03 09:39:22 +02:00
TRACE_ ( d3d_caps ) ( " Max GLSL varyings: %u (%u 4 component varyings). \n " , gl_max , gl_max / 4 ) ;
}
2010-01-27 20:19:39 +01:00
if ( gl_info - > supported [ ARB_SHADING_LANGUAGE_100 ] )
{
const char * str = ( const char * ) glGetString ( GL_SHADING_LANGUAGE_VERSION_ARB ) ;
2010-04-05 21:10:15 +02:00
unsigned int major , minor ;
2010-01-27 20:19:39 +01:00
TRACE_ ( d3d_caps ) ( " GLSL version string: %s. \n " , debugstr_a ( str ) ) ;
2010-04-05 21:10:15 +02:00
/* The format of the GLSL version string is "major.minor[.release] [vendor info]". */
sscanf ( str , " %u.%u " , & major , & minor ) ;
gl_info - > glsl_version = MAKEDWORD_VERSION ( major , minor ) ;
2010-01-27 20:19:39 +01:00
}
2009-07-03 09:39:22 +02:00
if ( gl_info - > supported [ NV_LIGHT_MAX_EXPONENT ] )
{
2009-10-29 10:37:10 +01:00
glGetFloatv ( GL_MAX_SHININESS_NV , & gl_info - > limits . shininess ) ;
2009-07-03 09:39:22 +02:00
}
else
{
2009-10-29 10:37:10 +01:00
gl_info - > limits . shininess = 128.0f ;
2009-07-03 09:39:22 +02:00
}
if ( gl_info - > supported [ ARB_TEXTURE_NON_POWER_OF_TWO ] )
{
/* If we have full NP2 texture support, disable
* GL_ARB_texture_rectangle because we will never use it .
* This saves a few redundant glDisable calls . */
gl_info - > supported [ ARB_TEXTURE_RECTANGLE ] = FALSE ;
}
if ( gl_info - > supported [ ATI_FRAGMENT_SHADER ] )
{
/* Disable NV_register_combiners and fragment shader if this is supported.
* generally the NV extensions are preferred over the ATI ones , and this
* extension is disabled if register_combiners and texture_shader2 are both
* supported . So we reach this place only if we have incomplete NV dxlevel 8
* fragment processing support . */
gl_info - > supported [ NV_REGISTER_COMBINERS ] = FALSE ;
gl_info - > supported [ NV_REGISTER_COMBINERS2 ] = FALSE ;
gl_info - > supported [ NV_TEXTURE_SHADER ] = FALSE ;
gl_info - > supported [ NV_TEXTURE_SHADER2 ] = FALSE ;
}
if ( gl_info - > supported [ NV_HALF_FLOAT ] )
{
/* GL_ARB_half_float_vertex is a subset of GL_NV_half_float. */
gl_info - > supported [ ARB_HALF_FLOAT_VERTEX ] = TRUE ;
}
if ( gl_info - > supported [ ARB_POINT_SPRITE ] )
{
2009-10-29 10:37:10 +01:00
gl_info - > limits . point_sprite_units = gl_info - > limits . textures ;
2009-07-03 09:39:22 +02:00
}
else
{
2009-10-29 10:37:10 +01:00
gl_info - > limits . point_sprite_units = 0 ;
2004-09-29 23:26:47 +02:00
}
2009-07-07 11:08:02 +02:00
checkGLcall ( " extension detection " ) ;
2006-07-30 23:28:10 +02:00
2009-08-13 10:03:04 +02:00
LEAVE_GL ( ) ;
2010-02-02 12:06:56 +01:00
adapter - > fragment_pipe = select_fragment_implementation ( adapter ) ;
2010-02-02 12:06:57 +01:00
adapter - > shader_backend = select_shader_backend ( adapter ) ;
2010-02-03 11:02:20 +01:00
adapter - > blitter = select_blit_implementation ( adapter ) ;
2010-02-02 12:06:56 +01:00
2010-02-04 18:30:05 +01:00
adapter - > fragment_pipe - > get_caps ( gl_info , & fragment_caps ) ;
gl_info - > limits . texture_stages = fragment_caps . MaxTextureBlendStages ;
TRACE_ ( d3d_caps ) ( " Max texture stages: %u. \n " , gl_info - > limits . texture_stages ) ;
2006-09-26 20:31:52 +02:00
/* In some cases the number of texture stages can be larger than the number
* of samplers . The GF4 for example can use only 2 samplers ( no fragment
* shaders ) , but 8 texture stages ( register combiners ) . */
2009-10-29 10:37:10 +01:00
gl_info - > limits . sampler_stages = max ( gl_info - > limits . fragment_samplers , gl_info - > limits . texture_stages ) ;
2004-09-29 23:26:47 +02:00
2009-09-23 10:05:55 +02:00
if ( gl_info - > supported [ ARB_FRAMEBUFFER_OBJECT ] )
{
gl_info - > fbo_ops . glIsRenderbuffer = gl_info - > glIsRenderbuffer ;
gl_info - > fbo_ops . glBindRenderbuffer = gl_info - > glBindRenderbuffer ;
gl_info - > fbo_ops . glDeleteRenderbuffers = gl_info - > glDeleteRenderbuffers ;
gl_info - > fbo_ops . glGenRenderbuffers = gl_info - > glGenRenderbuffers ;
gl_info - > fbo_ops . glRenderbufferStorage = gl_info - > glRenderbufferStorage ;
gl_info - > fbo_ops . glRenderbufferStorageMultisample = gl_info - > glRenderbufferStorageMultisample ;
gl_info - > fbo_ops . glGetRenderbufferParameteriv = gl_info - > glGetRenderbufferParameteriv ;
gl_info - > fbo_ops . glIsFramebuffer = gl_info - > glIsFramebuffer ;
gl_info - > fbo_ops . glBindFramebuffer = gl_info - > glBindFramebuffer ;
gl_info - > fbo_ops . glDeleteFramebuffers = gl_info - > glDeleteFramebuffers ;
gl_info - > fbo_ops . glGenFramebuffers = gl_info - > glGenFramebuffers ;
gl_info - > fbo_ops . glCheckFramebufferStatus = gl_info - > glCheckFramebufferStatus ;
gl_info - > fbo_ops . glFramebufferTexture1D = gl_info - > glFramebufferTexture1D ;
gl_info - > fbo_ops . glFramebufferTexture2D = gl_info - > glFramebufferTexture2D ;
gl_info - > fbo_ops . glFramebufferTexture3D = gl_info - > glFramebufferTexture3D ;
gl_info - > fbo_ops . glFramebufferRenderbuffer = gl_info - > glFramebufferRenderbuffer ;
gl_info - > fbo_ops . glGetFramebufferAttachmentParameteriv = gl_info - > glGetFramebufferAttachmentParameteriv ;
gl_info - > fbo_ops . glBlitFramebuffer = gl_info - > glBlitFramebuffer ;
gl_info - > fbo_ops . glGenerateMipmap = gl_info - > glGenerateMipmap ;
}
else
{
if ( gl_info - > supported [ EXT_FRAMEBUFFER_OBJECT ] )
{
gl_info - > fbo_ops . glIsRenderbuffer = gl_info - > glIsRenderbufferEXT ;
gl_info - > fbo_ops . glBindRenderbuffer = gl_info - > glBindRenderbufferEXT ;
gl_info - > fbo_ops . glDeleteRenderbuffers = gl_info - > glDeleteRenderbuffersEXT ;
gl_info - > fbo_ops . glGenRenderbuffers = gl_info - > glGenRenderbuffersEXT ;
gl_info - > fbo_ops . glRenderbufferStorage = gl_info - > glRenderbufferStorageEXT ;
gl_info - > fbo_ops . glGetRenderbufferParameteriv = gl_info - > glGetRenderbufferParameterivEXT ;
gl_info - > fbo_ops . glIsFramebuffer = gl_info - > glIsFramebufferEXT ;
gl_info - > fbo_ops . glBindFramebuffer = gl_info - > glBindFramebufferEXT ;
gl_info - > fbo_ops . glDeleteFramebuffers = gl_info - > glDeleteFramebuffersEXT ;
gl_info - > fbo_ops . glGenFramebuffers = gl_info - > glGenFramebuffersEXT ;
gl_info - > fbo_ops . glCheckFramebufferStatus = gl_info - > glCheckFramebufferStatusEXT ;
gl_info - > fbo_ops . glFramebufferTexture1D = gl_info - > glFramebufferTexture1DEXT ;
gl_info - > fbo_ops . glFramebufferTexture2D = gl_info - > glFramebufferTexture2DEXT ;
gl_info - > fbo_ops . glFramebufferTexture3D = gl_info - > glFramebufferTexture3DEXT ;
gl_info - > fbo_ops . glFramebufferRenderbuffer = gl_info - > glFramebufferRenderbufferEXT ;
gl_info - > fbo_ops . glGetFramebufferAttachmentParameteriv = gl_info - > glGetFramebufferAttachmentParameterivEXT ;
gl_info - > fbo_ops . glGenerateMipmap = gl_info - > glGenerateMipmapEXT ;
}
else if ( wined3d_settings . offscreen_rendering_mode = = ORM_FBO )
{
WARN_ ( d3d_caps ) ( " Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode. \n " ) ;
wined3d_settings . offscreen_rendering_mode = ORM_BACKBUFFER ;
}
if ( gl_info - > supported [ EXT_FRAMEBUFFER_BLIT ] )
{
gl_info - > fbo_ops . glBlitFramebuffer = gl_info - > glBlitFramebufferEXT ;
}
if ( gl_info - > supported [ EXT_FRAMEBUFFER_MULTISAMPLE ] )
{
gl_info - > fbo_ops . glRenderbufferStorageMultisample = gl_info - > glRenderbufferStorageMultisampleEXT ;
}
2006-09-26 20:31:48 +02:00
}
2006-12-19 19:25:42 +01:00
/* MRTs are currently only supported when FBOs are used. */
2009-10-29 10:37:10 +01:00
if ( wined3d_settings . offscreen_rendering_mode ! = ORM_FBO )
{
gl_info - > limits . buffers = 1 ;
2006-12-19 19:25:42 +01:00
}
2010-03-04 18:51:31 +01:00
gl_vendor = wined3d_guess_gl_vendor ( gl_info , gl_vendor_str , gl_renderer_str ) ;
card_vendor = wined3d_guess_card_vendor ( gl_vendor_str , gl_renderer_str ) ;
TRACE_ ( d3d_caps ) ( " found GL_VENDOR (%s)->(0x%04x/0x%04x) \n " , debugstr_a ( gl_vendor_str ) , gl_vendor , card_vendor ) ;
2010-03-03 08:16:26 +01:00
2010-03-04 18:51:31 +01:00
device = wined3d_guess_card ( gl_info , gl_renderer_str , & gl_vendor , & card_vendor , & vidmem ) ;
2010-03-01 19:26:04 +01:00
TRACE_ ( d3d_caps ) ( " FOUND (fake) card: 0x%x (vendor id), 0x%x (device id) \n " , card_vendor , device ) ;
2006-08-19 11:58:23 +02:00
2007-09-23 00:46:21 +02:00
/* If we have an estimate use it, else default to 64MB; */
if ( vidmem )
gl_info - > vidmem = vidmem * 1024 * 1024 ; /* convert from MBs to bytes */
else
gl_info - > vidmem = WINE_DEFAULT_VIDMEM ;
2007-09-17 22:16:48 +02:00
2010-01-03 21:18:22 +01:00
gl_info - > wrap_lookup [ WINED3DTADDRESS_WRAP - WINED3DTADDRESS_WRAP ] = GL_REPEAT ;
gl_info - > wrap_lookup [ WINED3DTADDRESS_MIRROR - WINED3DTADDRESS_WRAP ] =
2009-10-23 10:26:10 +02:00
gl_info - > supported [ ARB_TEXTURE_MIRRORED_REPEAT ] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT ;
2010-01-03 21:18:22 +01:00
gl_info - > wrap_lookup [ WINED3DTADDRESS_CLAMP - WINED3DTADDRESS_WRAP ] = GL_CLAMP_TO_EDGE ;
gl_info - > wrap_lookup [ WINED3DTADDRESS_BORDER - WINED3DTADDRESS_WRAP ] =
2009-10-23 10:26:10 +02:00
gl_info - > supported [ ARB_TEXTURE_BORDER_CLAMP ] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT ;
2010-01-03 21:18:22 +01:00
gl_info - > wrap_lookup [ WINED3DTADDRESS_MIRRORONCE - WINED3DTADDRESS_WRAP ] =
2009-10-23 10:26:10 +02:00
gl_info - > supported [ ATI_TEXTURE_MIRROR_ONCE ] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT ;
2005-08-03 13:00:28 +02:00
2007-08-08 03:09:38 +02:00
/* Make sure there's an active HDC else the WGL extensions will fail */
2007-08-16 15:04:47 +02:00
hdc = pwglGetCurrentDC ( ) ;
2007-08-08 03:09:38 +02:00
if ( hdc ) {
2009-03-29 22:08:42 +02:00
/* Not all GL drivers might offer WGL extensions e.g. VirtualBox */
if ( GL_EXTCALL ( wglGetExtensionsStringARB ) )
WGL_Extensions = GL_EXTCALL ( wglGetExtensionsStringARB ( hdc ) ) ;
2005-07-13 16:15:54 +02:00
2007-08-08 03:09:38 +02:00
if ( NULL = = WGL_Extensions ) {
ERR ( " WGL_Extensions returns NULL \n " ) ;
2004-09-29 23:26:47 +02:00
} else {
2009-03-29 22:08:42 +02:00
TRACE_ ( d3d_caps ) ( " WGL_Extensions reported: \n " ) ;
2007-08-08 03:09:38 +02:00
while ( * WGL_Extensions ! = 0x00 ) {
2007-08-08 18:57:39 +02:00
const char * Start ;
2004-09-29 23:26:47 +02:00
char ThisExtn [ 256 ] ;
2005-07-13 16:15:54 +02:00
2007-08-08 18:57:39 +02:00
while ( isspace ( * WGL_Extensions ) ) WGL_Extensions + + ;
Start = WGL_Extensions ;
while ( ! isspace ( * WGL_Extensions ) & & * WGL_Extensions ! = 0x00 ) {
2007-08-08 03:09:38 +02:00
WGL_Extensions + + ;
2004-09-29 23:26:47 +02:00
}
2007-08-08 18:57:39 +02:00
len = WGL_Extensions - Start ;
if ( len = = 0 | | len > = sizeof ( ThisExtn ) )
continue ;
memcpy ( ThisExtn , Start , len ) ;
ThisExtn [ len ] = ' \0 ' ;
2009-08-14 09:23:20 +02:00
TRACE_ ( d3d_caps ) ( " - %s \n " , debugstr_a ( ThisExtn ) ) ;
2007-08-08 03:09:38 +02:00
2009-03-15 10:01:43 +01:00
if ( ! strcmp ( ThisExtn , " WGL_ARB_pixel_format " ) ) {
gl_info - > supported [ WGL_ARB_PIXEL_FORMAT ] = TRUE ;
TRACE_ ( d3d_caps ) ( " FOUND: WGL_ARB_pixel_format support \n " ) ;
}
2008-04-23 00:15:15 +02:00
if ( ! strcmp ( ThisExtn , " WGL_WINE_pixel_format_passthrough " ) ) {
gl_info - > supported [ WGL_WINE_PIXEL_FORMAT_PASSTHROUGH ] = TRUE ;
TRACE_ ( d3d_caps ) ( " FOUND: WGL_WINE_pixel_format_passthrough support \n " ) ;
}
2004-09-29 23:26:47 +02:00
}
}
}
2010-03-04 18:51:31 +01:00
fixup_extensions ( gl_info , gl_renderer_str , gl_vendor , card_vendor , device ) ;
2010-03-01 19:26:04 +01:00
init_driver_info ( driver_info , card_vendor , device ) ;
2009-07-06 10:08:41 +02:00
add_gl_compat_wrappers ( gl_info ) ;
2009-07-06 10:08:38 +02:00
return TRUE ;
2004-09-29 23:26:47 +02:00
}
/**********************************************************
* IWineD3D implementation follows
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-06-10 13:15:32 +02:00
static UINT WINAPI IWineD3DImpl_GetAdapterCount ( IWineD3D * iface ) {
2004-09-23 06:34:27 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
2009-03-11 10:15:09 +01:00
TRACE_ ( d3d_caps ) ( " (%p): Reporting %u adapters \n " , This , This - > adapter_count ) ;
return This - > adapter_count ;
2004-09-23 06:34:27 +02:00
}
2009-12-21 23:17:26 +01:00
static HRESULT WINAPI IWineD3DImpl_RegisterSoftwareDevice ( IWineD3D * iface , void * init_function )
{
FIXME ( " iface %p, init_function %p stub! \n " , iface , init_function ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-09-28 04:12:12 +02:00
}
2006-06-10 13:15:32 +02:00
static HMONITOR WINAPI IWineD3DImpl_GetAdapterMonitor ( IWineD3D * iface , UINT Adapter ) {
2004-09-28 04:12:12 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
2006-07-11 04:32:47 +02:00
2008-08-24 23:43:26 +02:00
TRACE_ ( d3d_caps ) ( " (%p)->(%d) \n " , This , Adapter ) ;
2004-09-28 04:12:12 +02:00
if ( Adapter > = IWineD3DImpl_GetAdapterCount ( iface ) ) {
return NULL ;
}
2006-07-11 04:32:47 +02:00
2009-03-11 10:15:09 +01:00
return MonitorFromPoint ( This - > adapters [ Adapter ] . monitorPoint , MONITOR_DEFAULTTOPRIMARY ) ;
2004-09-28 04:12:12 +02:00
}
2005-07-13 16:15:54 +02:00
/* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
2004-09-28 04:12:12 +02:00
of the same bpp but different resolutions */
2006-10-11 03:51:13 +02:00
/* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
2006-06-10 13:15:32 +02:00
static UINT WINAPI IWineD3DImpl_GetAdapterModeCount ( IWineD3D * iface , UINT Adapter , WINED3DFORMAT Format ) {
2004-09-28 04:12:12 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
TRACE_ ( d3d_caps ) ( " (%p}->(Adapter: %d, Format: %s) \n " , This , Adapter , debug_d3dformat ( Format ) ) ;
if ( Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
return 0 ;
}
2007-06-09 14:27:41 +02:00
/* TODO: Store modes per adapter and read it from the adapter structure */
2004-09-28 04:12:12 +02:00
if ( Adapter = = 0 ) { /* Display */
2010-03-19 13:19:51 +01:00
const struct wined3d_format_desc * format_desc = getFormatDescEntry ( Format , & This - > adapters [ Adapter ] . gl_info ) ;
2009-12-09 20:32:09 +01:00
UINT format_bits = format_desc - > byte_count * CHAR_BIT ;
2009-06-22 10:15:59 +02:00
unsigned int i = 0 ;
unsigned int j = 0 ;
DEVMODEW mode ;
2004-09-28 04:12:12 +02:00
2009-06-22 10:15:59 +02:00
memset ( & mode , 0 , sizeof ( mode ) ) ;
mode . dmSize = sizeof ( mode ) ;
2007-02-23 09:27:42 +01:00
2009-06-22 10:15:59 +02:00
while ( EnumDisplaySettingsExW ( NULL , j , & mode , 0 ) )
{
+ + j ;
2009-12-09 20:32:09 +01:00
if ( Format = = WINED3DFMT_UNKNOWN )
{
/* This is for D3D8, do not enumerate P8 here */
if ( mode . dmBitsPerPel = = 32 | | mode . dmBitsPerPel = = 16 ) + + i ;
}
else if ( mode . dmBitsPerPel = = format_bits )
2009-06-22 10:15:59 +02:00
{
2009-12-09 20:32:09 +01:00
+ + i ;
2004-09-28 04:12:12 +02:00
}
}
2007-02-23 09:27:42 +01:00
2004-09-28 04:12:12 +02:00
TRACE_ ( d3d_caps ) ( " (%p}->(Adapter: %d) => %d (out of %d) \n " , This , Adapter , i , j ) ;
return i ;
} else {
FIXME_ ( d3d_caps ) ( " Adapter not primary display \n " ) ;
}
return 0 ;
}
2006-10-11 03:51:13 +02:00
/* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_EnumAdapterModes ( IWineD3D * iface , UINT Adapter , WINED3DFORMAT Format , UINT Mode , WINED3DDISPLAYMODE * pMode ) {
2004-09-28 04:12:12 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
TRACE_ ( d3d_caps ) ( " (%p}->(Adapter:%d, mode:%d, pMode:%p, format:%s) \n " , This , Adapter , Mode , pMode , debug_d3dformat ( Format ) ) ;
/* Validate the parameters as much as possible */
2005-07-13 16:15:54 +02:00
if ( NULL = = pMode | |
2004-09-28 04:12:12 +02:00
Adapter > = IWineD3DImpl_GetAdapterCount ( iface ) | |
Mode > = IWineD3DImpl_GetAdapterModeCount ( iface , Adapter , Format ) ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-09-28 04:12:12 +02:00
}
2007-06-09 14:27:41 +02:00
/* TODO: Store modes per adapter and read it from the adapter structure */
2009-06-22 10:15:59 +02:00
if ( Adapter = = 0 )
{
2010-03-19 13:19:51 +01:00
const struct wined3d_format_desc * format_desc = getFormatDescEntry ( Format , & This - > adapters [ Adapter ] . gl_info ) ;
2009-12-09 20:32:09 +01:00
UINT format_bits = format_desc - > byte_count * CHAR_BIT ;
2004-09-28 04:12:12 +02:00
DEVMODEW DevModeW ;
int ModeIdx = 0 ;
2008-11-26 21:37:28 +01:00
UINT i = 0 ;
2006-12-20 13:44:08 +01:00
int j = 0 ;
2005-07-13 16:15:54 +02:00
2007-08-05 19:50:45 +02:00
ZeroMemory ( & DevModeW , sizeof ( DevModeW ) ) ;
DevModeW . dmSize = sizeof ( DevModeW ) ;
2006-12-20 13:44:08 +01:00
/* If we are filtering to a specific format (D3D9), then need to skip
all unrelated modes , but if mode is irrelevant ( D3D8 ) , then we can
just count through the ones with valid bit depths */
2009-12-09 20:32:09 +01:00
while ( ( i < = Mode ) & & EnumDisplaySettingsExW ( NULL , j + + , & DevModeW , 0 ) )
{
if ( Format = = WINED3DFMT_UNKNOWN )
{
/* This is for D3D8, do not enumerate P8 here */
if ( DevModeW . dmBitsPerPel = = 32 | | DevModeW . dmBitsPerPel = = 16 ) + + i ;
}
else if ( DevModeW . dmBitsPerPel = = format_bits )
2006-12-20 13:44:08 +01:00
{
2009-12-09 20:32:09 +01:00
+ + i ;
2004-09-28 04:12:12 +02:00
}
}
2006-12-20 13:44:08 +01:00
if ( i = = 0 ) {
TRACE_ ( d3d_caps ) ( " No modes found for format (%x - %s) \n " , Format , debug_d3dformat ( Format ) ) ;
return WINED3DERR_INVALIDCALL ;
}
ModeIdx = j - 1 ;
2004-09-28 04:12:12 +02:00
/* Now get the display mode via the calculated index */
2006-12-20 13:44:08 +01:00
if ( EnumDisplaySettingsExW ( NULL , ModeIdx , & DevModeW , 0 ) ) {
2004-09-28 04:12:12 +02:00
pMode - > Width = DevModeW . dmPelsWidth ;
pMode - > Height = DevModeW . dmPelsHeight ;
2009-08-26 10:24:09 +02:00
pMode - > RefreshRate = DEFAULT_REFRESH_RATE ;
2005-09-19 17:25:07 +02:00
if ( DevModeW . dmFields & DM_DISPLAYFREQUENCY )
2004-09-28 04:12:12 +02:00
pMode - > RefreshRate = DevModeW . dmDisplayFrequency ;
2007-11-30 16:29:49 +01:00
if ( Format = = WINED3DFMT_UNKNOWN ) {
pMode - > Format = pixelformat_for_depth ( DevModeW . dmBitsPerPel ) ;
2004-09-28 04:12:12 +02:00
} else {
pMode - > Format = Format ;
}
2006-12-20 13:44:08 +01:00
} else {
2004-09-28 04:12:12 +02:00
TRACE_ ( d3d_caps ) ( " Requested mode out of range %d \n " , Mode ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-09-28 04:12:12 +02:00
}
2007-02-23 09:27:42 +01:00
TRACE_ ( d3d_caps ) ( " W %d H %d rr %d fmt (%x - %s) bpp %u \n " , pMode - > Width , pMode - > Height ,
pMode - > RefreshRate , pMode - > Format , debug_d3dformat ( pMode - > Format ) ,
DevModeW . dmBitsPerPel ) ;
2009-06-22 10:15:59 +02:00
}
else
{
2004-09-28 04:12:12 +02:00
FIXME_ ( d3d_caps ) ( " Adapter not primary display \n " ) ;
}
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-09-28 04:12:12 +02:00
}
2009-12-21 23:17:26 +01:00
static HRESULT WINAPI IWineD3DImpl_GetAdapterDisplayMode ( IWineD3D * iface , UINT Adapter , WINED3DDISPLAYMODE * pMode )
{
TRACE ( " iface %p, adapter_idx %u, display_mode %p. \n " , iface , Adapter , pMode ) ;
2004-09-28 04:12:12 +02:00
2005-07-13 16:15:54 +02:00
if ( NULL = = pMode | |
2004-09-28 04:12:12 +02:00
Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-09-28 04:12:12 +02:00
}
if ( Adapter = = 0 ) { /* Display */
int bpp = 0 ;
DEVMODEW DevModeW ;
2007-08-05 19:50:45 +02:00
ZeroMemory ( & DevModeW , sizeof ( DevModeW ) ) ;
DevModeW . dmSize = sizeof ( DevModeW ) ;
2007-08-06 04:42:09 +02:00
EnumDisplaySettingsExW ( NULL , ENUM_CURRENT_SETTINGS , & DevModeW , 0 ) ;
2004-09-28 04:12:12 +02:00
pMode - > Width = DevModeW . dmPelsWidth ;
pMode - > Height = DevModeW . dmPelsHeight ;
bpp = DevModeW . dmBitsPerPel ;
2009-08-26 10:24:09 +02:00
pMode - > RefreshRate = DEFAULT_REFRESH_RATE ;
2004-09-28 04:12:12 +02:00
if ( DevModeW . dmFields & DM_DISPLAYFREQUENCY )
{
pMode - > RefreshRate = DevModeW . dmDisplayFrequency ;
}
2007-11-30 16:29:49 +01:00
pMode - > Format = pixelformat_for_depth ( bpp ) ;
2004-09-28 04:12:12 +02:00
} else {
FIXME_ ( d3d_caps ) ( " Adapter not primary display \n " ) ;
}
TRACE_ ( d3d_caps ) ( " returning w:%d, h:%d, ref:%d, fmt:%s \n " , pMode - > Width ,
pMode - > Height , pMode - > RefreshRate , debug_d3dformat ( pMode - > Format ) ) ;
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-09-28 04:12:12 +02:00
}
2004-09-23 06:34:27 +02:00
2005-07-10 19:48:07 +02:00
/* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
2004-09-29 23:26:47 +02:00
and fields being inserted in the middle , a new structure is used in place */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_GetAdapterIdentifier ( IWineD3D * iface , UINT Adapter , DWORD Flags ,
2004-09-29 23:26:47 +02:00
WINED3DADAPTER_IDENTIFIER * pIdentifier ) {
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
2009-10-26 10:12:16 +01:00
struct wined3d_adapter * adapter ;
2009-07-07 11:08:03 +02:00
size_t len ;
2004-09-29 23:26:47 +02:00
2006-10-01 05:20:10 +02:00
TRACE_ ( d3d_caps ) ( " (%p}->(Adapter: %d, Flags: %x, pId=%p) \n " , This , Adapter , Flags , pIdentifier ) ;
2004-09-29 23:26:47 +02:00
if ( Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-09-29 23:26:47 +02:00
}
2009-10-26 10:12:16 +01:00
adapter = & This - > adapters [ Adapter ] ;
2007-06-09 14:27:41 +02:00
/* Return the information requested */
TRACE_ ( d3d_caps ) ( " device/Vendor Name and Version detection using FillGLCaps \n " ) ;
2009-07-07 11:08:03 +02:00
if ( pIdentifier - > driver_size )
{
2009-10-26 10:12:16 +01:00
const char * name = adapter - > driver_info . name ;
len = min ( strlen ( name ) , pIdentifier - > driver_size - 1 ) ;
memcpy ( pIdentifier - > driver , name , len ) ;
2009-07-07 11:08:03 +02:00
pIdentifier - > driver [ len ] = ' \0 ' ;
}
if ( pIdentifier - > description_size )
{
2009-10-26 10:12:16 +01:00
const char * description = adapter - > driver_info . description ;
2009-07-07 11:08:03 +02:00
len = min ( strlen ( description ) , pIdentifier - > description_size - 1 ) ;
memcpy ( pIdentifier - > description , description , len ) ;
pIdentifier - > description [ len ] = ' \0 ' ;
}
/* Note that d3d8 doesn't supply a device name. */
if ( pIdentifier - > device_name_size )
{
static const char * device_name = " \\ \\ . \\ DISPLAY1 " ; /* FIXME: May depend on desktop? */
len = strlen ( device_name ) ;
if ( len > = pIdentifier - > device_name_size )
{
ERR ( " Device name size too small. \n " ) ;
return WINED3DERR_INVALIDCALL ;
}
memcpy ( pIdentifier - > device_name , device_name , len ) ;
pIdentifier - > device_name [ len ] = ' \0 ' ;
}
2009-10-26 10:12:16 +01:00
pIdentifier - > driver_version . u . HighPart = adapter - > driver_info . version_high ;
pIdentifier - > driver_version . u . LowPart = adapter - > driver_info . version_low ;
2009-10-27 10:10:39 +01:00
pIdentifier - > vendor_id = adapter - > driver_info . vendor ;
pIdentifier - > device_id = adapter - > driver_info . device ;
2009-07-07 11:08:03 +02:00
pIdentifier - > subsystem_id = 0 ;
pIdentifier - > revision = 0 ;
memcpy ( & pIdentifier - > device_identifier , & IID_D3DDEVICE_D3DUID , sizeof ( pIdentifier - > device_identifier ) ) ;
pIdentifier - > whql_level = ( Flags & WINED3DENUM_NO_WHQL_LEVEL ) ? 0 : 1 ;
2009-12-02 10:41:23 +01:00
memcpy ( & pIdentifier - > adapter_luid , & adapter - > luid , sizeof ( pIdentifier - > adapter_luid ) ) ;
2009-12-04 11:50:49 +01:00
pIdentifier - > video_memory = adapter - > TextureRam ;
2004-09-29 23:26:47 +02:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-09-29 23:26:47 +02:00
}
2009-07-17 10:34:01 +02:00
static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt ( const struct wined3d_gl_info * gl_info ,
2010-03-19 13:19:51 +01:00
const WineD3D_PixelFormat * cfg , const struct wined3d_format_desc * format_desc )
2009-03-13 10:44:18 +01:00
{
2007-08-11 16:25:58 +02:00
short redSize , greenSize , blueSize , alphaSize , colorBits ;
if ( ! cfg )
return FALSE ;
2010-03-24 22:34:38 +01:00
/* Float formats need FBOs. If FBOs are used this function isn't called */
if ( format_desc - > Flags & WINED3DFMT_FLAG_FLOAT ) return FALSE ;
2008-03-21 14:52:15 +01:00
if ( cfg - > iPixelType = = WGL_TYPE_RGBA_ARB ) { /* Integer RGBA formats */
2009-03-24 10:09:24 +01:00
if ( ! getColorBits ( format_desc , & redSize , & greenSize , & blueSize , & alphaSize , & colorBits ) )
2009-03-13 10:44:18 +01:00
{
2009-03-24 10:09:23 +01:00
ERR ( " Unable to check compatibility for Format=%s \n " , debug_d3dformat ( format_desc - > format ) ) ;
2008-03-21 14:52:15 +01:00
return FALSE ;
}
2007-08-11 16:25:58 +02:00
2008-03-21 14:52:15 +01:00
if ( cfg - > redSize < redSize )
return FALSE ;
2007-08-11 16:25:58 +02:00
2008-03-21 14:52:15 +01:00
if ( cfg - > greenSize < greenSize )
return FALSE ;
2007-08-11 16:25:58 +02:00
2008-03-21 14:52:15 +01:00
if ( cfg - > blueSize < blueSize )
return FALSE ;
2007-08-11 16:25:58 +02:00
2008-03-21 14:52:15 +01:00
if ( cfg - > alphaSize < alphaSize )
return FALSE ;
return TRUE ;
}
2007-08-11 16:25:58 +02:00
2010-03-21 19:16:23 +01:00
/* Probably a RGBA_float or color index mode */
2008-03-21 14:52:15 +01:00
return FALSE ;
2005-04-28 14:02:03 +02:00
}
2009-07-17 10:34:01 +02:00
static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt ( const struct wined3d_gl_info * gl_info ,
2010-03-19 13:19:51 +01:00
const WineD3D_PixelFormat * cfg , const struct wined3d_format_desc * format_desc )
2009-03-13 10:44:18 +01:00
{
2007-08-11 16:25:58 +02:00
short depthSize , stencilSize ;
2008-03-25 11:02:20 +01:00
BOOL lockable = FALSE ;
2007-08-11 16:25:58 +02:00
if ( ! cfg )
return FALSE ;
2009-03-24 10:09:24 +01:00
if ( ! getDepthStencilBits ( format_desc , & depthSize , & stencilSize ) )
2009-03-13 10:44:18 +01:00
{
2009-03-24 10:09:23 +01:00
ERR ( " Unable to check compatibility for Format=%s \n " , debug_d3dformat ( format_desc - > format ) ) ;
2007-08-11 16:25:58 +02:00
return FALSE ;
}
2010-03-24 22:34:38 +01:00
/* Float formats need FBOs. If FBOs are used this function isn't called */
if ( format_desc - > Flags & WINED3DFMT_FLAG_FLOAT ) return FALSE ;
2009-09-25 13:31:49 +02:00
if ( ( format_desc - > format = = WINED3DFMT_D16_LOCKABLE ) | | ( format_desc - > format = = WINED3DFMT_D32_FLOAT ) )
2008-03-25 11:02:20 +01:00
lockable = TRUE ;
/* On some modern cards like the Geforce8/9 GLX doesn't offer some dephthstencil formats which D3D9 reports.
* We can safely report ' compatible ' formats ( e . g . D24 can be used for D16 ) as long as we aren ' t dealing with
* a lockable format . This also helps D3D < = 7 as they expect D16 which isn ' t offered without this on Geforce8 cards . */
if ( ! ( cfg - > depthSize = = depthSize | | ( ! lockable & & cfg - > depthSize > depthSize ) ) )
2007-08-11 16:25:58 +02:00
return FALSE ;
2008-05-03 16:37:09 +02:00
/* Some cards like Intel i915 ones only offer D24S8 but lots of games also need a format without stencil, so
* allow more stencil bits than requested . */
if ( cfg - > stencilSize < stencilSize )
2007-08-11 16:25:58 +02:00
return FALSE ;
2005-10-04 17:50:57 +02:00
return TRUE ;
2005-04-28 14:02:03 +02:00
}
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_CheckDepthStencilMatch ( IWineD3D * iface , UINT Adapter , WINED3DDEVTYPE DeviceType ,
2005-07-13 16:15:54 +02:00
WINED3DFORMAT AdapterFormat ,
WINED3DFORMAT RenderTargetFormat ,
WINED3DFORMAT DepthStencilFormat ) {
2004-10-05 04:14:06 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
2007-08-11 16:25:58 +02:00
int nCfgs ;
2008-11-28 15:30:11 +01:00
const WineD3D_PixelFormat * cfgs ;
2009-10-21 10:33:58 +02:00
const struct wined3d_adapter * adapter ;
2010-03-19 13:19:51 +01:00
const struct wined3d_format_desc * rt_format_desc ;
const struct wined3d_format_desc * ds_format_desc ;
2005-09-19 16:31:21 +02:00
int it ;
2005-07-13 16:15:54 +02:00
WARN_ ( d3d_caps ) ( " (%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s)) \n " ,
This , Adapter ,
2004-10-05 04:14:06 +02:00
DeviceType , debug_d3ddevicetype ( DeviceType ) ,
AdapterFormat , debug_d3dformat ( AdapterFormat ) ,
2005-07-13 16:15:54 +02:00
RenderTargetFormat , debug_d3dformat ( RenderTargetFormat ) ,
2004-10-05 04:14:06 +02:00
DepthStencilFormat , debug_d3dformat ( DepthStencilFormat ) ) ;
if ( Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
2006-04-07 12:51:12 +02:00
TRACE ( " (%p) Failed: Atapter (%u) higher than supported adapters (%u) returning WINED3DERR_INVALIDCALL \n " , This , Adapter , IWineD3D_GetAdapterCount ( iface ) ) ;
return WINED3DERR_INVALIDCALL ;
2004-10-05 04:14:06 +02:00
}
2005-09-19 16:31:21 +02:00
2009-03-13 10:44:18 +01:00
adapter = & This - > adapters [ Adapter ] ;
2009-03-24 10:09:23 +01:00
rt_format_desc = getFormatDescEntry ( RenderTargetFormat , & adapter - > gl_info ) ;
ds_format_desc = getFormatDescEntry ( DepthStencilFormat , & adapter - > gl_info ) ;
2010-03-21 19:05:38 +01:00
if ( wined3d_settings . offscreen_rendering_mode = = ORM_FBO )
{
if ( ( rt_format_desc - > Flags & WINED3DFMT_FLAG_RENDERTARGET ) & &
( ds_format_desc - > Flags & ( WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL ) ) ) {
TRACE_ ( d3d_caps ) ( " (%p) : Formats matched \n " , This ) ;
return WINED3D_OK ;
}
}
else
{
cfgs = adapter - > cfgs ;
nCfgs = adapter - > nCfgs ;
for ( it = 0 ; it < nCfgs ; + + it ) {
if ( IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt ( & adapter - > gl_info , & cfgs [ it ] , rt_format_desc ) )
2009-03-13 10:44:18 +01:00
{
2010-03-21 19:05:38 +01:00
if ( IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt ( & adapter - > gl_info , & cfgs [ it ] , ds_format_desc ) )
{
TRACE_ ( d3d_caps ) ( " (%p) : Formats matched \n " , This ) ;
return WINED3D_OK ;
}
2005-07-13 16:15:54 +02:00
}
}
2005-09-19 16:31:21 +02:00
}
2007-06-08 14:16:37 +02:00
WARN_ ( d3d_caps ) ( " unsupported format pair: %s and %s \n " , debug_d3dformat ( RenderTargetFormat ) , debug_d3dformat ( DepthStencilFormat ) ) ;
2005-07-13 16:15:54 +02:00
2007-06-08 14:16:37 +02:00
return WINED3DERR_NOTAVAILABLE ;
2004-10-05 04:14:06 +02:00
}
2009-08-27 10:04:56 +02:00
static HRESULT WINAPI IWineD3DImpl_CheckDeviceMultiSampleType ( IWineD3D * iface , UINT Adapter , WINED3DDEVTYPE DeviceType ,
WINED3DFORMAT SurfaceFormat , BOOL Windowed , WINED3DMULTISAMPLE_TYPE MultiSampleType , DWORD * pQualityLevels )
{
2004-10-05 04:14:06 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
2010-03-19 13:19:51 +01:00
const struct wined3d_format_desc * glDesc ;
2009-10-21 10:33:58 +02:00
const struct wined3d_adapter * adapter ;
2008-04-28 23:44:21 +02:00
TRACE_ ( d3d_caps ) ( " (%p)-> (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p) \n " ,
2005-07-13 16:15:54 +02:00
This ,
Adapter ,
2004-10-05 04:14:06 +02:00
DeviceType , debug_d3ddevicetype ( DeviceType ) ,
SurfaceFormat , debug_d3dformat ( SurfaceFormat ) ,
2005-07-13 16:15:54 +02:00
Windowed ,
2004-10-05 04:14:06 +02:00
MultiSampleType ,
pQualityLevels ) ;
2005-07-13 16:15:54 +02:00
2004-10-05 04:14:06 +02:00
if ( Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-10-05 04:14:06 +02:00
}
2008-04-28 23:44:21 +02:00
/* TODO: handle Windowed, add more quality levels */
2009-05-27 19:29:46 +02:00
if ( WINED3DMULTISAMPLE_NONE = = MultiSampleType ) {
if ( pQualityLevels ) * pQualityLevels = 1 ;
return WINED3D_OK ;
}
2008-04-28 23:44:21 +02:00
2008-06-02 23:06:01 +02:00
/* By default multisampling is disabled right now as it causes issues
* on some Nvidia driver versions and it doesn ' t work well in combination
* with FBOs yet . */
if ( ! wined3d_settings . allow_multisampling )
return WINED3DERR_NOTAVAILABLE ;
2009-03-13 10:44:18 +01:00
adapter = & This - > adapters [ Adapter ] ;
glDesc = getFormatDescEntry ( SurfaceFormat , & adapter - > gl_info ) ;
if ( ! glDesc ) return WINED3DERR_INVALIDCALL ;
2008-04-28 23:44:21 +02:00
if ( glDesc - > Flags & ( WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL ) ) {
int i , nCfgs ;
2008-11-28 15:30:11 +01:00
const WineD3D_PixelFormat * cfgs ;
2008-04-28 23:44:21 +02:00
2009-03-13 10:44:18 +01:00
cfgs = adapter - > cfgs ;
nCfgs = adapter - > nCfgs ;
2008-04-28 23:44:21 +02:00
for ( i = 0 ; i < nCfgs ; i + + ) {
if ( cfgs [ i ] . numSamples ! = MultiSampleType )
continue ;
2009-03-24 10:09:23 +01:00
if ( ! IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt ( & adapter - > gl_info , & cfgs [ i ] , glDesc ) )
2008-04-28 23:44:21 +02:00
continue ;
TRACE ( " Found iPixelFormat=%d to support MultiSampleType=%d for format %s \n " , cfgs [ i ] . iPixelFormat , MultiSampleType , debug_d3dformat ( SurfaceFormat ) ) ;
if ( pQualityLevels )
* pQualityLevels = 1 ; /* Guess at a value! */
return WINED3D_OK ;
2005-07-13 16:15:54 +02:00
}
2004-10-05 04:14:06 +02:00
}
2008-04-28 23:44:21 +02:00
else if ( glDesc - > Flags & WINED3DFMT_FLAG_RENDERTARGET ) {
short redSize , greenSize , blueSize , alphaSize , colorBits ;
int i , nCfgs ;
2008-11-28 15:30:11 +01:00
const WineD3D_PixelFormat * cfgs ;
2004-10-05 04:14:06 +02:00
2009-03-24 10:09:24 +01:00
if ( ! getColorBits ( glDesc , & redSize , & greenSize , & blueSize , & alphaSize , & colorBits ) )
2009-03-13 10:44:18 +01:00
{
2008-04-28 23:44:21 +02:00
ERR ( " Unable to color bits for format %#x, can't check multisampling capability! \n " , SurfaceFormat ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2009-03-13 10:44:18 +01:00
cfgs = adapter - > cfgs ;
nCfgs = adapter - > nCfgs ;
2008-04-28 23:44:21 +02:00
for ( i = 0 ; i < nCfgs ; i + + ) {
if ( cfgs [ i ] . numSamples ! = MultiSampleType )
continue ;
if ( cfgs [ i ] . redSize ! = redSize )
continue ;
if ( cfgs [ i ] . greenSize ! = greenSize )
continue ;
if ( cfgs [ i ] . blueSize ! = blueSize )
continue ;
2010-03-01 17:32:53 +01:00
/* Not all drivers report alpha-less formats since they use 32-bit anyway, so accept alpha even if we didn't ask for it. */
if ( alphaSize & & cfgs [ i ] . alphaSize ! = alphaSize )
continue ;
if ( cfgs [ i ] . colorSize ! = ( glDesc - > byte_count < < 3 ) )
2008-04-28 23:44:21 +02:00
continue ;
TRACE ( " Found iPixelFormat=%d to support MultiSampleType=%d for format %s \n " , cfgs [ i ] . iPixelFormat , MultiSampleType , debug_d3dformat ( SurfaceFormat ) ) ;
if ( pQualityLevels )
* pQualityLevels = 1 ; /* Guess at a value! */
return WINED3D_OK ;
}
}
2006-04-07 12:51:12 +02:00
return WINED3DERR_NOTAVAILABLE ;
2004-10-05 04:14:06 +02:00
}
2008-02-26 10:47:30 +01:00
static HRESULT WINAPI IWineD3DImpl_CheckDeviceType ( IWineD3D * iface , UINT Adapter , WINED3DDEVTYPE DeviceType ,
2009-12-21 23:17:26 +01:00
WINED3DFORMAT DisplayFormat , WINED3DFORMAT BackBufferFormat , BOOL Windowed )
{
2006-11-23 19:57:54 +01:00
HRESULT hr = WINED3DERR_NOTAVAILABLE ;
2008-02-26 10:47:30 +01:00
UINT nmodes ;
2006-11-23 19:57:54 +01:00
2009-12-21 23:17:26 +01:00
TRACE ( " iface %p, adapter_idx %u, device_type %s, display_format %s, backbuffer_format %s, windowed %#x. \n " ,
iface , Adapter , debug_d3ddevicetype ( DeviceType ) , debug_d3dformat ( DisplayFormat ) ,
debug_d3dformat ( BackBufferFormat ) , Windowed ) ;
2004-10-05 04:14:06 +02:00
if ( Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
2006-11-23 19:56:31 +01:00
WARN_ ( d3d_caps ) ( " Adapter >= IWineD3D_GetAdapterCount(iface), returning WINED3DERR_INVALIDCALL \n " ) ;
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-10-05 04:14:06 +02:00
}
2008-02-26 10:47:30 +01:00
/* The task of this function is to check whether a certain display / backbuffer format
* combination is available on the given adapter . In fullscreen mode microsoft specified
* that the display format shouldn ' t provide alpha and that ignoring alpha the backbuffer
* and display format should match exactly .
* In windowed mode format conversion can occur and this depends on the driver . When format
* conversion is done , this function should nevertheless fail and applications need to use
* CheckDeviceFormatConversion .
* At the moment we assume that fullscreen and windowed have the same capabilities */
/* There are only 4 display formats */
2009-09-25 13:31:49 +02:00
if ( ! ( DisplayFormat = = WINED3DFMT_B5G6R5_UNORM
| | DisplayFormat = = WINED3DFMT_B5G5R5X1_UNORM
| | DisplayFormat = = WINED3DFMT_B8G8R8X8_UNORM
| | DisplayFormat = = WINED3DFMT_B10G10R10A2_UNORM ) )
2008-02-26 10:47:30 +01:00
{
TRACE_ ( d3d_caps ) ( " Format %s unsupported as display format \n " , debug_d3dformat ( DisplayFormat ) ) ;
return WINED3DERR_NOTAVAILABLE ;
}
/* If the requested DisplayFormat is not available, don't continue */
nmodes = IWineD3DImpl_GetAdapterModeCount ( iface , Adapter , DisplayFormat ) ;
if ( ! nmodes ) {
TRACE_ ( d3d_caps ) ( " No available modes for display format %s \n " , debug_d3dformat ( DisplayFormat ) ) ;
return WINED3DERR_NOTAVAILABLE ;
2004-10-05 04:14:06 +02:00
}
2005-04-28 14:02:03 +02:00
2008-02-26 10:47:30 +01:00
/* Windowed mode allows you to specify WINED3DFMT_UNKNOWN for the backbufferformat, it means 'reuse' the display format for the backbuffer */
if ( ! Windowed & & BackBufferFormat = = WINED3DFMT_UNKNOWN ) {
TRACE_ ( d3d_caps ) ( " BackBufferFormat WINED3FMT_UNKNOWN not available in Windowed mode \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
/* In FULLSCREEN mode R5G6B5 can only be mixed with backbuffer format R5G6B5 */
2009-09-25 13:31:49 +02:00
if ( DisplayFormat = = WINED3DFMT_B5G6R5_UNORM & & BackBufferFormat ! = WINED3DFMT_B5G6R5_UNORM )
{
2008-02-26 10:47:30 +01:00
TRACE_ ( d3d_caps ) ( " Unsupported display/backbuffer format combination %s/%s \n " , debug_d3dformat ( DisplayFormat ) , debug_d3dformat ( BackBufferFormat ) ) ;
return WINED3DERR_NOTAVAILABLE ;
}
/* In FULLSCREEN mode X1R5G5B5 can only be mixed with backbuffer format *1R5G5B5 */
2009-09-25 13:31:49 +02:00
if ( DisplayFormat = = WINED3DFMT_B5G5R5X1_UNORM
& & ! ( BackBufferFormat = = WINED3DFMT_B5G5R5X1_UNORM | | BackBufferFormat = = WINED3DFMT_B5G5R5A1_UNORM ) )
{
2008-02-26 10:47:30 +01:00
TRACE_ ( d3d_caps ) ( " Unsupported display/backbuffer format combination %s/%s \n " , debug_d3dformat ( DisplayFormat ) , debug_d3dformat ( BackBufferFormat ) ) ;
return WINED3DERR_NOTAVAILABLE ;
}
/* In FULLSCREEN mode X8R8G8B8 can only be mixed with backbuffer format *8R8G8B8 */
2009-09-25 13:31:49 +02:00
if ( DisplayFormat = = WINED3DFMT_B8G8R8X8_UNORM
& & ! ( BackBufferFormat = = WINED3DFMT_B8G8R8X8_UNORM | | BackBufferFormat = = WINED3DFMT_B8G8R8A8_UNORM ) )
{
2008-02-26 10:47:30 +01:00
TRACE_ ( d3d_caps ) ( " Unsupported display/backbuffer format combination %s/%s \n " , debug_d3dformat ( DisplayFormat ) , debug_d3dformat ( BackBufferFormat ) ) ;
return WINED3DERR_NOTAVAILABLE ;
}
/* A2R10G10B10 is only allowed in fullscreen mode and it can only be mixed with backbuffer format A2R10G10B10 */
2009-09-25 13:31:49 +02:00
if ( DisplayFormat = = WINED3DFMT_B10G10R10A2_UNORM
& & ( BackBufferFormat ! = WINED3DFMT_B10G10R10A2_UNORM | | Windowed ) )
{
2008-02-26 10:47:30 +01:00
TRACE_ ( d3d_caps ) ( " Unsupported display/backbuffer format combination %s/%s \n " , debug_d3dformat ( DisplayFormat ) , debug_d3dformat ( BackBufferFormat ) ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2007-08-11 16:25:58 +02:00
2008-02-26 10:47:30 +01:00
/* Use CheckDeviceFormat to see if the BackBufferFormat is usable with the given DisplayFormat */
2008-08-27 17:42:40 +02:00
hr = IWineD3DImpl_CheckDeviceFormat ( iface , Adapter , DeviceType , DisplayFormat , WINED3DUSAGE_RENDERTARGET , WINED3DRTYPE_SURFACE , BackBufferFormat , SURFACE_OPENGL ) ;
2008-02-26 10:47:30 +01:00
if ( FAILED ( hr ) )
TRACE_ ( d3d_caps ) ( " Unsupported display/backbuffer format combination %s/%s \n " , debug_d3dformat ( DisplayFormat ) , debug_d3dformat ( BackBufferFormat ) ) ;
2006-11-23 19:57:54 +01:00
return hr ;
2004-10-05 04:14:06 +02:00
}
2008-03-16 17:02:02 +01:00
2008-03-17 18:29:29 +01:00
/* Check if we support bumpmapping for a format */
2010-05-05 18:22:38 +02:00
static BOOL CheckBumpMapCapability ( struct wined3d_adapter * adapter , const struct wined3d_format_desc * format_desc )
2008-03-17 18:29:29 +01:00
{
2010-04-29 00:09:00 +02:00
/* Ask the fixed function pipeline implementation if it can deal
* with the conversion . If we ' ve got a GL extension giving native
* support this will be an identity conversion . */
return ( format_desc - > Flags & WINED3DFMT_FLAG_BUMPMAP )
& & adapter - > fragment_pipe - > color_fixup_supported ( format_desc - > color_fixup ) ;
2008-03-17 18:29:29 +01:00
}
2008-03-16 17:02:02 +01:00
/* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
2009-10-21 10:33:58 +02:00
static BOOL CheckDepthStencilCapability ( struct wined3d_adapter * adapter ,
2010-03-19 13:19:51 +01:00
const struct wined3d_format_desc * display_format_desc , const struct wined3d_format_desc * ds_format_desc )
2008-03-16 17:02:02 +01:00
{
int it = 0 ;
2008-03-29 00:29:38 +01:00
/* Only allow depth/stencil formats */
2009-08-03 08:06:50 +02:00
if ( ! ( ds_format_desc - > depth_size | | ds_format_desc - > stencil_size ) ) return FALSE ;
2010-03-25 16:55:26 +01:00
if ( wined3d_settings . offscreen_rendering_mode = = ORM_FBO )
{
/* With FBOs WGL limitations do not apply, but the format needs to be FBO attachable */
if ( ds_format_desc - > Flags & ( WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL ) ) return TRUE ;
}
else
2009-03-11 10:15:09 +01:00
{
2010-03-25 16:55:26 +01:00
/* Walk through all WGL pixel formats to find a match */
for ( it = 0 ; it < adapter - > nCfgs ; + + it )
2009-03-13 10:44:18 +01:00
{
2010-03-25 16:55:26 +01:00
WineD3D_PixelFormat * cfg = & adapter - > cfgs [ it ] ;
if ( IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt ( & adapter - > gl_info , cfg , display_format_desc ) )
2009-03-13 10:44:18 +01:00
{
2010-03-25 16:55:26 +01:00
if ( IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt ( & adapter - > gl_info , cfg , ds_format_desc ) )
{
return TRUE ;
}
2008-03-16 17:02:02 +01:00
}
}
}
return FALSE ;
}
2010-03-19 13:19:51 +01:00
static BOOL CheckFilterCapability ( struct wined3d_adapter * adapter , const struct wined3d_format_desc * format_desc )
2008-03-17 19:27:24 +01:00
{
2008-03-29 00:18:41 +01:00
/* The flags entry of a format contains the filtering capability */
2009-03-24 10:09:23 +01:00
if ( format_desc - > Flags & WINED3DFMT_FLAG_FILTERING ) return TRUE ;
2008-03-29 00:18:41 +01:00
return FALSE ;
2008-03-17 19:27:24 +01:00
}
2008-03-16 17:37:38 +01:00
/* Check the render target capabilities of a format */
2009-10-21 10:33:58 +02:00
static BOOL CheckRenderTargetCapability ( struct wined3d_adapter * adapter ,
2010-03-19 13:19:51 +01:00
const struct wined3d_format_desc * adapter_format_desc , const struct wined3d_format_desc * check_format_desc )
2008-03-16 17:37:38 +01:00
{
/* Filter out non-RT formats */
2009-03-24 10:09:23 +01:00
if ( ! ( check_format_desc - > Flags & WINED3DFMT_FLAG_RENDERTARGET ) ) return FALSE ;
2008-03-16 17:37:38 +01:00
if ( wined3d_settings . offscreen_rendering_mode = = ORM_BACKBUFFER ) {
2009-03-11 10:15:09 +01:00
WineD3D_PixelFormat * cfgs = adapter - > cfgs ;
2008-03-16 17:37:38 +01:00
int it ;
short AdapterRed , AdapterGreen , AdapterBlue , AdapterAlpha , AdapterTotalSize ;
short CheckRed , CheckGreen , CheckBlue , CheckAlpha , CheckTotalSize ;
2009-03-24 10:09:24 +01:00
getColorBits ( adapter_format_desc , & AdapterRed , & AdapterGreen , & AdapterBlue , & AdapterAlpha , & AdapterTotalSize ) ;
getColorBits ( check_format_desc , & CheckRed , & CheckGreen , & CheckBlue , & CheckAlpha , & CheckTotalSize ) ;
2008-03-16 17:37:38 +01:00
/* In backbuffer mode the front and backbuffer share the same WGL pixelformat.
* The format must match in RGB , alpha is allowed to be different . ( Only the backbuffer can have alpha ) */
if ( ! ( ( AdapterRed = = CheckRed ) & & ( AdapterGreen = = CheckGreen ) & & ( AdapterBlue = = CheckBlue ) ) ) {
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return FALSE ;
}
/* Check if there is a WGL pixel format matching the requirements, the format should also be window
* drawable ( not offscreen ; e . g . Nvidia offers R5G6B5 for pbuffers even when X is running at 24 bit ) */
2009-03-11 10:15:09 +01:00
for ( it = 0 ; it < adapter - > nCfgs ; + + it )
{
2009-03-13 10:44:18 +01:00
if ( cfgs [ it ] . windowDrawable & & IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt ( & adapter - > gl_info ,
2009-03-24 10:09:23 +01:00
& cfgs [ it ] , check_format_desc ) )
2009-03-13 10:44:18 +01:00
{
2009-03-24 10:09:23 +01:00
TRACE_ ( d3d_caps ) ( " iPixelFormat=%d is compatible with CheckFormat=%s \n " ,
cfgs [ it ] . iPixelFormat , debug_d3dformat ( check_format_desc - > format ) ) ;
2008-03-16 17:37:38 +01:00
return TRUE ;
}
}
2010-03-14 21:53:23 +01:00
}
else if ( wined3d_settings . offscreen_rendering_mode = = ORM_FBO )
{
2008-03-16 17:37:38 +01:00
/* For now return TRUE for FBOs until we have some proper checks.
* Note that this function will only be called when the format is around for texturing . */
return TRUE ;
}
return FALSE ;
}
2010-03-19 13:19:51 +01:00
static BOOL CheckSrgbReadCapability ( struct wined3d_adapter * adapter , const struct wined3d_format_desc * format_desc )
2008-03-17 18:32:53 +01:00
{
2010-04-29 00:09:01 +02:00
return adapter - > gl_info . supported [ EXT_TEXTURE_SRGB ]
& & ( format_desc - > Flags & WINED3DFMT_FLAG_SRGB_READ ) ;
2008-03-17 18:32:53 +01:00
}
2010-05-05 18:22:38 +02:00
static BOOL CheckSrgbWriteCapability ( struct wined3d_adapter * adapter , const struct wined3d_format_desc * format_desc )
2008-03-21 23:45:52 +01:00
{
/* Only offer SRGB writing on X8R8G8B8/A8R8G8B8 when we use ARB or GLSL shaders as we are
* doing the color fixup in shaders .
* Note Windows drivers ( at least on the Geforce 8800 ) also offer this on R5G6B5 . */
2010-04-29 00:09:02 +02:00
if ( format_desc - > Flags & WINED3DFMT_FLAG_SRGB_WRITE )
2009-03-24 10:09:23 +01:00
{
2008-03-21 23:45:52 +01:00
int vs_selected_mode ;
int ps_selected_mode ;
2009-09-17 12:35:27 +02:00
select_shader_mode ( & adapter - > gl_info , & ps_selected_mode , & vs_selected_mode ) ;
2008-03-21 23:45:52 +01:00
if ( ( ps_selected_mode = = SHADER_ARB ) | | ( ps_selected_mode = = SHADER_GLSL ) ) {
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
return TRUE ;
}
}
2009-03-24 10:09:23 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] - no SRGB writing support on format=%s \n " , debug_d3dformat ( format_desc - > format ) ) ;
2008-03-21 23:45:52 +01:00
return FALSE ;
}
2008-03-22 22:41:30 +01:00
/* Check if a format support blending in combination with pixel shaders */
2009-10-21 10:33:58 +02:00
static BOOL CheckPostPixelShaderBlendingCapability ( struct wined3d_adapter * adapter ,
2010-03-19 13:19:51 +01:00
const struct wined3d_format_desc * format_desc )
2008-03-22 22:41:30 +01:00
{
/* The flags entry of a format contains the post pixel shader blending capability */
2009-03-24 10:09:23 +01:00
if ( format_desc - > Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING ) return TRUE ;
2008-03-22 22:41:30 +01:00
return FALSE ;
}
2010-03-19 13:19:51 +01:00
static BOOL CheckWrapAndMipCapability ( struct wined3d_adapter * adapter , const struct wined3d_format_desc * format_desc )
2009-03-24 10:09:23 +01:00
{
2008-04-05 23:35:21 +02:00
/* OpenGL supports mipmapping on all formats basically. Wrapping is unsupported,
* but we have to report mipmapping so we cannot reject this flag . Tests show that
* windows reports WRAPANDMIP on unfilterable surfaces as well , apparently to show
* that wrapping is supported . The lack of filtering will sort out the mipmapping
* capability anyway .
*
* For now lets report this on all formats , but in the future we may want to
* restrict it to some should games need that
*/
return TRUE ;
}
2008-03-16 17:20:27 +01:00
/* Check if a texture format is supported on the given adapter */
2010-05-05 18:22:38 +02:00
static BOOL CheckTextureCapability ( struct wined3d_adapter * adapter , const struct wined3d_format_desc * format_desc )
2008-03-16 17:20:27 +01:00
{
2009-07-17 10:34:01 +02:00
const struct wined3d_gl_info * gl_info = & adapter - > gl_info ;
2008-03-16 17:20:27 +01:00
2009-03-24 10:09:23 +01:00
switch ( format_desc - > format )
{
2008-03-16 17:20:27 +01:00
/*****
* supported : RGB ( A ) formats
*/
2009-09-25 13:31:49 +02:00
case WINED3DFMT_B8G8R8_UNORM : /* Enable for dx7, blacklisted for 8 and 9 above */
case WINED3DFMT_B8G8R8A8_UNORM :
case WINED3DFMT_B8G8R8X8_UNORM :
case WINED3DFMT_B5G6R5_UNORM :
case WINED3DFMT_B5G5R5X1_UNORM :
case WINED3DFMT_B5G5R5A1_UNORM :
case WINED3DFMT_B4G4R4A4_UNORM :
2009-02-19 16:59:42 +01:00
case WINED3DFMT_A8_UNORM :
2009-09-25 13:31:49 +02:00
case WINED3DFMT_B4G4R4X4_UNORM :
2009-02-19 16:59:42 +01:00
case WINED3DFMT_R8G8B8A8_UNORM :
2009-09-25 13:31:49 +02:00
case WINED3DFMT_R8G8B8X8_UNORM :
case WINED3DFMT_B10G10R10A2_UNORM :
2009-02-19 16:59:42 +01:00
case WINED3DFMT_R10G10B10A2_UNORM :
case WINED3DFMT_R16G16_UNORM :
2008-03-16 17:20:27 +01:00
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
return TRUE ;
2009-09-25 13:31:49 +02:00
case WINED3DFMT_B2G3R3_UNORM :
2008-08-19 13:57:13 +02:00
TRACE_ ( d3d_caps ) ( " [FAILED] - Not supported on Windows \n " ) ;
return FALSE ;
2008-03-16 17:20:27 +01:00
/*****
2010-04-05 20:05:15 +02:00
* Not supported : Palettized
* Only some Geforce / Voodoo3 / G400 cards offer 8 - bit textures in case of < = Direct3D7 .
* Since it is not widely available , don ' t offer it . Further no Windows driver offers
* WINED3DFMT_P8_UINT_A8_NORM , so don ' t offer it either .
2008-03-16 17:20:27 +01:00
*/
2009-09-25 13:31:49 +02:00
case WINED3DFMT_P8_UINT :
case WINED3DFMT_P8_UINT_A8_UNORM :
2008-03-16 17:20:27 +01:00
return FALSE ;
/*****
* Supported : ( Alpha ) - Luminance
*/
2009-09-25 13:31:49 +02:00
case WINED3DFMT_L8_UNORM :
case WINED3DFMT_L8A8_UNORM :
case WINED3DFMT_L16_UNORM :
2008-03-16 17:20:27 +01:00
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
return TRUE ;
2008-08-15 13:49:20 +02:00
/* Not supported on Windows, thus disabled */
2009-09-25 13:31:49 +02:00
case WINED3DFMT_L4A4_UNORM :
2008-08-15 13:49:20 +02:00
TRACE_ ( d3d_caps ) ( " [FAILED] - not supported on windows \n " ) ;
return FALSE ;
2008-06-19 18:24:23 +02:00
/*****
* Supported : Depth / Stencil formats
*/
2008-03-16 17:20:27 +01:00
case WINED3DFMT_D16_LOCKABLE :
2009-02-19 16:59:42 +01:00
case WINED3DFMT_D16_UNORM :
2009-09-25 13:31:49 +02:00
case WINED3DFMT_S1_UINT_D15_UNORM :
case WINED3DFMT_X8D24_UNORM :
case WINED3DFMT_S4X4_UINT_D24_UNORM :
2009-10-29 18:56:21 +01:00
case WINED3DFMT_D24_UNORM_S8_UINT :
2009-09-25 13:31:49 +02:00
case WINED3DFMT_S8_UINT_D24_FLOAT :
case WINED3DFMT_D32_UNORM :
case WINED3DFMT_D32_FLOAT :
2008-06-19 18:24:23 +02:00
return TRUE ;
2008-03-16 17:20:27 +01:00
/*****
* Not supported everywhere ( depends on GL_ATI_envmap_bumpmap or
2008-08-07 21:51:35 +02:00
* GL_NV_texture_shader ) . Emulated by shaders
2008-03-16 17:20:27 +01:00
*/
2009-02-19 16:59:42 +01:00
case WINED3DFMT_R8G8_SNORM :
2009-09-25 13:31:49 +02:00
case WINED3DFMT_R8G8_SNORM_L8X8_UNORM :
case WINED3DFMT_R5G5_SNORM_L6_UNORM :
2009-02-19 16:59:42 +01:00
case WINED3DFMT_R8G8B8A8_SNORM :
case WINED3DFMT_R16G16_SNORM :
2008-12-03 14:53:43 +01:00
/* Ask the shader backend if it can deal with the conversion. If
* we ' ve got a GL extension giving native support this will be an
* identity conversion . */
2010-02-02 12:06:57 +01:00
if ( adapter - > shader_backend - > shader_color_fixup_supported ( format_desc - > color_fixup ) )
2008-12-03 14:53:43 +01:00
{
2008-08-07 21:51:35 +02:00
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
2008-04-03 17:15:47 +02:00
return TRUE ;
}
2008-12-03 14:53:43 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return FALSE ;
2008-03-16 17:20:27 +01:00
case WINED3DFMT_DXT1 :
case WINED3DFMT_DXT2 :
case WINED3DFMT_DXT3 :
case WINED3DFMT_DXT4 :
case WINED3DFMT_DXT5 :
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ EXT_TEXTURE_COMPRESSION_S3TC ] )
{
2008-03-16 17:20:27 +01:00
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
return TRUE ;
}
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return FALSE ;
/*****
* Odd formats - not supported
*/
case WINED3DFMT_VERTEXDATA :
2009-02-19 16:59:42 +01:00
case WINED3DFMT_R16_UINT :
case WINED3DFMT_R32_UINT :
case WINED3DFMT_R16G16B16A16_SNORM :
2009-09-25 13:31:49 +02:00
case WINED3DFMT_R10G10B10_SNORM_A2_UNORM :
case WINED3DFMT_R10G11B11_SNORM :
2008-03-16 17:20:27 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ; /* Enable when implemented */
return FALSE ;
/*****
2009-09-25 13:31:49 +02:00
* WINED3DFMT_R8G8_SNORM_Cx : Not supported right now
2008-03-16 17:20:27 +01:00
*/
2009-09-25 13:31:49 +02:00
case WINED3DFMT_R8G8_SNORM_Cx :
2008-03-16 17:20:27 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ; /* Enable when implemented */
return FALSE ;
2008-08-19 17:55:42 +02:00
/* YUV formats */
2008-03-16 17:20:27 +01:00
case WINED3DFMT_UYVY :
case WINED3DFMT_YUY2 :
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ APPLE_YCBCR_422 ] )
{
2008-08-19 17:55:42 +02:00
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
return TRUE ;
}
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
2008-03-16 17:20:27 +01:00
return FALSE ;
2008-08-25 16:25:24 +02:00
case WINED3DFMT_YV12 :
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return FALSE ;
2008-03-16 17:20:27 +01:00
/* Not supported */
2009-08-19 10:55:39 +02:00
case WINED3DFMT_R16G16B16A16_UNORM :
2009-09-25 13:31:49 +02:00
case WINED3DFMT_B2G3R3A8_UNORM :
2008-03-16 17:20:27 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ; /* Enable when implemented */
return FALSE ;
/* Floating point formats */
2009-02-19 16:59:42 +01:00
case WINED3DFMT_R16_FLOAT :
2009-04-06 15:05:27 +02:00
case WINED3DFMT_R16G16_FLOAT :
2009-02-19 16:59:42 +01:00
case WINED3DFMT_R16G16B16A16_FLOAT :
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ ARB_TEXTURE_FLOAT ] & & gl_info - > supported [ ARB_HALF_FLOAT_PIXEL ] )
{
2008-03-16 17:20:27 +01:00
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
return TRUE ;
}
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return FALSE ;
2009-02-19 16:59:42 +01:00
case WINED3DFMT_R32_FLOAT :
2009-04-06 15:05:27 +02:00
case WINED3DFMT_R32G32_FLOAT :
2009-02-19 16:59:42 +01:00
case WINED3DFMT_R32G32B32A32_FLOAT :
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ ARB_TEXTURE_FLOAT ] )
{
2008-03-16 17:20:27 +01:00
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
return TRUE ;
}
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return FALSE ;
/* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
* instancing . To query if the card supports instancing CheckDeviceFormat with the special format
* MAKEFOURCC ( ' I ' , ' N ' , ' S ' , ' T ' ) is used . Should a ( broken ) app check for this provide a proper return value .
* We can do instancing with all shader versions , but we need vertex shaders .
*
2008-03-21 22:41:59 +01:00
* Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC ( ' I ' , ' N ' , ' S ' , ' T ' ) once
2008-03-16 17:20:27 +01:00
* to enable instancing . WineD3D doesn ' t need that and just ignores it .
*
* With Shader Model 3.0 capable cards Instancing ' just works ' in Windows .
*/
2010-01-03 17:23:43 +01:00
case WINED3DFMT_INST :
2008-03-16 17:20:27 +01:00
TRACE ( " ATI Instancing check hack \n " ) ;
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ ARB_VERTEX_PROGRAM ] | | gl_info - > supported [ ARB_VERTEX_SHADER ] )
{
2008-03-16 17:20:27 +01:00
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
return TRUE ;
}
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return FALSE ;
/* Some weird FOURCC formats */
case WINED3DFMT_R8G8_B8G8 :
case WINED3DFMT_G8R8_G8B8 :
case WINED3DFMT_MULTI2_ARGB8 :
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return FALSE ;
2008-07-23 17:33:10 +02:00
/* Vendor specific formats */
case WINED3DFMT_ATI2N :
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ ATI_TEXTURE_COMPRESSION_3DC ]
| | gl_info - > supported [ EXT_TEXTURE_COMPRESSION_RGTC ] )
{
2010-02-02 12:06:57 +01:00
if ( adapter - > shader_backend - > shader_color_fixup_supported ( format_desc - > color_fixup )
2010-02-02 12:06:56 +01:00
& & adapter - > fragment_pipe - > color_fixup_supported ( format_desc - > color_fixup ) )
2008-12-03 14:53:43 +01:00
{
2008-08-07 21:51:35 +02:00
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
return TRUE ;
}
2008-07-23 17:33:10 +02:00
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
return TRUE ;
}
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return FALSE ;
2008-08-25 16:25:24 +02:00
case WINED3DFMT_NVHU :
case WINED3DFMT_NVHS :
/* These formats seem to be similar to the HILO formats in GL_NV_texture_shader. NVHU
* is said to be GL_UNSIGNED_HILO16 , NVHS GL_SIGNED_HILO16 . Rumours say that d3d computes
* a 3 rd channel similarly to D3DFMT_CxV8U8 ( So NVHS could be called D3DFMT_CxV16U16 ) .
* ATI refused to support formats which can easilly be emulated with pixel shaders , so
* Applications have to deal with not having NVHS and NVHU .
*/
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return FALSE ;
2008-03-16 17:20:27 +01:00
case WINED3DFMT_UNKNOWN :
return FALSE ;
default :
2009-03-24 10:09:23 +01:00
ERR ( " Unhandled format=%s \n " , debug_d3dformat ( format_desc - > format ) ) ;
2008-03-16 17:20:27 +01:00
break ;
}
return FALSE ;
}
2010-03-19 13:19:51 +01:00
static BOOL CheckSurfaceCapability ( struct wined3d_adapter * adapter ,
const struct wined3d_format_desc * adapter_format_desc ,
2010-05-05 18:22:38 +02:00
const struct wined3d_format_desc * check_format_desc ,
2010-03-19 13:19:51 +01:00
WINED3DSURFTYPE SurfaceType )
2009-03-11 10:15:09 +01:00
{
2008-08-27 17:42:40 +02:00
if ( SurfaceType = = SURFACE_GDI ) {
2009-03-24 10:09:23 +01:00
switch ( check_format_desc - > format )
{
2009-09-25 13:31:49 +02:00
case WINED3DFMT_B8G8R8_UNORM :
case WINED3DFMT_B8G8R8A8_UNORM :
case WINED3DFMT_B8G8R8X8_UNORM :
case WINED3DFMT_B5G6R5_UNORM :
case WINED3DFMT_B5G5R5X1_UNORM :
case WINED3DFMT_B5G5R5A1_UNORM :
case WINED3DFMT_B4G4R4A4_UNORM :
case WINED3DFMT_B2G3R3_UNORM :
2009-02-19 16:59:42 +01:00
case WINED3DFMT_A8_UNORM :
2009-09-25 13:31:49 +02:00
case WINED3DFMT_B2G3R3A8_UNORM :
case WINED3DFMT_B4G4R4X4_UNORM :
2009-02-19 16:59:42 +01:00
case WINED3DFMT_R10G10B10A2_UNORM :
case WINED3DFMT_R8G8B8A8_UNORM :
2009-09-25 13:31:49 +02:00
case WINED3DFMT_R8G8B8X8_UNORM :
2009-02-19 16:59:42 +01:00
case WINED3DFMT_R16G16_UNORM :
2009-09-25 13:31:49 +02:00
case WINED3DFMT_B10G10R10A2_UNORM :
2009-02-19 16:59:42 +01:00
case WINED3DFMT_R16G16B16A16_UNORM :
2009-09-25 13:31:49 +02:00
case WINED3DFMT_P8_UINT :
2008-08-27 17:42:40 +02:00
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
return TRUE ;
default :
TRACE_ ( d3d_caps ) ( " [FAILED] - not available on GDI surfaces \n " ) ;
return FALSE ;
}
}
2008-08-07 21:36:55 +02:00
/* All format that are supported for textures are supported for surfaces as well */
2010-05-05 18:22:38 +02:00
if ( CheckTextureCapability ( adapter , check_format_desc ) ) return TRUE ;
2008-08-07 21:36:55 +02:00
/* All depth stencil formats are supported on surfaces */
2009-03-24 10:09:23 +01:00
if ( CheckDepthStencilCapability ( adapter , adapter_format_desc , check_format_desc ) ) return TRUE ;
2008-08-07 21:36:55 +02:00
2008-08-07 21:51:35 +02:00
/* If opengl can't process the format natively, the blitter may be able to convert it */
2010-04-06 22:20:42 +02:00
if ( adapter - > blitter - > blit_supported ( & adapter - > gl_info , BLIT_OP_BLIT ,
NULL , WINED3DPOOL_DEFAULT , 0 , check_format_desc ,
NULL , WINED3DPOOL_DEFAULT , 0 , adapter_format_desc ) )
2008-12-03 14:53:43 +01:00
{
2008-08-07 21:51:35 +02:00
TRACE_ ( d3d_caps ) ( " [OK] \n " ) ;
return TRUE ;
}
2008-08-07 21:36:55 +02:00
/* Reject other formats */
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return FALSE ;
}
2010-03-19 13:19:51 +01:00
static BOOL CheckVertexTextureCapability ( struct wined3d_adapter * adapter ,
const struct wined3d_format_desc * format_desc )
2008-03-17 18:37:15 +01:00
{
2010-04-29 00:09:03 +02:00
return adapter - > gl_info . limits . vertex_samplers
& & ( format_desc - > Flags & WINED3DFMT_FLAG_VTF ) ;
2008-03-17 18:37:15 +01:00
}
2009-08-27 10:04:56 +02:00
static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat ( IWineD3D * iface , UINT Adapter , WINED3DDEVTYPE DeviceType ,
2008-08-27 17:42:40 +02:00
WINED3DFORMAT AdapterFormat , DWORD Usage , WINED3DRESOURCETYPE RType , WINED3DFORMAT CheckFormat ,
2009-08-27 10:04:56 +02:00
WINED3DSURFTYPE SurfaceType )
{
2004-10-05 04:14:06 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
2009-10-21 10:33:58 +02:00
struct wined3d_adapter * adapter = & This - > adapters [ Adapter ] ;
2009-07-17 10:34:01 +02:00
const struct wined3d_gl_info * gl_info = & adapter - > gl_info ;
2010-03-19 13:19:51 +01:00
const struct wined3d_format_desc * format_desc = getFormatDescEntry ( CheckFormat , gl_info ) ;
const struct wined3d_format_desc * adapter_format_desc = getFormatDescEntry ( AdapterFormat , gl_info ) ;
2008-03-16 17:02:02 +01:00
DWORD UsageCaps = 0 ;
2006-10-05 11:11:03 +02:00
TRACE_ ( d3d_caps ) ( " (%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s)) \n " ,
2005-07-13 16:15:54 +02:00
This ,
Adapter ,
DeviceType , debug_d3ddevicetype ( DeviceType ) ,
AdapterFormat , debug_d3dformat ( AdapterFormat ) ,
2006-07-28 21:33:20 +02:00
Usage , debug_d3dusage ( Usage ) , debug_d3dusagequery ( Usage ) ,
2005-07-13 16:15:54 +02:00
RType , debug_d3dresourcetype ( RType ) ,
2004-10-05 04:14:06 +02:00
CheckFormat , debug_d3dformat ( CheckFormat ) ) ;
if ( Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-10-05 04:14:06 +02:00
}
2010-05-05 18:22:37 +02:00
switch ( RType )
{
case WINED3DRTYPE_CUBETEXTURE :
/* Cubetexture allows:
* - WINED3DUSAGE_AUTOGENMIPMAP
* - WINED3DUSAGE_DEPTHSTENCIL
* - WINED3DUSAGE_DYNAMIC
* - WINED3DUSAGE_NONSECURE ( d3d9ex )
* - WINED3DUSAGE_RENDERTARGET
* - WINED3DUSAGE_SOFTWAREPROCESSING
* - WINED3DUSAGE_QUERY_WRAPANDMIP
*/
if ( SurfaceType ! = SURFACE_OPENGL )
{
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2008-08-27 17:42:40 +02:00
2010-05-05 18:22:37 +02:00
if ( ! gl_info - > supported [ ARB_TEXTURE_CUBE_MAP ] )
{
TRACE_ ( d3d_caps ) ( " [FAILED] - No cube texture support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2008-08-27 17:42:40 +02:00
2010-05-05 18:22:38 +02:00
if ( ! CheckTextureCapability ( adapter , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2010-05-05 18:22:37 +02:00
TRACE_ ( d3d_caps ) ( " [FAILED] - Cube texture format not supported \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2008-03-17 20:11:32 +01:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_AUTOGENMIPMAP )
{
if ( ! gl_info - > supported [ SGIS_GENERATE_MIPMAP ] )
/* When autogenmipmap isn't around continue and return
* WINED3DOK_NOAUTOGEN instead of D3D_OK . */
TRACE_ ( d3d_caps ) ( " [FAILED] - No autogenmipmap support, but continuing \n " ) ;
else
UsageCaps | = WINED3DUSAGE_AUTOGENMIPMAP ;
}
2008-03-18 09:43:27 +01:00
2010-05-05 18:22:37 +02:00
/* Always report dynamic locking. */
if ( Usage & WINED3DUSAGE_DYNAMIC )
UsageCaps | = WINED3DUSAGE_DYNAMIC ;
if ( Usage & WINED3DUSAGE_RENDERTARGET )
{
if ( ! CheckRenderTargetCapability ( adapter , adapter_format_desc , format_desc ) )
{
TRACE_ ( d3d_caps ) ( " [FAILED] - No rendertarget support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
2008-03-16 17:37:38 +01:00
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_RENDERTARGET ;
}
2008-03-17 18:32:53 +01:00
2010-05-05 18:22:37 +02:00
/* Always report software processing. */
if ( Usage & WINED3DUSAGE_SOFTWAREPROCESSING )
UsageCaps | = WINED3DUSAGE_SOFTWAREPROCESSING ;
2008-03-18 09:45:35 +01:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_FILTER )
{
if ( ! CheckFilterCapability ( adapter , format_desc ) )
{
TRACE_ ( d3d_caps ) ( " [FAILED] - No query filter support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
2008-03-17 19:27:24 +01:00
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_FILTER ;
}
2008-03-17 19:27:24 +01:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING )
{
if ( ! CheckPostPixelShaderBlendingCapability ( adapter , format_desc ) )
{
TRACE_ ( d3d_caps ) ( " [FAILED] - No query post pixelshader blending support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
2008-03-22 22:41:30 +01:00
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING ;
}
2008-03-22 22:41:30 +01:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_SRGBREAD )
{
if ( ! CheckSrgbReadCapability ( adapter , format_desc ) )
{
TRACE_ ( d3d_caps ) ( " [FAILED] - No query srgbread support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
2008-03-17 18:32:53 +01:00
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_SRGBREAD ;
}
2008-03-17 18:37:15 +01:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_SRGBWRITE )
{
2010-05-05 18:22:38 +02:00
if ( ! CheckSrgbWriteCapability ( adapter , format_desc ) )
2010-05-05 18:22:37 +02:00
{
TRACE_ ( d3d_caps ) ( " [FAILED] - No query srgbwrite support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
2008-03-21 23:45:52 +01:00
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_SRGBWRITE ;
}
2008-03-21 23:45:52 +01:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE )
{
if ( ! CheckVertexTextureCapability ( adapter , format_desc ) )
{
TRACE_ ( d3d_caps ) ( " [FAILED] - No query vertextexture support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
2008-03-17 18:37:15 +01:00
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_VERTEXTEXTURE ;
}
2008-04-05 23:35:21 +02:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_WRAPANDMIP )
{
if ( ! CheckWrapAndMipCapability ( adapter , format_desc ) )
{
TRACE_ ( d3d_caps ) ( " [FAILED] - No wrapping and mipmapping support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
2008-04-05 23:35:21 +02:00
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_WRAPANDMIP ;
}
break ;
case WINED3DRTYPE_SURFACE :
/* Surface allows:
* - WINED3DUSAGE_DEPTHSTENCIL
* - WINED3DUSAGE_NONSECURE ( d3d9ex )
* - WINED3DUSAGE_RENDERTARGET
*/
2010-05-05 18:22:38 +02:00
if ( ! CheckSurfaceCapability ( adapter , adapter_format_desc , format_desc , SurfaceType ) )
2010-05-05 18:22:37 +02:00
{
TRACE_ ( d3d_caps ) ( " [FAILED] - Not supported for plain surfaces \n " ) ;
2008-03-21 22:11:12 +01:00
return WINED3DERR_NOTAVAILABLE ;
2008-03-16 17:20:27 +01:00
}
2008-03-16 17:02:02 +01:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_DEPTHSTENCIL )
{
if ( ! CheckDepthStencilCapability ( adapter , adapter_format_desc , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-08-07 21:36:55 +02:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No depthstencil support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_DEPTHSTENCIL ;
2008-03-16 17:02:02 +01:00
}
2008-03-16 17:37:38 +01:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_RENDERTARGET )
{
if ( ! CheckRenderTargetCapability ( adapter , adapter_format_desc , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-08-07 21:36:55 +02:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No rendertarget support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_RENDERTARGET ;
2008-03-16 17:37:38 +01:00
}
2008-04-03 16:14:57 +02:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING )
{
if ( ! CheckPostPixelShaderBlendingCapability ( adapter , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-08-07 21:36:55 +02:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No query post pixelshader blending support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING ;
2008-04-03 16:14:57 +02:00
}
2010-05-05 18:22:37 +02:00
break ;
2008-08-07 21:36:55 +02:00
2010-05-05 18:22:37 +02:00
case WINED3DRTYPE_TEXTURE :
/* Texture allows:
* - WINED3DUSAGE_AUTOGENMIPMAP
* - WINED3DUSAGE_DEPTHSTENCIL
* - WINED3DUSAGE_DMAP
* - WINED3DUSAGE_DYNAMIC
* - WINED3DUSAGE_NONSECURE ( d3d9ex )
* - WINED3DUSAGE_RENDERTARGET
* - WINED3DUSAGE_SOFTWAREPROCESSING
* - WINED3DUSAGE_TEXTAPI ( d3d9ex )
* - WINED3DUSAGE_QUERY_WRAPANDMIP
*/
if ( SurfaceType ! = SURFACE_OPENGL )
{
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2008-03-16 17:02:02 +01:00
2010-05-05 18:22:38 +02:00
if ( ! CheckTextureCapability ( adapter , format_desc ) )
2010-05-05 18:22:37 +02:00
{
TRACE_ ( d3d_caps ) ( " [FAILED] - Texture format not supported \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2008-08-27 17:42:40 +02:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_AUTOGENMIPMAP )
{
if ( ! gl_info - > supported [ SGIS_GENERATE_MIPMAP ] )
/* When autogenmipmap isn't around continue and return
* WINED3DOK_NOAUTOGEN instead of D3D_OK . */
2008-03-17 20:11:32 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No autogenmipmap support, but continuing \n " ) ;
2010-05-05 18:22:37 +02:00
else
UsageCaps | = WINED3DUSAGE_AUTOGENMIPMAP ;
2008-03-17 20:11:32 +01:00
}
2010-05-05 18:22:37 +02:00
/* Always report dynamic locking. */
if ( Usage & WINED3DUSAGE_DYNAMIC )
2008-03-18 09:43:27 +01:00
UsageCaps | = WINED3DUSAGE_DYNAMIC ;
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_RENDERTARGET )
{
if ( ! CheckRenderTargetCapability ( adapter , adapter_format_desc , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-03-16 17:37:38 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No rendertarget support \n " ) ;
2010-05-05 18:22:37 +02:00
return WINED3DERR_NOTAVAILABLE ;
}
UsageCaps | = WINED3DUSAGE_RENDERTARGET ;
2008-03-16 17:37:38 +01:00
}
2008-03-17 18:29:29 +01:00
2010-05-05 18:22:37 +02:00
/* Always report software processing. */
if ( Usage & WINED3DUSAGE_SOFTWAREPROCESSING )
2008-03-18 09:45:35 +01:00
UsageCaps | = WINED3DUSAGE_SOFTWAREPROCESSING ;
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_FILTER )
{
if ( ! CheckFilterCapability ( adapter , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-03-17 19:27:24 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No query filter support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_FILTER ;
2008-03-17 19:27:24 +01:00
}
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP )
{
2010-05-05 18:22:38 +02:00
if ( ! CheckBumpMapCapability ( adapter , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-03-17 18:29:29 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No legacy bumpmap support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_LEGACYBUMPMAP ;
2008-03-17 18:29:29 +01:00
}
2008-03-17 18:32:53 +01:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING )
{
if ( ! CheckPostPixelShaderBlendingCapability ( adapter , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-03-22 22:41:30 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No query post pixelshader blending support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING ;
2008-03-22 22:41:30 +01:00
}
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_SRGBREAD )
{
if ( ! CheckSrgbReadCapability ( adapter , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-03-17 18:32:53 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No query srgbread support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_SRGBREAD ;
2008-03-17 18:32:53 +01:00
}
2008-03-17 18:37:15 +01:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_SRGBWRITE )
{
2010-05-05 18:22:38 +02:00
if ( ! CheckSrgbWriteCapability ( adapter , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-03-21 23:45:52 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No query srgbwrite support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_SRGBWRITE ;
2008-03-21 23:45:52 +01:00
}
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE )
{
if ( ! CheckVertexTextureCapability ( adapter , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-03-17 18:37:15 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No query vertextexture support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_VERTEXTEXTURE ;
2008-03-17 18:37:15 +01:00
}
2008-04-05 23:35:21 +02:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_WRAPANDMIP )
{
if ( ! CheckWrapAndMipCapability ( adapter , format_desc ) )
2009-03-24 10:09:23 +01:00
{
2008-04-05 23:35:21 +02:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No wrapping and mipmapping support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_WRAPANDMIP ;
2008-04-05 23:35:21 +02:00
}
2008-06-19 18:24:23 +02:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_DEPTHSTENCIL )
{
if ( ! CheckDepthStencilCapability ( adapter , adapter_format_desc , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-06-19 18:24:23 +02:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No depth stencil support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_DEPTHSTENCIL ;
2008-06-19 18:24:23 +02:00
}
2010-05-05 18:22:37 +02:00
break ;
2008-03-18 09:43:27 +01:00
2010-05-05 18:22:37 +02:00
case WINED3DRTYPE_VOLUMETEXTURE :
case WINED3DRTYPE_VOLUME :
/* Volume is to VolumeTexture what Surface is to Texture, but its
* usage caps are not documented . Most driver seem to offer
* ( nearly ) the same on Volume and VolumeTexture , so do that too .
*
* Volumetexture allows :
* - D3DUSAGE_DYNAMIC
* - D3DUSAGE_NONSECURE ( d3d9ex )
* - D3DUSAGE_SOFTWAREPROCESSING
* - D3DUSAGE_QUERY_WRAPANDMIP
*/
if ( SurfaceType ! = SURFACE_OPENGL )
{
TRACE_ ( d3d_caps ) ( " [FAILED] \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
if ( ! gl_info - > supported [ EXT_TEXTURE3D ] )
{
TRACE_ ( d3d_caps ) ( " [FAILED] - No volume texture support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2008-08-27 17:42:40 +02:00
2010-05-05 18:22:38 +02:00
if ( ! CheckTextureCapability ( adapter , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-03-16 17:20:27 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] - Format not supported \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2008-03-17 18:32:53 +01:00
2010-05-05 18:22:37 +02:00
/* Filter formats that need conversion; For one part, this
* conversion is unimplemented , and volume textures are huge , so
* it would be a big performance hit . Unless we hit an application
* needing one of those formats , don ' t advertize them to avoid
* leading applications into temptation . The windows drivers don ' t
* support most of those formats on volumes anyway , except for
* WINED3DFMT_R32_FLOAT . */
switch ( CheckFormat )
{
case WINED3DFMT_P8_UINT :
case WINED3DFMT_L4A4_UNORM :
case WINED3DFMT_R32_FLOAT :
case WINED3DFMT_R16_FLOAT :
case WINED3DFMT_R8G8_SNORM_L8X8_UNORM :
case WINED3DFMT_R5G5_SNORM_L6_UNORM :
case WINED3DFMT_R16G16_UNORM :
TRACE_ ( d3d_caps ) ( " [FAILED] - No converted formats on volumes \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
case WINED3DFMT_R8G8B8A8_SNORM :
case WINED3DFMT_R16G16_SNORM :
if ( ! gl_info - > supported [ NV_TEXTURE_SHADER ] )
{
TRACE_ ( d3d_caps ) ( " [FAILED] - No converted formats on volumes \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
break ;
case WINED3DFMT_R8G8_SNORM :
if ( ! gl_info - > supported [ NV_TEXTURE_SHADER ] )
{
TRACE_ ( d3d_caps ) ( " [FAILED] - No converted formats on volumes \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
break ;
case WINED3DFMT_DXT1 :
case WINED3DFMT_DXT2 :
case WINED3DFMT_DXT3 :
case WINED3DFMT_DXT4 :
case WINED3DFMT_DXT5 :
/* The GL_EXT_texture_compression_s3tc spec requires that
* loading an s3tc compressed texture results in an error .
* While the D3D refrast does support s3tc volumes , at
* least the nvidia windows driver does not , so we ' re free
* not to support this format . */
TRACE_ ( d3d_caps ) ( " [FAILED] - DXTn does not support 3D textures \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
default :
/* Do nothing, continue with checking the format below */
break ;
}
/* Always report dynamic locking. */
if ( Usage & WINED3DUSAGE_DYNAMIC )
2008-03-18 09:43:27 +01:00
UsageCaps | = WINED3DUSAGE_DYNAMIC ;
2010-05-05 18:22:37 +02:00
/* Always report software processing. */
if ( Usage & WINED3DUSAGE_SOFTWAREPROCESSING )
2008-03-18 09:45:35 +01:00
UsageCaps | = WINED3DUSAGE_SOFTWAREPROCESSING ;
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_FILTER )
{
if ( ! CheckFilterCapability ( adapter , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-03-17 19:27:24 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No query filter support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_FILTER ;
2008-03-17 19:27:24 +01:00
}
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING )
{
if ( ! CheckPostPixelShaderBlendingCapability ( adapter , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-03-22 22:41:30 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No query post pixelshader blending support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING ;
2008-03-22 22:41:30 +01:00
}
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_SRGBREAD )
{
if ( ! CheckSrgbReadCapability ( adapter , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-03-17 18:32:53 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No query srgbread support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_SRGBREAD ;
2008-03-17 18:32:53 +01:00
}
2008-03-17 18:37:15 +01:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_SRGBWRITE )
{
2010-05-05 18:22:38 +02:00
if ( ! CheckSrgbWriteCapability ( adapter , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-03-21 23:45:52 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No query srgbwrite support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_SRGBWRITE ;
2008-03-21 23:45:52 +01:00
}
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE )
{
if ( ! CheckVertexTextureCapability ( adapter , format_desc ) )
2009-03-11 10:15:09 +01:00
{
2008-03-17 18:37:15 +01:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No query vertextexture support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_VERTEXTEXTURE ;
2008-03-17 18:37:15 +01:00
}
2008-04-05 23:35:21 +02:00
2010-05-05 18:22:37 +02:00
if ( Usage & WINED3DUSAGE_QUERY_WRAPANDMIP )
{
if ( ! CheckWrapAndMipCapability ( adapter , format_desc ) )
2009-03-24 10:09:23 +01:00
{
2008-04-05 23:35:21 +02:00
TRACE_ ( d3d_caps ) ( " [FAILED] - No wrapping and mipmapping support \n " ) ;
return WINED3DERR_NOTAVAILABLE ;
}
2010-05-05 18:22:37 +02:00
UsageCaps | = WINED3DUSAGE_QUERY_WRAPANDMIP ;
2007-09-01 19:57:25 +02:00
}
break ;
2010-05-05 18:22:37 +02:00
default :
FIXME_ ( d3d_caps ) ( " Unhandled resource type %s. \n " , debug_d3dresourcetype ( RType ) ) ;
return WINED3DERR_NOTAVAILABLE ;
2008-08-27 17:42:40 +02:00
}
2007-05-01 01:27:05 +02:00
2010-05-05 18:22:37 +02:00
/* When the UsageCaps exactly matches Usage return WINED3D_OK except for
* the situation in which WINED3DUSAGE_AUTOGENMIPMAP isn ' t around , then
* WINED3DOK_NOAUTOGEN is returned if all the other usage flags match . */
if ( UsageCaps = = Usage )
2008-03-17 20:11:32 +01:00
return WINED3D_OK ;
2010-05-05 18:22:37 +02:00
if ( UsageCaps = = ( Usage & ~ WINED3DUSAGE_AUTOGENMIPMAP ) )
2008-03-17 20:11:32 +01:00
return WINED3DOK_NOAUTOGEN ;
2010-05-05 18:22:37 +02:00
TRACE_ ( d3d_caps ) ( " [FAILED] - Usage %#x requested for CheckFormat %s and RType %s but only %#x is available \n " ,
Usage , debug_d3dformat ( CheckFormat ) , debug_d3dresourcetype ( RType ) , UsageCaps ) ;
return WINED3DERR_NOTAVAILABLE ;
2004-10-05 04:14:06 +02:00
}
2009-12-21 23:17:26 +01:00
static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormatConversion ( IWineD3D * iface , UINT adapter_idx ,
WINED3DDEVTYPE device_type , WINED3DFORMAT src_format , WINED3DFORMAT dst_format )
{
FIXME ( " iface %p, adapter_idx %u, device_type %s, src_format %s, dst_format %s stub! \n " ,
iface , adapter_idx , debug_d3ddevicetype ( device_type ) , debug_d3dformat ( src_format ) ,
debug_d3dformat ( dst_format ) ) ;
2004-10-05 04:14:06 +02:00
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-10-05 04:14:06 +02:00
}
2005-07-13 16:15:54 +02:00
/* Note: d3d8 passes in a pointer to a D3DCAPS8 structure, which is a true
subset of a D3DCAPS9 structure . However , it has to come via a void *
2004-10-06 02:05:29 +02:00
as the d3d8 interface cannot import the d3d9 header */
2006-06-10 13:15:32 +02:00
static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps ( IWineD3D * iface , UINT Adapter , WINED3DDEVTYPE DeviceType , WINED3DCAPS * pCaps ) {
2004-10-06 02:05:29 +02:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
2009-10-21 10:33:58 +02:00
struct wined3d_adapter * adapter = & This - > adapters [ Adapter ] ;
2009-07-17 10:34:01 +02:00
const struct wined3d_gl_info * gl_info = & adapter - > gl_info ;
2006-10-08 05:25:01 +02:00
int vs_selected_mode ;
int ps_selected_mode ;
2008-03-18 19:39:26 +01:00
struct shader_caps shader_caps ;
2008-07-03 21:36:18 +02:00
struct fragment_caps fragment_caps ;
2008-07-29 18:03:59 +02:00
DWORD ckey_caps , blit_caps , fx_caps ;
2004-10-06 02:05:29 +02:00
TRACE_ ( d3d_caps ) ( " (%p)->(Adptr:%d, DevType: %x, pCaps: %p) \n " , This , Adapter , DeviceType , pCaps ) ;
if ( Adapter > = IWineD3D_GetAdapterCount ( iface ) ) {
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-10-06 02:05:29 +02:00
}
2009-09-17 12:35:27 +02:00
select_shader_mode ( & adapter - > gl_info , & ps_selected_mode , & vs_selected_mode ) ;
2006-10-08 05:25:01 +02:00
2004-10-06 02:05:29 +02:00
/* ------------------------------------------------
The following fields apply to both d3d8 and d3d9
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2008-03-18 19:26:00 +01:00
pCaps - > DeviceType = ( DeviceType = = WINED3DDEVTYPE_HAL ) ? WINED3DDEVTYPE_HAL : WINED3DDEVTYPE_REF ; /* Not quite true, but use h/w supported by opengl I suppose */
pCaps - > AdapterOrdinal = Adapter ;
2005-06-22 20:30:29 +02:00
2008-03-18 19:26:00 +01:00
pCaps - > Caps = 0 ;
pCaps - > Caps2 = WINED3DCAPS2_CANRENDERWINDOWED |
WINED3DCAPS2_FULLSCREENGAMMA |
WINED3DCAPS2_DYNAMICTEXTURES ;
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ SGIS_GENERATE_MIPMAP ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > Caps2 | = WINED3DCAPS2_CANAUTOGENMIPMAP ;
}
2008-11-10 10:42:27 +01:00
pCaps - > Caps3 = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
WINED3DCAPS3_COPY_TO_VIDMEM |
WINED3DCAPS3_COPY_TO_SYSTEMMEM ;
2008-03-18 19:26:00 +01:00
pCaps - > PresentationIntervals = WINED3DPRESENT_INTERVAL_IMMEDIATE |
WINED3DPRESENT_INTERVAL_ONE ;
pCaps - > CursorCaps = WINED3DCURSORCAPS_COLOR |
WINED3DCURSORCAPS_LOWRES ;
pCaps - > DevCaps = WINED3DDEVCAPS_FLOATTLVERTEX |
WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY |
WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
WINED3DDEVCAPS_DRAWPRIMTLVERTEX |
WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
WINED3DDEVCAPS_EXECUTEVIDEOMEMORY |
WINED3DDEVCAPS_PUREDEVICE |
WINED3DDEVCAPS_HWRASTERIZATION |
WINED3DDEVCAPS_TEXTUREVIDEOMEMORY |
WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
WINED3DDEVCAPS_CANRENDERAFTERFLIP |
WINED3DDEVCAPS_DRAWPRIMITIVES2 |
WINED3DDEVCAPS_DRAWPRIMITIVES2EX |
WINED3DDEVCAPS_RTPATCHES ;
pCaps - > PrimitiveMiscCaps = WINED3DPMISCCAPS_CULLNONE |
WINED3DPMISCCAPS_CULLCCW |
WINED3DPMISCCAPS_CULLCW |
WINED3DPMISCCAPS_COLORWRITEENABLE |
WINED3DPMISCCAPS_CLIPTLVERTS |
WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
WINED3DPMISCCAPS_MASKZ |
2008-06-27 00:52:07 +02:00
WINED3DPMISCCAPS_BLENDOP |
WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING ;
2006-08-04 22:37:27 +02:00
/* TODO:
2007-02-14 23:31:05 +01:00
WINED3DPMISCCAPS_NULLREFERENCE
WINED3DPMISCCAPS_FOGANDSPECULARALPHA
WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
2006-08-04 22:37:27 +02:00
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ EXT_BLEND_EQUATION_SEPARATE ] & & gl_info - > supported [ EXT_BLEND_FUNC_SEPARATE ] )
2008-03-18 19:26:00 +01:00
pCaps - > PrimitiveMiscCaps | = WINED3DPMISCCAPS_SEPARATEALPHABLEND ;
2010-03-25 22:51:24 +01:00
if ( gl_info - > supported [ EXT_DRAW_BUFFERS2 ] )
pCaps - > PrimitiveMiscCaps | = WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS ;
2008-02-16 16:42:11 +01:00
2008-03-18 19:26:00 +01:00
pCaps - > RasterCaps = WINED3DPRASTERCAPS_DITHER |
WINED3DPRASTERCAPS_PAT |
WINED3DPRASTERCAPS_WFOG |
WINED3DPRASTERCAPS_ZFOG |
WINED3DPRASTERCAPS_FOGVERTEX |
WINED3DPRASTERCAPS_FOGTABLE |
WINED3DPRASTERCAPS_STIPPLE |
WINED3DPRASTERCAPS_SUBPIXEL |
WINED3DPRASTERCAPS_ZTEST |
WINED3DPRASTERCAPS_SCISSORTEST |
WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
WINED3DPRASTERCAPS_DEPTHBIAS ;
2004-10-06 02:05:29 +02:00
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ EXT_TEXTURE_FILTER_ANISOTROPIC ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > RasterCaps | = WINED3DPRASTERCAPS_ANISOTROPY |
WINED3DPRASTERCAPS_ZBIAS |
WINED3DPRASTERCAPS_MIPMAPLODBIAS ;
2007-08-21 12:30:22 +02:00
}
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ NV_FOG_DISTANCE ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > RasterCaps | = WINED3DPRASTERCAPS_FOGRANGE ;
2004-10-06 02:05:29 +02:00
}
/* FIXME Add:
2009-01-09 10:23:43 +01:00
WINED3DPRASTERCAPS_COLORPERSPECTIVE
WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
WINED3DPRASTERCAPS_ANTIALIASEDGES
WINED3DPRASTERCAPS_ZBUFFERLESSHSR
WINED3DPRASTERCAPS_WBUFFER */
2004-10-06 02:05:29 +02:00
2008-03-18 19:26:00 +01:00
pCaps - > ZCmpCaps = WINED3DPCMPCAPS_ALWAYS |
WINED3DPCMPCAPS_EQUAL |
WINED3DPCMPCAPS_GREATER |
WINED3DPCMPCAPS_GREATEREQUAL |
WINED3DPCMPCAPS_LESS |
WINED3DPCMPCAPS_LESSEQUAL |
WINED3DPCMPCAPS_NEVER |
WINED3DPCMPCAPS_NOTEQUAL ;
pCaps - > SrcBlendCaps = WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
WINED3DPBLENDCAPS_BOTHSRCALPHA |
WINED3DPBLENDCAPS_DESTALPHA |
WINED3DPBLENDCAPS_DESTCOLOR |
WINED3DPBLENDCAPS_INVDESTALPHA |
WINED3DPBLENDCAPS_INVDESTCOLOR |
WINED3DPBLENDCAPS_INVSRCALPHA |
WINED3DPBLENDCAPS_INVSRCCOLOR |
WINED3DPBLENDCAPS_ONE |
WINED3DPBLENDCAPS_SRCALPHA |
WINED3DPBLENDCAPS_SRCALPHASAT |
WINED3DPBLENDCAPS_SRCCOLOR |
WINED3DPBLENDCAPS_ZERO ;
pCaps - > DestBlendCaps = WINED3DPBLENDCAPS_DESTALPHA |
WINED3DPBLENDCAPS_DESTCOLOR |
WINED3DPBLENDCAPS_INVDESTALPHA |
WINED3DPBLENDCAPS_INVDESTCOLOR |
WINED3DPBLENDCAPS_INVSRCALPHA |
WINED3DPBLENDCAPS_INVSRCCOLOR |
WINED3DPBLENDCAPS_ONE |
WINED3DPBLENDCAPS_SRCALPHA |
WINED3DPBLENDCAPS_SRCCOLOR |
WINED3DPBLENDCAPS_ZERO ;
2007-08-12 21:38:24 +02:00
/* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
* according to the glBlendFunc manpage
2007-08-12 21:44:30 +02:00
*
* WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
* legacy settings for srcblend only
2007-08-12 21:38:24 +02:00
*/
2006-08-04 19:14:16 +02:00
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ EXT_BLEND_COLOR ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > SrcBlendCaps | = WINED3DPBLENDCAPS_BLENDFACTOR ;
pCaps - > DestBlendCaps | = WINED3DPBLENDCAPS_BLENDFACTOR ;
}
pCaps - > AlphaCmpCaps = WINED3DPCMPCAPS_ALWAYS |
WINED3DPCMPCAPS_EQUAL |
WINED3DPCMPCAPS_GREATER |
WINED3DPCMPCAPS_GREATEREQUAL |
WINED3DPCMPCAPS_LESS |
WINED3DPCMPCAPS_LESSEQUAL |
WINED3DPCMPCAPS_NEVER |
WINED3DPCMPCAPS_NOTEQUAL ;
pCaps - > ShadeCaps = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
WINED3DPSHADECAPS_COLORGOURAUDRGB |
WINED3DPSHADECAPS_ALPHAFLATBLEND |
WINED3DPSHADECAPS_ALPHAGOURAUDBLEND |
WINED3DPSHADECAPS_COLORFLATRGB |
WINED3DPSHADECAPS_FOGFLAT |
WINED3DPSHADECAPS_FOGGOURAUD |
WINED3DPSHADECAPS_SPECULARFLATRGB ;
pCaps - > TextureCaps = WINED3DPTEXTURECAPS_ALPHA |
WINED3DPTEXTURECAPS_ALPHAPALETTE |
2008-08-20 20:51:41 +02:00
WINED3DPTEXTURECAPS_TRANSPARENCY |
2008-03-18 19:26:00 +01:00
WINED3DPTEXTURECAPS_BORDER |
WINED3DPTEXTURECAPS_MIPMAP |
WINED3DPTEXTURECAPS_PROJECTED |
WINED3DPTEXTURECAPS_PERSPECTIVE ;
2007-08-21 12:13:42 +02:00
2009-10-29 10:37:11 +01:00
if ( ! gl_info - > supported [ ARB_TEXTURE_NON_POWER_OF_TWO ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > TextureCaps | = WINED3DPTEXTURECAPS_POW2 |
WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL ;
2007-08-21 12:13:42 +02:00
}
2004-10-06 02:05:29 +02:00
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ EXT_TEXTURE3D ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > TextureCaps | = WINED3DPTEXTURECAPS_VOLUMEMAP |
WINED3DPTEXTURECAPS_MIPVOLUMEMAP |
WINED3DPTEXTURECAPS_VOLUMEMAP_POW2 ;
2006-08-05 00:11:17 +02:00
}
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ ARB_TEXTURE_CUBE_MAP ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > TextureCaps | = WINED3DPTEXTURECAPS_CUBEMAP |
WINED3DPTEXTURECAPS_MIPCUBEMAP |
WINED3DPTEXTURECAPS_CUBEMAP_POW2 ;
2005-06-22 20:30:29 +02:00
2004-10-06 02:05:29 +02:00
}
2008-03-18 19:26:00 +01:00
pCaps - > TextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
WINED3DPTFILTERCAPS_MAGFPOINT |
WINED3DPTFILTERCAPS_MINFLINEAR |
WINED3DPTFILTERCAPS_MINFPOINT |
WINED3DPTFILTERCAPS_MIPFLINEAR |
WINED3DPTFILTERCAPS_MIPFPOINT |
WINED3DPTFILTERCAPS_LINEAR |
WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
WINED3DPTFILTERCAPS_MIPLINEAR |
WINED3DPTFILTERCAPS_MIPNEAREST |
WINED3DPTFILTERCAPS_NEAREST ;
2004-10-06 02:05:29 +02:00
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ EXT_TEXTURE_FILTER_ANISOTROPIC ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > TextureFilterCaps | = WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
WINED3DPTFILTERCAPS_MINFANISOTROPIC ;
2006-08-06 22:50:40 +02:00
}
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ ARB_TEXTURE_CUBE_MAP ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > CubeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
WINED3DPTFILTERCAPS_MAGFPOINT |
WINED3DPTFILTERCAPS_MINFLINEAR |
WINED3DPTFILTERCAPS_MINFPOINT |
WINED3DPTFILTERCAPS_MIPFLINEAR |
WINED3DPTFILTERCAPS_MIPFPOINT |
WINED3DPTFILTERCAPS_LINEAR |
WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
WINED3DPTFILTERCAPS_MIPLINEAR |
WINED3DPTFILTERCAPS_MIPNEAREST |
WINED3DPTFILTERCAPS_NEAREST ;
2006-08-06 22:50:40 +02:00
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ EXT_TEXTURE_FILTER_ANISOTROPIC ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > CubeTextureFilterCaps | = WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
2006-08-06 22:50:40 +02:00
WINED3DPTFILTERCAPS_MINFANISOTROPIC ;
}
} else
2008-03-18 19:26:00 +01:00
pCaps - > CubeTextureFilterCaps = 0 ;
2006-08-06 22:50:40 +02:00
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ EXT_TEXTURE3D ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > VolumeTextureFilterCaps = WINED3DPTFILTERCAPS_MAGFLINEAR |
WINED3DPTFILTERCAPS_MAGFPOINT |
WINED3DPTFILTERCAPS_MINFLINEAR |
WINED3DPTFILTERCAPS_MINFPOINT |
WINED3DPTFILTERCAPS_MIPFLINEAR |
WINED3DPTFILTERCAPS_MIPFPOINT |
WINED3DPTFILTERCAPS_LINEAR |
WINED3DPTFILTERCAPS_LINEARMIPLINEAR |
WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
WINED3DPTFILTERCAPS_MIPLINEAR |
WINED3DPTFILTERCAPS_MIPNEAREST |
WINED3DPTFILTERCAPS_NEAREST ;
2006-08-06 22:50:40 +02:00
} else
2008-03-18 19:26:00 +01:00
pCaps - > VolumeTextureFilterCaps = 0 ;
2004-10-06 02:05:29 +02:00
2008-03-18 19:26:00 +01:00
pCaps - > TextureAddressCaps = WINED3DPTADDRESSCAPS_INDEPENDENTUV |
WINED3DPTADDRESSCAPS_CLAMP |
WINED3DPTADDRESSCAPS_WRAP ;
2004-10-06 02:05:29 +02:00
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ ARB_TEXTURE_BORDER_CLAMP ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > TextureAddressCaps | = WINED3DPTADDRESSCAPS_BORDER ;
2004-10-06 02:05:29 +02:00
}
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ ARB_TEXTURE_MIRRORED_REPEAT ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > TextureAddressCaps | = WINED3DPTADDRESSCAPS_MIRROR ;
2004-10-06 02:05:29 +02:00
}
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ ATI_TEXTURE_MIRROR_ONCE ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > TextureAddressCaps | = WINED3DPTADDRESSCAPS_MIRRORONCE ;
2004-10-06 02:05:29 +02:00
}
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ EXT_TEXTURE3D ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > VolumeTextureAddressCaps = WINED3DPTADDRESSCAPS_INDEPENDENTUV |
WINED3DPTADDRESSCAPS_CLAMP |
WINED3DPTADDRESSCAPS_WRAP ;
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ ARB_TEXTURE_BORDER_CLAMP ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > VolumeTextureAddressCaps | = WINED3DPTADDRESSCAPS_BORDER ;
2006-08-08 17:50:33 +02:00
}
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ ARB_TEXTURE_MIRRORED_REPEAT ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > VolumeTextureAddressCaps | = WINED3DPTADDRESSCAPS_MIRROR ;
2006-08-08 17:50:33 +02:00
}
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ ATI_TEXTURE_MIRROR_ONCE ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > VolumeTextureAddressCaps | = WINED3DPTADDRESSCAPS_MIRRORONCE ;
2006-08-08 17:50:33 +02:00
}
} else
2008-03-18 19:26:00 +01:00
pCaps - > VolumeTextureAddressCaps = 0 ;
2004-10-06 02:05:29 +02:00
2008-08-19 16:34:54 +02:00
pCaps - > LineCaps = WINED3DLINECAPS_TEXTURE |
WINED3DLINECAPS_ZTEST |
WINED3DLINECAPS_BLEND |
WINED3DLINECAPS_ALPHACMP |
WINED3DLINECAPS_FOG ;
/* WINED3DLINECAPS_ANTIALIAS is not supported on Windows, and dx and gl seem to have a different
* idea how generating the smoothing alpha values works ; the result is different
*/
2004-10-06 02:05:29 +02:00
2009-10-29 10:37:10 +01:00
pCaps - > MaxTextureWidth = gl_info - > limits . texture_size ;
pCaps - > MaxTextureHeight = gl_info - > limits . texture_size ;
2004-10-06 02:05:29 +02:00
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ EXT_TEXTURE3D ] )
2009-10-29 10:37:10 +01:00
pCaps - > MaxVolumeExtent = gl_info - > limits . texture3d_size ;
2006-08-06 13:53:19 +02:00
else
2008-03-18 19:26:00 +01:00
pCaps - > MaxVolumeExtent = 0 ;
2004-10-06 02:05:29 +02:00
2008-03-18 19:26:00 +01:00
pCaps - > MaxTextureRepeat = 32768 ;
2009-10-29 10:37:10 +01:00
pCaps - > MaxTextureAspectRatio = gl_info - > limits . texture_size ;
2009-07-07 11:08:01 +02:00
pCaps - > MaxVertexW = 1.0f ;
2004-10-06 02:05:29 +02:00
2009-07-07 11:08:01 +02:00
pCaps - > GuardBandLeft = 0.0f ;
pCaps - > GuardBandTop = 0.0f ;
pCaps - > GuardBandRight = 0.0f ;
pCaps - > GuardBandBottom = 0.0f ;
2004-10-06 02:05:29 +02:00
2009-07-07 11:08:01 +02:00
pCaps - > ExtentsAdjust = 0.0f ;
2004-10-06 02:05:29 +02:00
2008-03-18 19:26:00 +01:00
pCaps - > StencilCaps = WINED3DSTENCILCAPS_DECRSAT |
WINED3DSTENCILCAPS_INCRSAT |
WINED3DSTENCILCAPS_INVERT |
WINED3DSTENCILCAPS_KEEP |
WINED3DSTENCILCAPS_REPLACE |
WINED3DSTENCILCAPS_ZERO ;
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ EXT_STENCIL_WRAP ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > StencilCaps | = WINED3DSTENCILCAPS_DECR |
WINED3DSTENCILCAPS_INCR ;
2004-10-06 02:05:29 +02:00
}
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ EXT_STENCIL_TWO_SIDE ] | | gl_info - > supported [ ATI_SEPARATE_STENCIL ] )
{
2008-03-18 19:26:00 +01:00
pCaps - > StencilCaps | = WINED3DSTENCILCAPS_TWOSIDED ;
2006-06-09 17:30:20 +02:00
}
2004-10-06 02:05:29 +02:00
2008-03-18 19:26:00 +01:00
pCaps - > FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008 ; /* 8 texture coords */
2005-06-22 20:30:29 +02:00
2009-10-29 10:37:10 +01:00
pCaps - > MaxUserClipPlanes = gl_info - > limits . clipplanes ;
pCaps - > MaxActiveLights = gl_info - > limits . lights ;
2005-07-10 19:48:07 +02:00
2009-10-29 10:37:10 +01:00
pCaps - > MaxVertexBlendMatrices = gl_info - > limits . blends ;
2008-03-18 19:26:00 +01:00
pCaps - > MaxVertexBlendMatrixIndex = 0 ;
2004-10-06 02:05:29 +02:00
2009-10-29 10:37:10 +01:00
pCaps - > MaxAnisotropy = gl_info - > limits . anisotropy ;
pCaps - > MaxPointSize = gl_info - > limits . pointsize_max ;
2004-10-06 02:05:29 +02:00
2009-08-27 10:04:56 +02:00
/* FIXME: Add D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
2008-03-18 19:26:00 +01:00
pCaps - > VertexProcessingCaps = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
WINED3DVTXPCAPS_MATERIALSOURCE7 |
WINED3DVTXPCAPS_POSITIONALLIGHTS |
WINED3DVTXPCAPS_LOCALVIEWER |
WINED3DVTXPCAPS_VERTEXFOG |
WINED3DVTXPCAPS_TEXGEN ;
2004-10-06 02:05:29 +02:00
2008-03-18 19:26:00 +01:00
pCaps - > MaxPrimitiveCount = 0xFFFFF ; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
pCaps - > MaxVertexIndex = 0xFFFFF ;
pCaps - > MaxStreams = MAX_STREAMS ;
pCaps - > MaxStreamStride = 1024 ;
2004-10-06 02:05:29 +02:00
2008-03-18 19:26:00 +01:00
/* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
2008-07-12 18:22:18 +02:00
pCaps - > DevCaps2 = WINED3DDEVCAPS2_STREAMOFFSET |
WINED3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET ;
2008-03-18 19:26:00 +01:00
pCaps - > MaxNpatchTessellationLevel = 0 ;
pCaps - > MasterAdapterOrdinal = 0 ;
pCaps - > AdapterOrdinalInGroup = 0 ;
pCaps - > NumberOfAdaptersInGroup = 1 ;
2009-10-29 10:37:10 +01:00
pCaps - > NumSimultaneousRTs = gl_info - > limits . buffers ;
2008-03-18 19:39:26 +01:00
pCaps - > StretchRectFilterCaps = WINED3DPTFILTERCAPS_MINFPOINT |
WINED3DPTFILTERCAPS_MAGFPOINT |
WINED3DPTFILTERCAPS_MINFLINEAR |
WINED3DPTFILTERCAPS_MAGFLINEAR ;
pCaps - > VertexTextureFilterCaps = 0 ;
2010-02-03 18:18:00 +01:00
adapter - > shader_backend - > shader_get_caps ( & adapter - > gl_info , & shader_caps ) ;
2010-02-03 18:17:59 +01:00
adapter - > fragment_pipe - > get_caps ( & adapter - > gl_info , & fragment_caps ) ;
2008-07-03 21:36:18 +02:00
2008-03-29 23:55:09 +01:00
/* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
2008-07-03 21:36:18 +02:00
pCaps - > PrimitiveMiscCaps | = fragment_caps . PrimitiveMiscCaps ;
2008-03-29 23:55:09 +01:00
2008-03-22 14:27:53 +01:00
/* This takes care for disabling vertex shader or pixel shader caps while leaving the other one enabled.
* Ignore shader model capabilities if disabled in config
*/
if ( vs_selected_mode = = SHADER_NONE ) {
TRACE_ ( d3d_caps ) ( " Vertex shader disabled in config, reporting version 0.0 \n " ) ;
pCaps - > VertexShaderVersion = WINED3DVS_VERSION ( 0 , 0 ) ;
pCaps - > MaxVertexShaderConst = 0 ;
} else {
pCaps - > VertexShaderVersion = shader_caps . VertexShaderVersion ;
pCaps - > MaxVertexShaderConst = shader_caps . MaxVertexShaderConst ;
}
if ( ps_selected_mode = = SHADER_NONE ) {
TRACE_ ( d3d_caps ) ( " Pixel shader disabled in config, reporting version 0.0 \n " ) ;
pCaps - > PixelShaderVersion = WINED3DPS_VERSION ( 0 , 0 ) ;
2009-07-07 11:08:01 +02:00
pCaps - > PixelShader1xMaxValue = 0.0f ;
2008-03-22 14:27:53 +01:00
} else {
pCaps - > PixelShaderVersion = shader_caps . PixelShaderVersion ;
pCaps - > PixelShader1xMaxValue = shader_caps . PixelShader1xMaxValue ;
}
2008-07-03 21:36:18 +02:00
pCaps - > TextureOpCaps = fragment_caps . TextureOpCaps ;
pCaps - > MaxTextureBlendStages = fragment_caps . MaxTextureBlendStages ;
pCaps - > MaxSimultaneousTextures = fragment_caps . MaxSimultaneousTextures ;
2008-03-22 14:27:53 +01:00
/* The following caps are shader specific, but they are things we cannot detect, or which
* are the same among all shader models . So to avoid code duplication set the shader version
* specific , but otherwise constant caps here
*/
if ( pCaps - > VertexShaderVersion = = WINED3DVS_VERSION ( 3 , 0 ) ) {
/* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
use the VS 3.0 from MSDN or else if there ' s OpenGL spec use a hardcoded value minimum VS3 .0 value . */
pCaps - > VS20Caps . Caps = WINED3DVS20CAPS_PREDICATION ;
pCaps - > VS20Caps . DynamicFlowControlDepth = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH ; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
2009-10-29 10:37:10 +01:00
pCaps - > VS20Caps . NumTemps = max ( 32 , adapter - > gl_info . limits . arb_vs_temps ) ;
2008-03-22 14:27:53 +01:00
pCaps - > VS20Caps . StaticFlowControlDepth = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
pCaps - > MaxVShaderInstructionsExecuted = 65535 ; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
2009-10-29 10:37:10 +01:00
pCaps - > MaxVertexShader30InstructionSlots = max ( 512 , adapter - > gl_info . limits . arb_vs_instructions ) ;
}
else if ( pCaps - > VertexShaderVersion = = WINED3DVS_VERSION ( 2 , 0 ) )
{
2008-03-22 14:27:53 +01:00
pCaps - > VS20Caps . Caps = 0 ;
pCaps - > VS20Caps . DynamicFlowControlDepth = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH ;
2009-10-29 10:37:10 +01:00
pCaps - > VS20Caps . NumTemps = max ( 12 , adapter - > gl_info . limits . arb_vs_temps ) ;
2008-03-22 14:27:53 +01:00
pCaps - > VS20Caps . StaticFlowControlDepth = 1 ;
pCaps - > MaxVShaderInstructionsExecuted = 65535 ;
pCaps - > MaxVertexShader30InstructionSlots = 0 ;
} else { /* VS 1.x */
pCaps - > VS20Caps . Caps = 0 ;
pCaps - > VS20Caps . DynamicFlowControlDepth = 0 ;
pCaps - > VS20Caps . NumTemps = 0 ;
pCaps - > VS20Caps . StaticFlowControlDepth = 0 ;
pCaps - > MaxVShaderInstructionsExecuted = 0 ;
pCaps - > MaxVertexShader30InstructionSlots = 0 ;
}
if ( pCaps - > PixelShaderVersion = = WINED3DPS_VERSION ( 3 , 0 ) ) {
/* Where possible set the caps based on OpenGL extensions and if they aren't set (in case of software rendering)
use the PS 3.0 from MSDN or else if there ' s OpenGL spec use a hardcoded value minimum PS 3.0 value . */
/* Caps is more or less undocumented on MSDN but it appears to be used for PS20Caps based on results from R9600/FX5900/Geforce6800 cards from Windows */
pCaps - > PS20Caps . Caps = WINED3DPS20CAPS_ARBITRARYSWIZZLE |
WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
WINED3DPS20CAPS_PREDICATION |
WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT ;
pCaps - > PS20Caps . DynamicFlowControlDepth = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH ; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
2009-10-29 10:37:10 +01:00
pCaps - > PS20Caps . NumTemps = max ( 32 , adapter - > gl_info . limits . arb_ps_temps ) ;
2008-03-22 14:27:53 +01:00
pCaps - > PS20Caps . StaticFlowControlDepth = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH ; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
pCaps - > PS20Caps . NumInstructionSlots = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS ; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
pCaps - > MaxPShaderInstructionsExecuted = 65535 ;
2009-10-29 10:37:10 +01:00
pCaps - > MaxPixelShader30InstructionSlots = max ( WINED3DMIN30SHADERINSTRUCTIONS ,
adapter - > gl_info . limits . arb_ps_instructions ) ;
}
else if ( pCaps - > PixelShaderVersion = = WINED3DPS_VERSION ( 2 , 0 ) )
{
2008-03-22 14:27:53 +01:00
/* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
pCaps - > PS20Caps . Caps = 0 ;
pCaps - > PS20Caps . DynamicFlowControlDepth = 0 ; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
2009-10-29 10:37:10 +01:00
pCaps - > PS20Caps . NumTemps = max ( 12 , adapter - > gl_info . limits . arb_ps_temps ) ;
2008-03-22 14:27:53 +01:00
pCaps - > PS20Caps . StaticFlowControlDepth = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH ; /* Minimum: 1 */
pCaps - > PS20Caps . NumInstructionSlots = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS ; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
pCaps - > MaxPShaderInstructionsExecuted = 512 ; /* Minimum value, a GeforceFX uses 1024 */
pCaps - > MaxPixelShader30InstructionSlots = 0 ;
} else { /* PS 1.x */
pCaps - > PS20Caps . Caps = 0 ;
pCaps - > PS20Caps . DynamicFlowControlDepth = 0 ;
pCaps - > PS20Caps . NumTemps = 0 ;
pCaps - > PS20Caps . StaticFlowControlDepth = 0 ;
pCaps - > PS20Caps . NumInstructionSlots = 0 ;
pCaps - > MaxPShaderInstructionsExecuted = 0 ;
pCaps - > MaxPixelShader30InstructionSlots = 0 ;
}
2008-03-18 19:26:00 +01:00
if ( pCaps - > VertexShaderVersion > = WINED3DVS_VERSION ( 2 , 0 ) ) {
/* OpenGL supports all the formats below, perhaps not always
* without conversion , but it supports them .
* Further GLSL doesn ' t seem to have an official unsigned type so
* don ' t advertise it yet as I ' m not sure how we handle it .
* We might need to add some clamping in the shader engine to
* support it .
* TODO : WINED3DDTCAPS_USHORT2N , WINED3DDTCAPS_USHORT4N , WINED3DDTCAPS_UDEC3 , WINED3DDTCAPS_DEC3N */
pCaps - > DeclTypes = WINED3DDTCAPS_UBYTE4 |
2008-03-18 19:39:26 +01:00
WINED3DDTCAPS_UBYTE4N |
WINED3DDTCAPS_SHORT2N |
WINED3DDTCAPS_SHORT4N ;
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ ARB_HALF_FLOAT_VERTEX ] )
{
2008-03-18 19:39:26 +01:00
pCaps - > DeclTypes | = WINED3DDTCAPS_FLOAT16_2 |
WINED3DDTCAPS_FLOAT16_4 ;
2006-08-08 10:57:15 +02:00
}
2008-03-18 19:26:00 +01:00
} else
pCaps - > DeclTypes = 0 ;
2008-07-29 18:03:59 +02:00
/* Set DirectDraw helper Caps */
ckey_caps = WINEDDCKEYCAPS_DESTBLT |
WINEDDCKEYCAPS_SRCBLT ;
fx_caps = WINEDDFXCAPS_BLTALPHA |
WINEDDFXCAPS_BLTMIRRORLEFTRIGHT |
WINEDDFXCAPS_BLTMIRRORUPDOWN |
WINEDDFXCAPS_BLTROTATION90 |
WINEDDFXCAPS_BLTSHRINKX |
WINEDDFXCAPS_BLTSHRINKXN |
WINEDDFXCAPS_BLTSHRINKY |
WINEDDFXCAPS_BLTSHRINKXN |
WINEDDFXCAPS_BLTSTRETCHX |
WINEDDFXCAPS_BLTSTRETCHXN |
WINEDDFXCAPS_BLTSTRETCHY |
WINEDDFXCAPS_BLTSTRETCHYN ;
blit_caps = WINEDDCAPS_BLT |
WINEDDCAPS_BLTCOLORFILL |
WINEDDCAPS_BLTDEPTHFILL |
WINEDDCAPS_BLTSTRETCH |
WINEDDCAPS_CANBLTSYSMEM |
WINEDDCAPS_CANCLIP |
WINEDDCAPS_CANCLIPSTRETCHED |
WINEDDCAPS_COLORKEY |
WINEDDCAPS_COLORKEYHWASSIST |
WINEDDCAPS_ALIGNBOUNDARYSRC ;
/* Fill the ddraw caps structure */
pCaps - > DirectDrawCaps . Caps = WINEDDCAPS_GDI |
WINEDDCAPS_PALETTE |
2008-07-23 22:38:52 +02:00
blit_caps ;
2008-07-29 18:03:59 +02:00
pCaps - > DirectDrawCaps . Caps2 = WINEDDCAPS2_CERTIFIED |
WINEDDCAPS2_NOPAGELOCKREQUIRED |
WINEDDCAPS2_PRIMARYGAMMA |
WINEDDCAPS2_WIDESURFACES |
WINEDDCAPS2_CANRENDERWINDOWED ;
pCaps - > DirectDrawCaps . SVBCaps = blit_caps ;
pCaps - > DirectDrawCaps . SVBCKeyCaps = ckey_caps ;
pCaps - > DirectDrawCaps . SVBFXCaps = fx_caps ;
pCaps - > DirectDrawCaps . VSBCaps = blit_caps ;
pCaps - > DirectDrawCaps . VSBCKeyCaps = ckey_caps ;
pCaps - > DirectDrawCaps . VSBFXCaps = fx_caps ;
pCaps - > DirectDrawCaps . SSBCaps = blit_caps ;
pCaps - > DirectDrawCaps . SSBCKeyCaps = ckey_caps ;
pCaps - > DirectDrawCaps . SSBFXCaps = fx_caps ;
pCaps - > DirectDrawCaps . ddsCaps = WINEDDSCAPS_ALPHA |
WINEDDSCAPS_BACKBUFFER |
WINEDDSCAPS_FLIP |
WINEDDSCAPS_FRONTBUFFER |
WINEDDSCAPS_OFFSCREENPLAIN |
WINEDDSCAPS_PALETTE |
WINEDDSCAPS_PRIMARYSURFACE |
WINEDDSCAPS_SYSTEMMEMORY |
WINEDDSCAPS_VIDEOMEMORY |
2008-07-23 22:38:52 +02:00
WINEDDSCAPS_VISIBLE ;
2008-08-03 01:06:01 +02:00
pCaps - > DirectDrawCaps . StrideAlign = DDRAW_PITCH_ALIGNMENT ;
2008-07-23 22:38:52 +02:00
/* Set D3D caps if OpenGL is available. */
2009-03-11 10:15:09 +01:00
if ( adapter - > opengl )
{
2008-07-23 22:38:52 +02:00
pCaps - > DirectDrawCaps . ddsCaps | = WINEDDSCAPS_3DDEVICE |
WINEDDSCAPS_MIPMAP |
WINEDDSCAPS_TEXTURE |
WINEDDSCAPS_ZBUFFER ;
pCaps - > DirectDrawCaps . Caps | = WINEDDCAPS_3D ;
}
2006-04-07 12:51:12 +02:00
return WINED3D_OK ;
2004-10-06 02:05:29 +02:00
}
2009-11-18 10:45:53 +01:00
static HRESULT WINAPI IWineD3DImpl_CreateDevice ( IWineD3D * iface , UINT adapter_idx ,
WINED3DDEVTYPE device_type , HWND focus_window , DWORD flags , IUnknown * parent ,
IWineD3DDeviceParent * device_parent , IWineD3DDevice * * device )
2009-01-16 10:14:24 +01:00
{
2009-11-18 10:45:53 +01:00
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
IWineD3DDeviceImpl * object ;
2009-01-07 02:20:08 +01:00
HRESULT hr ;
2004-10-08 22:52:33 +02:00
2009-11-18 10:45:53 +01:00
TRACE ( " iface %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x. \n "
" parent %p, device_parent %p, device %p. \n " ,
iface , adapter_idx , device_type , focus_window , flags ,
parent , device_parent , device ) ;
2007-07-16 20:53:44 +02:00
/* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
2009-11-18 10:45:53 +01:00
* number and create a device without a 3 D adapter for 2 D only operation . */
if ( IWineD3D_GetAdapterCount ( iface ) & & adapter_idx > = IWineD3D_GetAdapterCount ( iface ) )
{
2006-04-07 12:51:12 +02:00
return WINED3DERR_INVALIDCALL ;
2004-10-08 22:52:33 +02:00
}
2009-11-18 10:45:53 +01:00
object = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * object ) ) ;
if ( ! object )
{
ERR ( " Failed to allocate device memory. \n " ) ;
return E_OUTOFMEMORY ;
2009-04-14 20:24:26 +02:00
}
2009-11-18 10:45:53 +01:00
hr = device_init ( object , This , adapter_idx , device_type , focus_window , flags , parent , device_parent ) ;
if ( FAILED ( hr ) )
{
WARN ( " Failed to initialize device, hr %#x. \n " , hr ) ;
2009-07-06 10:08:42 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , object ) ;
return hr ;
}
2008-07-09 01:59:10 +02:00
2009-11-18 10:45:53 +01:00
TRACE ( " Created device %p. \n " , object ) ;
* device = ( IWineD3DDevice * ) object ;
2009-04-14 20:24:26 +02:00
2009-11-18 10:45:53 +01:00
IWineD3DDeviceParent_WineD3DDeviceCreated ( device_parent , * device ) ;
2009-04-14 20:24:26 +02:00
2009-07-06 10:08:42 +02:00
return WINED3D_OK ;
}
2008-08-03 00:59:48 +02:00
2009-07-06 10:08:42 +02:00
static HRESULT WINAPI IWineD3DImpl_GetParent ( IWineD3D * iface , IUnknown * * pParent ) {
IWineD3DImpl * This = ( IWineD3DImpl * ) iface ;
IUnknown_AddRef ( This - > parent ) ;
* pParent = This - > parent ;
return WINED3D_OK ;
}
2008-02-11 01:55:11 +01:00
2008-11-28 15:30:11 +01:00
static void WINE_GLAPI invalid_func ( const void * data )
{
2007-12-19 17:10:02 +01:00
ERR ( " Invalid vertex attribute function called \n " ) ;
DebugBreak ( ) ;
}
2008-11-28 15:30:11 +01:00
static void WINE_GLAPI invalid_texcoord_func ( GLenum unit , const void * data )
{
2008-09-24 15:56:48 +02:00
ERR ( " Invalid texcoord function called \n " ) ;
DebugBreak ( ) ;
}
2007-12-19 17:10:02 +01:00
/* Helper functions for providing vertex data to opengl. The arrays are initialized based on
* the extension detection and are used in drawStridedSlow
*/
2008-11-28 15:30:11 +01:00
static void WINE_GLAPI position_d3dcolor ( const void * data )
{
DWORD pos = * ( ( const DWORD * ) data ) ;
2007-12-19 17:10:02 +01:00
FIXME ( " Add a test for fixed function position from d3dcolor type \n " ) ;
glVertex4s ( D3DCOLOR_B_R ( pos ) ,
D3DCOLOR_B_G ( pos ) ,
D3DCOLOR_B_B ( pos ) ,
D3DCOLOR_B_A ( pos ) ) ;
}
2008-11-28 15:30:11 +01:00
static void WINE_GLAPI position_float4 ( const void * data )
{
const GLfloat * pos = data ;
2007-12-19 17:10:02 +01:00
2009-07-07 11:08:01 +02:00
if ( pos [ 3 ] ! = 0.0f & & pos [ 3 ] ! = 1.0f )
2009-06-22 10:15:57 +02:00
{
2009-07-07 11:08:01 +02:00
float w = 1.0f / pos [ 3 ] ;
2007-12-25 09:18:21 +01:00
glVertex4f ( pos [ 0 ] * w , pos [ 1 ] * w , pos [ 2 ] * w , w ) ;
}
2009-06-22 10:15:57 +02:00
else
{
glVertex3fv ( pos ) ;
}
2007-12-19 17:10:02 +01:00
}
2008-11-28 15:30:11 +01:00
static void WINE_GLAPI diffuse_d3dcolor ( const void * data )
{
DWORD diffuseColor = * ( ( const DWORD * ) data ) ;
2007-12-19 17:10:02 +01:00
glColor4ub ( D3DCOLOR_B_R ( diffuseColor ) ,
D3DCOLOR_B_G ( diffuseColor ) ,
D3DCOLOR_B_B ( diffuseColor ) ,
D3DCOLOR_B_A ( diffuseColor ) ) ;
}
2008-11-28 15:30:11 +01:00
static void WINE_GLAPI specular_d3dcolor ( const void * data )
{
DWORD specularColor = * ( ( const DWORD * ) data ) ;
2009-03-11 10:15:09 +01:00
GLbyte d [ ] = { D3DCOLOR_B_R ( specularColor ) ,
D3DCOLOR_B_G ( specularColor ) ,
D3DCOLOR_B_B ( specularColor ) } ;
2007-12-19 17:10:02 +01:00
2009-03-11 10:15:09 +01:00
specular_func_3ubv ( d ) ;
2007-12-19 17:10:02 +01:00
}
2008-11-28 15:30:11 +01:00
static void WINE_GLAPI warn_no_specular_func ( const void * data )
{
2007-12-19 17:10:02 +01:00
WARN ( " GL_EXT_secondary_color not supported \n " ) ;
}
2009-07-17 10:34:01 +02:00
static void fillGLAttribFuncs ( const struct wined3d_gl_info * gl_info )
2008-11-28 15:30:11 +01:00
{
2009-03-27 10:25:56 +01:00
position_funcs [ WINED3D_FFP_EMIT_FLOAT1 ] = invalid_func ;
position_funcs [ WINED3D_FFP_EMIT_FLOAT2 ] = invalid_func ;
position_funcs [ WINED3D_FFP_EMIT_FLOAT3 ] = ( glAttribFunc ) glVertex3fv ;
position_funcs [ WINED3D_FFP_EMIT_FLOAT4 ] = position_float4 ;
position_funcs [ WINED3D_FFP_EMIT_D3DCOLOR ] = position_d3dcolor ;
position_funcs [ WINED3D_FFP_EMIT_UBYTE4 ] = invalid_func ;
position_funcs [ WINED3D_FFP_EMIT_SHORT2 ] = invalid_func ;
position_funcs [ WINED3D_FFP_EMIT_SHORT4 ] = ( glAttribFunc ) glVertex2sv ;
position_funcs [ WINED3D_FFP_EMIT_UBYTE4N ] = invalid_func ;
position_funcs [ WINED3D_FFP_EMIT_SHORT2N ] = invalid_func ;
position_funcs [ WINED3D_FFP_EMIT_SHORT4N ] = invalid_func ;
position_funcs [ WINED3D_FFP_EMIT_USHORT2N ] = invalid_func ;
position_funcs [ WINED3D_FFP_EMIT_USHORT4N ] = invalid_func ;
position_funcs [ WINED3D_FFP_EMIT_UDEC3 ] = invalid_func ;
position_funcs [ WINED3D_FFP_EMIT_DEC3N ] = invalid_func ;
position_funcs [ WINED3D_FFP_EMIT_FLOAT16_2 ] = invalid_func ;
position_funcs [ WINED3D_FFP_EMIT_FLOAT16_4 ] = invalid_func ;
diffuse_funcs [ WINED3D_FFP_EMIT_FLOAT1 ] = invalid_func ;
diffuse_funcs [ WINED3D_FFP_EMIT_FLOAT2 ] = invalid_func ;
diffuse_funcs [ WINED3D_FFP_EMIT_FLOAT3 ] = ( glAttribFunc ) glColor3fv ;
diffuse_funcs [ WINED3D_FFP_EMIT_FLOAT4 ] = ( glAttribFunc ) glColor4fv ;
diffuse_funcs [ WINED3D_FFP_EMIT_D3DCOLOR ] = diffuse_d3dcolor ;
diffuse_funcs [ WINED3D_FFP_EMIT_UBYTE4 ] = invalid_func ;
diffuse_funcs [ WINED3D_FFP_EMIT_SHORT2 ] = invalid_func ;
diffuse_funcs [ WINED3D_FFP_EMIT_SHORT4 ] = invalid_func ;
diffuse_funcs [ WINED3D_FFP_EMIT_UBYTE4N ] = ( glAttribFunc ) glColor4ubv ;
diffuse_funcs [ WINED3D_FFP_EMIT_SHORT2N ] = invalid_func ;
diffuse_funcs [ WINED3D_FFP_EMIT_SHORT4N ] = ( glAttribFunc ) glColor4sv ;
diffuse_funcs [ WINED3D_FFP_EMIT_USHORT2N ] = invalid_func ;
diffuse_funcs [ WINED3D_FFP_EMIT_USHORT4N ] = ( glAttribFunc ) glColor4usv ;
diffuse_funcs [ WINED3D_FFP_EMIT_UDEC3 ] = invalid_func ;
diffuse_funcs [ WINED3D_FFP_EMIT_DEC3N ] = invalid_func ;
diffuse_funcs [ WINED3D_FFP_EMIT_FLOAT16_2 ] = invalid_func ;
diffuse_funcs [ WINED3D_FFP_EMIT_FLOAT16_4 ] = invalid_func ;
2007-12-19 17:10:02 +01:00
/* No 4 component entry points here */
2009-03-27 10:25:56 +01:00
specular_funcs [ WINED3D_FFP_EMIT_FLOAT1 ] = invalid_func ;
specular_funcs [ WINED3D_FFP_EMIT_FLOAT2 ] = invalid_func ;
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ EXT_SECONDARY_COLOR ] )
{
2009-03-27 10:25:56 +01:00
specular_funcs [ WINED3D_FFP_EMIT_FLOAT3 ] = ( glAttribFunc ) GL_EXTCALL ( glSecondaryColor3fvEXT ) ;
2009-10-29 10:37:11 +01:00
}
else
{
2009-03-27 10:25:56 +01:00
specular_funcs [ WINED3D_FFP_EMIT_FLOAT3 ] = warn_no_specular_func ;
2007-12-19 17:10:02 +01:00
}
2009-03-27 10:25:56 +01:00
specular_funcs [ WINED3D_FFP_EMIT_FLOAT4 ] = invalid_func ;
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ EXT_SECONDARY_COLOR ] )
{
2009-03-11 10:15:09 +01:00
specular_func_3ubv = ( glAttribFunc ) GL_EXTCALL ( glSecondaryColor3ubvEXT ) ;
2009-03-27 10:25:56 +01:00
specular_funcs [ WINED3D_FFP_EMIT_D3DCOLOR ] = specular_d3dcolor ;
2009-10-29 10:37:11 +01:00
}
else
{
2009-03-27 10:25:56 +01:00
specular_funcs [ WINED3D_FFP_EMIT_D3DCOLOR ] = warn_no_specular_func ;
2007-12-19 17:10:02 +01:00
}
2009-03-27 10:25:56 +01:00
specular_funcs [ WINED3D_FFP_EMIT_UBYTE4 ] = invalid_func ;
specular_funcs [ WINED3D_FFP_EMIT_SHORT2 ] = invalid_func ;
specular_funcs [ WINED3D_FFP_EMIT_SHORT4 ] = invalid_func ;
specular_funcs [ WINED3D_FFP_EMIT_UBYTE4N ] = invalid_func ;
specular_funcs [ WINED3D_FFP_EMIT_SHORT2N ] = invalid_func ;
specular_funcs [ WINED3D_FFP_EMIT_SHORT4N ] = invalid_func ;
specular_funcs [ WINED3D_FFP_EMIT_USHORT2N ] = invalid_func ;
specular_funcs [ WINED3D_FFP_EMIT_USHORT4N ] = invalid_func ;
specular_funcs [ WINED3D_FFP_EMIT_UDEC3 ] = invalid_func ;
specular_funcs [ WINED3D_FFP_EMIT_DEC3N ] = invalid_func ;
specular_funcs [ WINED3D_FFP_EMIT_FLOAT16_2 ] = invalid_func ;
specular_funcs [ WINED3D_FFP_EMIT_FLOAT16_4 ] = invalid_func ;
2007-12-19 17:10:02 +01:00
/* Only 3 component entry points here. Test how others behave. Float4 normals are used
* by one of our tests , trying to pass it to the pixel shader , which fails on Windows .
*/
2009-03-27 10:25:56 +01:00
normal_funcs [ WINED3D_FFP_EMIT_FLOAT1 ] = invalid_func ;
normal_funcs [ WINED3D_FFP_EMIT_FLOAT2 ] = invalid_func ;
normal_funcs [ WINED3D_FFP_EMIT_FLOAT3 ] = ( glAttribFunc ) glNormal3fv ;
normal_funcs [ WINED3D_FFP_EMIT_FLOAT4 ] = ( glAttribFunc ) glNormal3fv ; /* Just ignore the 4th value */
normal_funcs [ WINED3D_FFP_EMIT_D3DCOLOR ] = invalid_func ;
normal_funcs [ WINED3D_FFP_EMIT_UBYTE4 ] = invalid_func ;
normal_funcs [ WINED3D_FFP_EMIT_SHORT2 ] = invalid_func ;
normal_funcs [ WINED3D_FFP_EMIT_SHORT4 ] = invalid_func ;
normal_funcs [ WINED3D_FFP_EMIT_UBYTE4N ] = invalid_func ;
normal_funcs [ WINED3D_FFP_EMIT_SHORT2N ] = invalid_func ;
normal_funcs [ WINED3D_FFP_EMIT_SHORT4N ] = invalid_func ;
normal_funcs [ WINED3D_FFP_EMIT_USHORT2N ] = invalid_func ;
normal_funcs [ WINED3D_FFP_EMIT_USHORT4N ] = invalid_func ;
normal_funcs [ WINED3D_FFP_EMIT_UDEC3 ] = invalid_func ;
normal_funcs [ WINED3D_FFP_EMIT_DEC3N ] = invalid_func ;
normal_funcs [ WINED3D_FFP_EMIT_FLOAT16_2 ] = invalid_func ;
normal_funcs [ WINED3D_FFP_EMIT_FLOAT16_4 ] = invalid_func ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_FLOAT1 ] = ( glMultiTexCoordFunc ) GL_EXTCALL ( glMultiTexCoord1fvARB ) ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_FLOAT2 ] = ( glMultiTexCoordFunc ) GL_EXTCALL ( glMultiTexCoord2fvARB ) ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_FLOAT3 ] = ( glMultiTexCoordFunc ) GL_EXTCALL ( glMultiTexCoord3fvARB ) ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_FLOAT4 ] = ( glMultiTexCoordFunc ) GL_EXTCALL ( glMultiTexCoord4fvARB ) ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_D3DCOLOR ] = invalid_texcoord_func ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_UBYTE4 ] = invalid_texcoord_func ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_SHORT2 ] = ( glMultiTexCoordFunc ) GL_EXTCALL ( glMultiTexCoord2svARB ) ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_SHORT4 ] = ( glMultiTexCoordFunc ) GL_EXTCALL ( glMultiTexCoord4svARB ) ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_UBYTE4N ] = invalid_texcoord_func ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_SHORT2N ] = invalid_texcoord_func ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_SHORT4N ] = invalid_texcoord_func ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_USHORT2N ] = invalid_texcoord_func ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_USHORT4N ] = invalid_texcoord_func ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_UDEC3 ] = invalid_texcoord_func ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_DEC3N ] = invalid_texcoord_func ;
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ NV_HALF_FLOAT ] )
2008-09-24 15:56:48 +02:00
{
2009-04-06 19:07:51 +02:00
/* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT */
2009-03-27 10:25:56 +01:00
multi_texcoord_funcs [ WINED3D_FFP_EMIT_FLOAT16_2 ] = ( glMultiTexCoordFunc ) GL_EXTCALL ( glMultiTexCoord2hvNV ) ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_FLOAT16_4 ] = ( glMultiTexCoordFunc ) GL_EXTCALL ( glMultiTexCoord4hvNV ) ;
2008-09-24 15:56:48 +02:00
} else {
2009-03-27 10:25:56 +01:00
multi_texcoord_funcs [ WINED3D_FFP_EMIT_FLOAT16_2 ] = invalid_texcoord_func ;
multi_texcoord_funcs [ WINED3D_FFP_EMIT_FLOAT16_4 ] = invalid_texcoord_func ;
2008-09-24 15:56:48 +02:00
}
2007-12-19 17:10:02 +01:00
}
2010-04-04 19:51:37 +02:00
static BOOL InitAdapters ( IWineD3DImpl * This )
2009-03-11 10:15:09 +01:00
{
2008-11-23 12:43:15 +01:00
static HMODULE mod_gl ;
2007-06-09 14:27:41 +02:00
BOOL ret ;
2007-07-16 19:59:41 +02:00
int ps_selected_mode , vs_selected_mode ;
2007-06-09 14:27:41 +02:00
/* No need to hold any lock. The calling library makes sure only one thread calls
* wined3d simultaneously
*/
TRACE ( " Initializing adapters \n " ) ;
2007-08-24 19:16:30 +02:00
if ( ! mod_gl ) {
# ifdef USE_WIN32_OPENGL
# define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
mod_gl = LoadLibraryA ( " opengl32.dll " ) ;
if ( ! mod_gl ) {
ERR ( " Can't load opengl32.dll! \n " ) ;
2008-03-28 23:04:17 +01:00
goto nogl_adapter ;
2007-08-24 19:16:30 +02:00
}
# else
# define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
/* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
mod_gl = GetModuleHandleA ( " gdi32.dll " ) ;
# endif
}
/* Load WGL core functions from opengl32.dll */
# define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
WGL_FUNCS_GEN ;
# undef USE_WGL_FUNC
if ( ! pwglGetProcAddress ) {
ERR ( " Unable to load wglGetProcAddress! \n " ) ;
2008-03-28 23:04:17 +01:00
goto nogl_adapter ;
2007-08-24 19:16:30 +02:00
}
2007-08-29 21:43:57 +02:00
/* Dynamically load all GL core functions */
2007-08-24 19:16:30 +02:00
GL_FUNCS_GEN ;
# undef USE_GL_FUNC
2008-07-30 17:53:33 +02:00
/* Load glFinish and glFlush from opengl32.dll even if we're not using WIN32 opengl
* otherwise because we have to use winex11 . drv ' s override
*/
2008-11-23 12:43:15 +01:00
# ifdef USE_WIN32_OPENGL
2009-08-26 11:44:34 +02:00
wglFinish = ( void * ) GetProcAddress ( mod_gl , " glFinish " ) ;
wglFlush = ( void * ) GetProcAddress ( mod_gl , " glFlush " ) ;
2008-11-23 12:43:15 +01:00
# else
2009-08-26 11:44:34 +02:00
wglFinish = ( void * ) pwglGetProcAddress ( " wglFinish " ) ;
wglFlush = ( void * ) pwglGetProcAddress ( " wglFlush " ) ;
2008-11-23 12:43:15 +01:00
# endif
2008-07-30 17:53:33 +02:00
2008-12-15 19:38:48 +01:00
glEnableWINE = glEnable ;
glDisableWINE = glDisable ;
2007-06-09 14:27:41 +02:00
/* For now only one default adapter */
{
2009-10-21 10:33:58 +02:00
struct wined3d_adapter * adapter = & This - > adapters [ 0 ] ;
2009-07-17 10:34:01 +02:00
const struct wined3d_gl_info * gl_info = & adapter - > gl_info ;
2009-07-03 09:39:18 +02:00
struct wined3d_fake_gl_ctx fake_gl_ctx = { 0 } ;
2007-08-24 19:16:30 +02:00
int iPixelFormat ;
int res ;
2008-05-03 16:37:09 +02:00
int i ;
2007-08-24 19:16:30 +02:00
WineD3D_PixelFormat * cfgs ;
2007-08-13 16:47:17 +02:00
DISPLAY_DEVICEW DisplayDevice ;
2007-08-27 17:49:11 +02:00
HDC hdc ;
2007-08-13 16:47:17 +02:00
2007-06-09 14:27:41 +02:00
TRACE ( " Initializing default adapter \n " ) ;
2009-12-07 20:20:00 +01:00
adapter - > ordinal = 0 ;
2009-03-11 10:15:09 +01:00
adapter - > monitorPoint . x = - 1 ;
adapter - > monitorPoint . y = - 1 ;
2007-06-09 14:27:41 +02:00
2009-12-02 10:41:23 +01:00
if ( ! AllocateLocallyUniqueId ( & adapter - > luid ) )
{
DWORD err = GetLastError ( ) ;
ERR ( " Failed to set adapter LUID (%#x). \n " , err ) ;
goto nogl_adapter ;
}
TRACE ( " Allocated LUID %08x:%08x for adapter. \n " ,
adapter - > luid . HighPart , adapter - > luid . LowPart ) ;
2009-07-03 09:39:18 +02:00
if ( ! WineD3D_CreateFakeGLContext ( & fake_gl_ctx ) )
{
2007-08-24 19:16:30 +02:00
ERR ( " Failed to get a gl context for default adapter \n " ) ;
2008-03-28 23:04:17 +01:00
goto nogl_adapter ;
2007-08-24 19:16:30 +02:00
}
2010-02-02 12:06:56 +01:00
ret = IWineD3DImpl_FillGLCaps ( adapter ) ;
2007-06-08 14:16:37 +02:00
if ( ! ret ) {
2007-06-09 14:27:41 +02:00
ERR ( " Failed to initialize gl caps for default adapter \n " ) ;
2009-07-03 09:39:18 +02:00
WineD3D_ReleaseFakeGLContext ( & fake_gl_ctx ) ;
2008-03-28 23:04:17 +01:00
goto nogl_adapter ;
2007-06-09 14:27:41 +02:00
}
2009-10-27 10:10:39 +01:00
ret = initPixelFormats ( & adapter - > gl_info , adapter - > driver_info . vendor ) ;
2007-07-27 13:22:54 +02:00
if ( ! ret ) {
ERR ( " Failed to init gl formats \n " ) ;
2009-07-03 09:39:18 +02:00
WineD3D_ReleaseFakeGLContext ( & fake_gl_ctx ) ;
2008-03-28 23:04:17 +01:00
goto nogl_adapter ;
2007-07-27 13:22:54 +02:00
}
2009-07-03 09:39:18 +02:00
hdc = fake_gl_ctx . dc ;
2007-08-27 17:49:11 +02:00
2007-09-23 00:46:21 +02:00
/* Use the VideoRamSize registry setting when set */
if ( wined3d_settings . emulated_textureram )
2009-03-11 10:15:09 +01:00
adapter - > TextureRam = wined3d_settings . emulated_textureram ;
2007-09-23 00:46:21 +02:00
else
2009-03-11 10:15:09 +01:00
adapter - > TextureRam = adapter - > gl_info . vidmem ;
adapter - > UsedTextureRam = 0 ;
TRACE ( " Emulating %dMB of texture ram \n " , adapter - > TextureRam / ( 1024 * 1024 ) ) ;
2007-09-23 00:46:21 +02:00
2007-08-13 16:47:17 +02:00
/* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
DisplayDevice . cb = sizeof ( DisplayDevice ) ;
EnumDisplayDevicesW ( NULL , 0 /* Adapter 0 = iDevNum 0 */ , & DisplayDevice , 0 ) ;
TRACE ( " DeviceName: %s \n " , debugstr_w ( DisplayDevice . DeviceName ) ) ;
2009-03-11 10:15:09 +01:00
strcpyW ( adapter - > DeviceName , DisplayDevice . DeviceName ) ;
2007-08-13 16:47:17 +02:00
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ WGL_ARB_PIXEL_FORMAT ] )
2009-03-11 10:15:09 +01:00
{
2009-03-15 11:30:10 +01:00
int attribute ;
2010-03-01 17:32:53 +01:00
int attribs [ 11 ] ;
int values [ 11 ] ;
2009-03-15 11:30:10 +01:00
int nAttribs = 0 ;
attribute = WGL_NUMBER_PIXEL_FORMATS_ARB ;
GL_EXTCALL ( wglGetPixelFormatAttribivARB ( hdc , 0 , 0 , 1 , & attribute , & adapter - > nCfgs ) ) ;
adapter - > cfgs = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , adapter - > nCfgs * sizeof ( WineD3D_PixelFormat ) ) ;
cfgs = adapter - > cfgs ;
attribs [ nAttribs + + ] = WGL_RED_BITS_ARB ;
attribs [ nAttribs + + ] = WGL_GREEN_BITS_ARB ;
attribs [ nAttribs + + ] = WGL_BLUE_BITS_ARB ;
attribs [ nAttribs + + ] = WGL_ALPHA_BITS_ARB ;
2010-03-01 17:32:53 +01:00
attribs [ nAttribs + + ] = WGL_COLOR_BITS_ARB ;
2009-03-15 11:30:10 +01:00
attribs [ nAttribs + + ] = WGL_DEPTH_BITS_ARB ;
attribs [ nAttribs + + ] = WGL_STENCIL_BITS_ARB ;
attribs [ nAttribs + + ] = WGL_DRAW_TO_WINDOW_ARB ;
attribs [ nAttribs + + ] = WGL_PIXEL_TYPE_ARB ;
attribs [ nAttribs + + ] = WGL_DOUBLE_BUFFER_ARB ;
attribs [ nAttribs + + ] = WGL_AUX_BUFFERS_ARB ;
for ( iPixelFormat = 1 ; iPixelFormat < = adapter - > nCfgs ; + + iPixelFormat )
{
res = GL_EXTCALL ( wglGetPixelFormatAttribivARB ( hdc , iPixelFormat , 0 , nAttribs , attribs , values ) ) ;
2007-08-24 19:16:30 +02:00
2009-03-15 11:30:10 +01:00
if ( ! res )
continue ;
/* Cache the pixel format */
cfgs - > iPixelFormat = iPixelFormat ;
cfgs - > redSize = values [ 0 ] ;
cfgs - > greenSize = values [ 1 ] ;
cfgs - > blueSize = values [ 2 ] ;
cfgs - > alphaSize = values [ 3 ] ;
2010-03-01 17:32:53 +01:00
cfgs - > colorSize = values [ 4 ] ;
cfgs - > depthSize = values [ 5 ] ;
cfgs - > stencilSize = values [ 6 ] ;
cfgs - > windowDrawable = values [ 7 ] ;
cfgs - > iPixelType = values [ 8 ] ;
cfgs - > doubleBuffer = values [ 9 ] ;
cfgs - > auxBuffers = values [ 10 ] ;
2009-03-15 11:30:10 +01:00
cfgs - > numSamples = 0 ;
/* Check multisample support */
2009-10-29 10:37:11 +01:00
if ( gl_info - > supported [ ARB_MULTISAMPLE ] )
{
2009-03-15 11:30:10 +01:00
int attrib [ 2 ] = { WGL_SAMPLE_BUFFERS_ARB , WGL_SAMPLES_ARB } ;
int value [ 2 ] ;
if ( GL_EXTCALL ( wglGetPixelFormatAttribivARB ( hdc , iPixelFormat , 0 , 2 , attrib , value ) ) ) {
/* value[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether multisampling is supported.
* value [ 1 ] = number of multi sample buffers */
if ( value [ 0 ] )
cfgs - > numSamples = value [ 1 ] ;
}
}
2007-08-24 19:16:30 +02:00
2010-03-14 21:53:23 +01:00
TRACE ( " iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
" depth=%d, stencil=%d, samples=%d, windowDrawable=%d \n " ,
cfgs - > iPixelFormat , cfgs - > iPixelType , cfgs - > doubleBuffer ,
cfgs - > redSize , cfgs - > greenSize , cfgs - > blueSize , cfgs - > alphaSize ,
cfgs - > depthSize , cfgs - > stencilSize , cfgs - > numSamples , cfgs - > windowDrawable ) ;
2009-03-15 11:30:10 +01:00
cfgs + + ;
2008-03-16 17:37:38 +01:00
}
2009-03-15 11:30:10 +01:00
}
else
{
int nCfgs = DescribePixelFormat ( hdc , 0 , 0 , 0 ) ;
adapter - > cfgs = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , nCfgs * sizeof ( WineD3D_PixelFormat ) ) ;
adapter - > nCfgs = 0 ; /* We won't accept all formats e.g. software accelerated ones will be skipped */
cfgs = adapter - > cfgs ;
for ( iPixelFormat = 1 ; iPixelFormat < = nCfgs ; iPixelFormat + + )
{
PIXELFORMATDESCRIPTOR ppfd ;
2007-08-24 19:16:30 +02:00
2009-03-15 11:30:10 +01:00
res = DescribePixelFormat ( hdc , iPixelFormat , sizeof ( PIXELFORMATDESCRIPTOR ) , & ppfd ) ;
if ( ! res )
continue ;
/* We only want HW acceleration using an OpenGL ICD driver.
* PFD_GENERIC_FORMAT = slow opengl 1.1 gdi software rendering
* PFD_GENERIC_ACCELERATED = partial hw acceleration using a MCD driver ( e . g . 3 dfx minigl )
*/
if ( ppfd . dwFlags & ( PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED ) )
{
TRACE ( " Skipping iPixelFormat=%d because it isn't ICD accelerated \n " , iPixelFormat ) ;
continue ;
2008-04-28 23:44:21 +02:00
}
2009-03-15 11:30:10 +01:00
cfgs - > iPixelFormat = iPixelFormat ;
cfgs - > redSize = ppfd . cRedBits ;
cfgs - > greenSize = ppfd . cGreenBits ;
cfgs - > blueSize = ppfd . cBlueBits ;
cfgs - > alphaSize = ppfd . cAlphaBits ;
2010-03-01 17:32:53 +01:00
cfgs - > colorSize = ppfd . cColorBits ;
2009-03-15 11:30:10 +01:00
cfgs - > depthSize = ppfd . cDepthBits ;
cfgs - > stencilSize = ppfd . cStencilBits ;
cfgs - > windowDrawable = ( ppfd . dwFlags & PFD_DRAW_TO_WINDOW ) ? 1 : 0 ;
cfgs - > iPixelType = ( ppfd . iPixelType = = PFD_TYPE_RGBA ) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB ;
cfgs - > doubleBuffer = ( ppfd . dwFlags & PFD_DOUBLEBUFFER ) ? 1 : 0 ;
cfgs - > auxBuffers = ppfd . cAuxBuffers ;
cfgs - > numSamples = 0 ;
2010-03-14 21:53:23 +01:00
TRACE ( " iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
" depth=%d, stencil=%d, windowDrawable=%d \n " ,
cfgs - > iPixelFormat , cfgs - > iPixelType , cfgs - > doubleBuffer ,
cfgs - > redSize , cfgs - > greenSize , cfgs - > blueSize , cfgs - > alphaSize ,
cfgs - > depthSize , cfgs - > stencilSize , cfgs - > windowDrawable ) ;
2009-03-15 11:30:10 +01:00
cfgs + + ;
adapter - > nCfgs + + ;
2008-04-28 23:44:21 +02:00
}
2009-03-15 11:30:10 +01:00
/* Yikes we haven't found any suitable formats. This should only happen in case of GDI software rendering which we can't use anyway as its 3D functionality is very, very limited */
if ( ! adapter - > nCfgs )
{
ERR ( " Disabling Direct3D because no hardware accelerated pixel formats have been found! \n " ) ;
2009-07-03 09:39:18 +02:00
WineD3D_ReleaseFakeGLContext ( & fake_gl_ctx ) ;
2009-03-15 11:30:10 +01:00
HeapFree ( GetProcessHeap ( ) , 0 , adapter - > cfgs ) ;
goto nogl_adapter ;
}
2007-08-08 03:09:38 +02:00
}
2008-05-03 16:37:09 +02:00
/* D16, D24X8 and D24S8 are common depth / depth+stencil formats. All drivers support them though this doesn't
* mean that the format is offered in hardware . For instance Geforce8 cards don ' t have offer D16 in hardware
* but just fake it using D24 ( X8 ? ) which is fine . D3D also allows that .
* Some display drivers ( i915 on Linux ) only report mixed depth + stencil formats like D24S8 . MSDN clearly mentions
* that only on lockable formats ( e . g . D16_locked ) the bit order is guaranteed and that on other formats the
* driver is allowed to consume more bits EXCEPT for stencil bits .
*
* Mark an adapter with this broken stencil behavior .
*/
2009-03-11 10:15:09 +01:00
adapter - > brokenStencil = TRUE ;
for ( i = 0 , cfgs = adapter - > cfgs ; i < adapter - > nCfgs ; + + i )
{
2008-05-03 16:37:09 +02:00
/* Nearly all drivers offer depth formats without stencil, only on i915 this if-statement won't be entered. */
if ( cfgs [ i ] . depthSize & & ! cfgs [ i ] . stencilSize ) {
2009-03-11 10:15:09 +01:00
adapter - > brokenStencil = FALSE ;
2008-05-03 16:37:09 +02:00
break ;
}
}
2009-07-03 09:39:18 +02:00
WineD3D_ReleaseFakeGLContext ( & fake_gl_ctx ) ;
2008-02-24 10:19:01 +01:00
2009-09-17 12:35:27 +02:00
select_shader_mode ( & adapter - > gl_info , & ps_selected_mode , & vs_selected_mode ) ;
2009-03-11 10:15:09 +01:00
fillGLAttribFuncs ( & adapter - > gl_info ) ;
adapter - > opengl = TRUE ;
2007-06-09 14:27:41 +02:00
}
2009-03-11 10:15:09 +01:00
This - > adapter_count = 1 ;
TRACE ( " %u adapters successfully initialized \n " , This - > adapter_count ) ;
2007-06-09 14:27:41 +02:00
return TRUE ;
2008-03-28 23:04:17 +01:00
nogl_adapter :
/* Initialize an adapter for ddraw-only memory counting */
2009-03-11 10:15:09 +01:00
memset ( This - > adapters , 0 , sizeof ( This - > adapters ) ) ;
2009-12-07 20:20:00 +01:00
This - > adapters [ 0 ] . ordinal = 0 ;
2009-03-11 10:15:09 +01:00
This - > adapters [ 0 ] . opengl = FALSE ;
This - > adapters [ 0 ] . monitorPoint . x = - 1 ;
This - > adapters [ 0 ] . monitorPoint . y = - 1 ;
2009-10-26 10:12:16 +01:00
This - > adapters [ 0 ] . driver_info . name = " Display " ;
This - > adapters [ 0 ] . driver_info . description = " WineD3D DirectDraw Emulation " ;
2008-03-28 23:04:17 +01:00
if ( wined3d_settings . emulated_textureram ) {
2009-03-11 10:15:09 +01:00
This - > adapters [ 0 ] . TextureRam = wined3d_settings . emulated_textureram ;
2008-03-28 23:04:17 +01:00
} else {
2009-03-11 10:15:09 +01:00
This - > adapters [ 0 ] . TextureRam = 8 * 1024 * 1024 ; /* This is plenty for a DDraw-only card */
2008-03-28 23:04:17 +01:00
}
2009-03-13 10:44:17 +01:00
initPixelFormatsNoGL ( & This - > adapters [ 0 ] . gl_info ) ;
2009-03-11 10:15:09 +01:00
This - > adapter_count = 1 ;
2008-03-28 23:04:17 +01:00
return FALSE ;
2007-06-09 14:27:41 +02:00
}
2004-09-29 23:26:47 +02:00
/**********************************************************
* IWineD3D VTbl follows
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-04-04 19:51:37 +02:00
static const struct IWineD3DVtbl IWineD3D_Vtbl =
2004-09-23 06:34:27 +02:00
{
2005-07-13 16:15:54 +02:00
/* IUnknown */
2004-09-23 06:34:27 +02:00
IWineD3DImpl_QueryInterface ,
IWineD3DImpl_AddRef ,
IWineD3DImpl_Release ,
2005-07-13 16:15:54 +02:00
/* IWineD3D */
2004-11-23 14:52:46 +01:00
IWineD3DImpl_GetParent ,
2004-09-28 04:12:12 +02:00
IWineD3DImpl_GetAdapterCount ,
IWineD3DImpl_RegisterSoftwareDevice ,
IWineD3DImpl_GetAdapterMonitor ,
IWineD3DImpl_GetAdapterModeCount ,
IWineD3DImpl_EnumAdapterModes ,
2004-09-29 23:26:47 +02:00
IWineD3DImpl_GetAdapterDisplayMode ,
2004-10-05 04:14:06 +02:00
IWineD3DImpl_GetAdapterIdentifier ,
IWineD3DImpl_CheckDeviceMultiSampleType ,
IWineD3DImpl_CheckDepthStencilMatch ,
IWineD3DImpl_CheckDeviceType ,
2004-10-06 02:05:29 +02:00
IWineD3DImpl_CheckDeviceFormat ,
IWineD3DImpl_CheckDeviceFormatConversion ,
2004-10-07 06:22:21 +02:00
IWineD3DImpl_GetDeviceCaps ,
IWineD3DImpl_CreateDevice
2004-09-23 06:34:27 +02:00
} ;
2009-09-16 08:37:15 +02:00
static void STDMETHODCALLTYPE wined3d_null_wined3d_object_destroyed ( void * parent ) { }
const struct wined3d_parent_ops wined3d_null_parent_ops =
{
wined3d_null_wined3d_object_destroyed ,
} ;
2010-04-04 19:51:37 +02:00
HRESULT wined3d_init ( IWineD3DImpl * wined3d , UINT version , IUnknown * parent )
{
wined3d - > lpVtbl = & IWineD3D_Vtbl ;
wined3d - > dxVersion = version ;
wined3d - > ref = 1 ;
wined3d - > parent = parent ;
if ( ! InitAdapters ( wined3d ) )
{
WARN ( " Failed to initialize adapters. \n " ) ;
if ( version > 7 )
{
MESSAGE ( " Direct3D%u is not available without OpenGL. \n " , version ) ;
return E_FAIL ;
}
}
return WINED3D_OK ;
}