ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

directx.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2002-2004 Jason Edmeades
00003  * Copyright 2003-2004 Raphael Junqueira
00004  * Copyright 2004 Christian Costa
00005  * Copyright 2005 Oliver Stieber
00006  * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
00007  * Copyright 2009-2011 Henri Verbeet for CodeWeavers
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2.1 of the License, or (at your option) any later version.
00013  *
00014  * This library is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with this library; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00022  */
00023 
00024 #include "config.h"
00025 #include <stdio.h>
00026 #include "wined3d_private.h"
00027 
00028 WINE_DEFAULT_DEBUG_CHANNEL(d3d);
00029 WINE_DECLARE_DEBUG_CHANNEL(d3d_caps);
00030 
00031 #define WINE_DEFAULT_VIDMEM (64 * 1024 * 1024)
00032 
00033 /* The driver names reflect the lowest GPU supported
00034  * by a certain driver, so DRIVER_AMD_R300 supports
00035  * R3xx, R4xx and R5xx GPUs. */
00036 enum wined3d_display_driver
00037 {
00038     DRIVER_AMD_RAGE_128PRO,
00039     DRIVER_AMD_R100,
00040     DRIVER_AMD_R300,
00041     DRIVER_AMD_R600,
00042     DRIVER_INTEL_GMA800,
00043     DRIVER_INTEL_GMA900,
00044     DRIVER_INTEL_GMA950,
00045     DRIVER_INTEL_GMA3000,
00046     DRIVER_NVIDIA_TNT,
00047     DRIVER_NVIDIA_GEFORCE2MX,
00048     DRIVER_NVIDIA_GEFORCEFX,
00049     DRIVER_NVIDIA_GEFORCE6,
00050     DRIVER_UNKNOWN
00051 };
00052 
00053 enum wined3d_driver_model
00054 {
00055     DRIVER_MODEL_WIN9X,
00056     DRIVER_MODEL_NT40,
00057     DRIVER_MODEL_NT5X,
00058     DRIVER_MODEL_NT6X
00059 };
00060 
00061 enum wined3d_gl_vendor
00062 {
00063     GL_VENDOR_UNKNOWN,
00064     GL_VENDOR_APPLE,
00065     GL_VENDOR_FGLRX,
00066     GL_VENDOR_INTEL,
00067     GL_VENDOR_MESA,
00068     GL_VENDOR_NVIDIA,
00069 };
00070 
00071 /* The d3d device ID */
00072 static const GUID IID_D3DDEVICE_D3DUID = { 0xaeb2cdd4, 0x6e41, 0x43ea, { 0x94,0x1c,0x83,0x61,0xcc,0x76,0x07,0x81 } };
00073 
00074 /* Extension detection */
00075 static const struct
00076 {
00077     const char *extension_string;
00078     enum wined3d_gl_extension extension;
00079     DWORD version;
00080 }
00081 EXTENSION_MAP[] =
00082 {
00083     /* APPLE */
00084     {"GL_APPLE_client_storage",             APPLE_CLIENT_STORAGE,           0                           },
00085     {"GL_APPLE_fence",                      APPLE_FENCE,                    0                           },
00086     {"GL_APPLE_float_pixels",               APPLE_FLOAT_PIXELS,             0                           },
00087     {"GL_APPLE_flush_buffer_range",         APPLE_FLUSH_BUFFER_RANGE,       0                           },
00088     {"GL_APPLE_flush_render",               APPLE_FLUSH_RENDER,             0                           },
00089     {"GL_APPLE_ycbcr_422",                  APPLE_YCBCR_422,                0                           },
00090 
00091     /* ARB */
00092     {"GL_ARB_color_buffer_float",           ARB_COLOR_BUFFER_FLOAT,         0                           },
00093     {"GL_ARB_depth_buffer_float",           ARB_DEPTH_BUFFER_FLOAT,         0                           },
00094     {"GL_ARB_depth_clamp",                  ARB_DEPTH_CLAMP,                0                           },
00095     {"GL_ARB_depth_texture",                ARB_DEPTH_TEXTURE,              0                           },
00096     {"GL_ARB_draw_buffers",                 ARB_DRAW_BUFFERS,               0                           },
00097     {"GL_ARB_draw_elements_base_vertex",    ARB_DRAW_ELEMENTS_BASE_VERTEX,  0                           },
00098     {"GL_ARB_fragment_program",             ARB_FRAGMENT_PROGRAM,           0                           },
00099     {"GL_ARB_fragment_shader",              ARB_FRAGMENT_SHADER,            0                           },
00100     {"GL_ARB_framebuffer_object",           ARB_FRAMEBUFFER_OBJECT,         0                           },
00101     {"GL_ARB_geometry_shader4",             ARB_GEOMETRY_SHADER4,           0                           },
00102     {"GL_ARB_half_float_pixel",             ARB_HALF_FLOAT_PIXEL,           0                           },
00103     {"GL_ARB_half_float_vertex",            ARB_HALF_FLOAT_VERTEX,          0                           },
00104     {"GL_ARB_map_buffer_alignment",         ARB_MAP_BUFFER_ALIGNMENT,       0                           },
00105     {"GL_ARB_map_buffer_range",             ARB_MAP_BUFFER_RANGE,           0                           },
00106     {"GL_ARB_multisample",                  ARB_MULTISAMPLE,                0                           }, /* needs GLX_ARB_MULTISAMPLE as well */
00107     {"GL_ARB_multitexture",                 ARB_MULTITEXTURE,               0                           },
00108     {"GL_ARB_occlusion_query",              ARB_OCCLUSION_QUERY,            0                           },
00109     {"GL_ARB_pixel_buffer_object",          ARB_PIXEL_BUFFER_OBJECT,        0                           },
00110     {"GL_ARB_point_parameters",             ARB_POINT_PARAMETERS,           0                           },
00111     {"GL_ARB_point_sprite",                 ARB_POINT_SPRITE,               0                           },
00112     {"GL_ARB_provoking_vertex",             ARB_PROVOKING_VERTEX,           0                           },
00113     {"GL_ARB_shader_objects",               ARB_SHADER_OBJECTS,             0                           },
00114     {"GL_ARB_shader_texture_lod",           ARB_SHADER_TEXTURE_LOD,         0                           },
00115     {"GL_ARB_shading_language_100",         ARB_SHADING_LANGUAGE_100,       0                           },
00116     {"GL_ARB_shadow",                       ARB_SHADOW,                     0                           },
00117     {"GL_ARB_sync",                         ARB_SYNC,                       0                           },
00118     {"GL_ARB_texture_border_clamp",         ARB_TEXTURE_BORDER_CLAMP,       0                           },
00119     {"GL_ARB_texture_compression",          ARB_TEXTURE_COMPRESSION,        0                           },
00120     {"GL_ARB_texture_compression_rgtc",     ARB_TEXTURE_COMPRESSION_RGTC,   0                           },
00121     {"GL_ARB_texture_cube_map",             ARB_TEXTURE_CUBE_MAP,           0                           },
00122     {"GL_ARB_texture_env_add",              ARB_TEXTURE_ENV_ADD,            0                           },
00123     {"GL_ARB_texture_env_combine",          ARB_TEXTURE_ENV_COMBINE,        0                           },
00124     {"GL_ARB_texture_env_dot3",             ARB_TEXTURE_ENV_DOT3,           0                           },
00125     {"GL_ARB_texture_float",                ARB_TEXTURE_FLOAT,              0                           },
00126     {"GL_ARB_texture_mirrored_repeat",      ARB_TEXTURE_MIRRORED_REPEAT,    0                           },
00127     {"GL_ARB_texture_non_power_of_two",     ARB_TEXTURE_NON_POWER_OF_TWO,   MAKEDWORD_VERSION(2, 0)     },
00128     {"GL_ARB_texture_rectangle",            ARB_TEXTURE_RECTANGLE,          0                           },
00129     {"GL_ARB_texture_rg",                   ARB_TEXTURE_RG,                 0                           },
00130     {"GL_ARB_vertex_array_bgra",            ARB_VERTEX_ARRAY_BGRA,          0                           },
00131     {"GL_ARB_vertex_blend",                 ARB_VERTEX_BLEND,               0                           },
00132     {"GL_ARB_vertex_buffer_object",         ARB_VERTEX_BUFFER_OBJECT,       0                           },
00133     {"GL_ARB_vertex_program",               ARB_VERTEX_PROGRAM,             0                           },
00134     {"GL_ARB_vertex_shader",                ARB_VERTEX_SHADER,              0                           },
00135 
00136     /* ATI */
00137     {"GL_ATI_fragment_shader",              ATI_FRAGMENT_SHADER,            0                           },
00138     {"GL_ATI_separate_stencil",             ATI_SEPARATE_STENCIL,           0                           },
00139     {"GL_ATI_texture_compression_3dc",      ATI_TEXTURE_COMPRESSION_3DC,    0                           },
00140     {"GL_ATI_texture_env_combine3",         ATI_TEXTURE_ENV_COMBINE3,       0                           },
00141     {"GL_ATI_texture_mirror_once",          ATI_TEXTURE_MIRROR_ONCE,        0                           },
00142 
00143     /* EXT */
00144     {"GL_EXT_blend_color",                  EXT_BLEND_COLOR,                0                           },
00145     {"GL_EXT_blend_equation_separate",      EXT_BLEND_EQUATION_SEPARATE,    0                           },
00146     {"GL_EXT_blend_func_separate",          EXT_BLEND_FUNC_SEPARATE,        0                           },
00147     {"GL_EXT_blend_minmax",                 EXT_BLEND_MINMAX,               0                           },
00148     {"GL_EXT_blend_subtract",               EXT_BLEND_SUBTRACT,             0                           },
00149     {"GL_EXT_depth_bounds_test",            EXT_DEPTH_BOUNDS_TEST,          0                           },
00150     {"GL_EXT_draw_buffers2",                EXT_DRAW_BUFFERS2,              0                           },
00151     {"GL_EXT_fog_coord",                    EXT_FOG_COORD,                  0                           },
00152     {"GL_EXT_framebuffer_blit",             EXT_FRAMEBUFFER_BLIT,           0                           },
00153     {"GL_EXT_framebuffer_multisample",      EXT_FRAMEBUFFER_MULTISAMPLE,    0                           },
00154     {"GL_EXT_framebuffer_object",           EXT_FRAMEBUFFER_OBJECT,         0                           },
00155     {"GL_EXT_gpu_program_parameters",       EXT_GPU_PROGRAM_PARAMETERS,     0                           },
00156     {"GL_EXT_gpu_shader4",                  EXT_GPU_SHADER4,                0                           },
00157     {"GL_EXT_packed_depth_stencil",         EXT_PACKED_DEPTH_STENCIL,       0                           },
00158     {"GL_EXT_paletted_texture",             EXT_PALETTED_TEXTURE,           0                           },
00159     {"GL_EXT_point_parameters",             EXT_POINT_PARAMETERS,           0                           },
00160     {"GL_EXT_provoking_vertex",             EXT_PROVOKING_VERTEX,           0                           },
00161     {"GL_EXT_secondary_color",              EXT_SECONDARY_COLOR,            0                           },
00162     {"GL_EXT_stencil_two_side",             EXT_STENCIL_TWO_SIDE,           0                           },
00163     {"GL_EXT_stencil_wrap",                 EXT_STENCIL_WRAP,               0                           },
00164     {"GL_EXT_texture3D",                    EXT_TEXTURE3D,                  MAKEDWORD_VERSION(1, 2)     },
00165     {"GL_EXT_texture_compression_rgtc",     EXT_TEXTURE_COMPRESSION_RGTC,   0                           },
00166     {"GL_EXT_texture_compression_s3tc",     EXT_TEXTURE_COMPRESSION_S3TC,   0                           },
00167     {"GL_EXT_texture_env_add",              EXT_TEXTURE_ENV_ADD,            0                           },
00168     {"GL_EXT_texture_env_combine",          EXT_TEXTURE_ENV_COMBINE,        0                           },
00169     {"GL_EXT_texture_env_dot3",             EXT_TEXTURE_ENV_DOT3,           0                           },
00170     {"GL_EXT_texture_filter_anisotropic",   EXT_TEXTURE_FILTER_ANISOTROPIC, 0                           },
00171     {"GL_EXT_texture_lod_bias",             EXT_TEXTURE_LOD_BIAS,           0                           },
00172     {"GL_EXT_texture_sRGB",                 EXT_TEXTURE_SRGB,               0                           },
00173     {"GL_EXT_texture_sRGB_decode",          EXT_TEXTURE_SRGB_DECODE,        0                           },
00174     {"GL_EXT_vertex_array_bgra",            EXT_VERTEX_ARRAY_BGRA,          0                           },
00175 
00176     /* NV */
00177     {"GL_NV_depth_clamp",                   NV_DEPTH_CLAMP,                 0                           },
00178     {"GL_NV_fence",                         NV_FENCE,                       0                           },
00179     {"GL_NV_fog_distance",                  NV_FOG_DISTANCE,                0                           },
00180     {"GL_NV_fragment_program",              NV_FRAGMENT_PROGRAM,            0                           },
00181     {"GL_NV_fragment_program2",             NV_FRAGMENT_PROGRAM2,           0                           },
00182     {"GL_NV_fragment_program_option",       NV_FRAGMENT_PROGRAM_OPTION,     0                           },
00183     {"GL_NV_half_float",                    NV_HALF_FLOAT,                  0                           },
00184     {"GL_NV_light_max_exponent",            NV_LIGHT_MAX_EXPONENT,          0                           },
00185     {"GL_NV_point_sprite",                  NV_POINT_SPRITE,                0                           },
00186     {"GL_NV_register_combiners",            NV_REGISTER_COMBINERS,          0                           },
00187     {"GL_NV_register_combiners2",           NV_REGISTER_COMBINERS2,         0                           },
00188     {"GL_NV_texgen_reflection",             NV_TEXGEN_REFLECTION,           0                           },
00189     {"GL_NV_texture_env_combine4",          NV_TEXTURE_ENV_COMBINE4,        0                           },
00190     {"GL_NV_texture_shader",                NV_TEXTURE_SHADER,              0                           },
00191     {"GL_NV_texture_shader2",               NV_TEXTURE_SHADER2,             0                           },
00192     {"GL_NV_vertex_program",                NV_VERTEX_PROGRAM,              0                           },
00193     {"GL_NV_vertex_program1_1",             NV_VERTEX_PROGRAM1_1,           0                           },
00194     {"GL_NV_vertex_program2",               NV_VERTEX_PROGRAM2,             0                           },
00195     {"GL_NV_vertex_program2_option",        NV_VERTEX_PROGRAM2_OPTION,      0                           },
00196     {"GL_NV_vertex_program3",               NV_VERTEX_PROGRAM3,             0                           },
00197 
00198     /* SGI */
00199     {"GL_SGIS_generate_mipmap",             SGIS_GENERATE_MIPMAP,           0                           },
00200 };
00201 
00202 /**********************************************************
00203  * Utility functions follow
00204  **********************************************************/
00205 
00206 const struct min_lookup minMipLookup[] =
00207 {
00208     /* NONE         POINT                       LINEAR */
00209     {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* NONE */
00210     {{GL_NEAREST,   GL_NEAREST_MIPMAP_NEAREST,  GL_NEAREST_MIPMAP_LINEAR}}, /* POINT*/
00211     {{GL_LINEAR,    GL_LINEAR_MIPMAP_NEAREST,   GL_LINEAR_MIPMAP_LINEAR}},  /* LINEAR */
00212 };
00213 
00214 const struct min_lookup minMipLookup_noFilter[] =
00215 {
00216     /* NONE         POINT                       LINEAR */
00217     {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* NONE */
00218     {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* POINT */
00219     {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* LINEAR */
00220 };
00221 
00222 const struct min_lookup minMipLookup_noMip[] =
00223 {
00224     /* NONE         POINT                       LINEAR */
00225     {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* NONE */
00226     {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* POINT */
00227     {{GL_LINEAR,    GL_LINEAR,                  GL_LINEAR }},               /* LINEAR */
00228 };
00229 
00230 const GLenum magLookup[] =
00231 {
00232     /* NONE     POINT       LINEAR */
00233     GL_NEAREST, GL_NEAREST, GL_LINEAR,
00234 };
00235 
00236 const GLenum magLookup_noFilter[] =
00237 {
00238     /* NONE     POINT       LINEAR */
00239     GL_NEAREST, GL_NEAREST, GL_NEAREST,
00240 };
00241 
00242 /* drawStridedSlow attributes */
00243 glAttribFunc position_funcs[WINED3D_FFP_EMIT_COUNT];
00244 glAttribFunc diffuse_funcs[WINED3D_FFP_EMIT_COUNT];
00245 glAttribFunc specular_func_3ubv;
00246 glAttribFunc specular_funcs[WINED3D_FFP_EMIT_COUNT];
00247 glAttribFunc normal_funcs[WINED3D_FFP_EMIT_COUNT];
00248 glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT];
00249 
00256 struct wined3d_fake_gl_ctx
00257 {
00258     HDC dc;
00259     HWND wnd;
00260     HGLRC gl_ctx;
00261     HDC restore_dc;
00262     HGLRC restore_gl_ctx;
00263 };
00264 
00265 static void WineD3D_ReleaseFakeGLContext(const struct wined3d_fake_gl_ctx *ctx)
00266 {
00267     TRACE_(d3d_caps)("Destroying fake GL context.\n");
00268 
00269     if (!pwglMakeCurrent(NULL, NULL))
00270     {
00271         ERR_(d3d_caps)("Failed to disable fake GL context.\n");
00272     }
00273 #if 0
00274     if (!pwglDeleteContext(ctx->gl_ctx))
00275     {
00276         DWORD err = GetLastError();
00277         ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx->gl_ctx, err);
00278     }
00279 #endif
00280     ReleaseDC(ctx->wnd, ctx->dc);
00281     DestroyWindow(ctx->wnd);
00282 
00283     if (ctx->restore_gl_ctx && !pwglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx))
00284     {
00285         ERR_(d3d_caps)("Failed to restore previous GL context.\n");
00286     }
00287 }
00288 
00289 /* Do not call while under the GL lock. */
00290 static BOOL WineD3D_CreateFakeGLContext(struct wined3d_fake_gl_ctx *ctx)
00291 {
00292     PIXELFORMATDESCRIPTOR pfd;
00293     int iPixelFormat;
00294 
00295     TRACE("getting context...\n");
00296 
00297     ctx->restore_dc = pwglGetCurrentDC();
00298     ctx->restore_gl_ctx = pwglGetCurrentContext();
00299 
00300     /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes. */
00301     ctx->wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window",
00302             WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL);
00303     if (!ctx->wnd)
00304     {
00305         ERR_(d3d_caps)("Failed to create a window.\n");
00306         goto fail;
00307     }
00308 
00309     ctx->dc = GetDC(ctx->wnd);
00310     if (!ctx->dc)
00311     {
00312         ERR_(d3d_caps)("Failed to get a DC.\n");
00313         goto fail;
00314     }
00315 
00316     /* PixelFormat selection */
00317     ZeroMemory(&pfd, sizeof(pfd));
00318     pfd.nSize = sizeof(pfd);
00319     pfd.nVersion = 1;
00320     pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW; /* PFD_GENERIC_ACCELERATED */
00321     pfd.iPixelType = PFD_TYPE_RGBA;
00322     pfd.cColorBits = 32;
00323     pfd.iLayerType = PFD_MAIN_PLANE;
00324 
00325     iPixelFormat = ChoosePixelFormat(ctx->dc, &pfd);
00326     if (!iPixelFormat)
00327     {
00328         /* If this happens something is very wrong as ChoosePixelFormat barely fails. */
00329         ERR_(d3d_caps)("Can't find a suitable iPixelFormat.\n");
00330         goto fail;
00331     }
00332     DescribePixelFormat(ctx->dc, iPixelFormat, sizeof(pfd), &pfd);
00333     SetPixelFormat(ctx->dc, iPixelFormat, &pfd);
00334 
00335     /* Create a GL context. */
00336     ctx->gl_ctx = pwglCreateContext(ctx->dc);
00337     if (!ctx->gl_ctx)
00338     {
00339         WARN_(d3d_caps)("Error creating default context for capabilities initialization.\n");
00340         goto fail;
00341     }
00342 
00343     /* Make it the current GL context. */
00344     if (!pwglMakeCurrent(ctx->dc, ctx->gl_ctx))
00345     {
00346         ERR_(d3d_caps)("Failed to make fake GL context current.\n");
00347         goto fail;
00348     }
00349 
00350     return TRUE;
00351 
00352 fail:
00353     if (ctx->gl_ctx) pwglDeleteContext(ctx->gl_ctx);
00354     ctx->gl_ctx = NULL;
00355     if (ctx->dc) ReleaseDC(ctx->wnd, ctx->dc);
00356     ctx->dc = NULL;
00357     if (ctx->wnd) DestroyWindow(ctx->wnd);
00358     ctx->wnd = NULL;
00359     if (ctx->restore_gl_ctx && !pwglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx))
00360     {
00361         ERR_(d3d_caps)("Failed to restore previous GL context.\n");
00362     }
00363 
00364     return FALSE;
00365 }
00366 
00367 /* Adjust the amount of used texture memory */
00368 unsigned int adapter_adjust_memory(struct wined3d_adapter *adapter, int amount)
00369 {
00370     adapter->UsedTextureRam += amount;
00371     TRACE("Adjusted adapter memory by %d to %d.\n", amount, adapter->UsedTextureRam);
00372     return adapter->UsedTextureRam;
00373 }
00374 
00375 static void wined3d_adapter_cleanup(struct wined3d_adapter *adapter)
00376 {
00377     HeapFree(GetProcessHeap(), 0, adapter->gl_info.formats);
00378     HeapFree(GetProcessHeap(), 0, adapter->cfgs);
00379 }
00380 
00381 ULONG CDECL wined3d_incref(struct wined3d *wined3d)
00382 {
00383     ULONG refcount = InterlockedIncrement(&wined3d->ref);
00384 
00385     TRACE("%p increasing refcount to %u.\n", wined3d, refcount);
00386 
00387     return refcount;
00388 }
00389 
00390 ULONG CDECL wined3d_decref(struct wined3d *wined3d)
00391 {
00392     ULONG refcount = InterlockedDecrement(&wined3d->ref);
00393 
00394     TRACE("%p decreasing refcount to %u.\n", wined3d, refcount);
00395 
00396     if (!refcount)
00397     {
00398         unsigned int i;
00399 
00400         for (i = 0; i < wined3d->adapter_count; ++i)
00401         {
00402             wined3d_adapter_cleanup(&wined3d->adapters[i]);
00403         }
00404         HeapFree(GetProcessHeap(), 0, wined3d);
00405     }
00406 
00407     return refcount;
00408 }
00409 
00410 /* GL locking is done by the caller */
00411 static inline BOOL test_arb_vs_offset_limit(const struct wined3d_gl_info *gl_info)
00412 {
00413     GLuint prog;
00414     BOOL ret = FALSE;
00415     const char *testcode =
00416         "!!ARBvp1.0\n"
00417         "PARAM C[66] = { program.env[0..65] };\n"
00418         "ADDRESS A0;"
00419         "PARAM zero = {0.0, 0.0, 0.0, 0.0};\n"
00420         "ARL A0.x, zero.x;\n"
00421         "MOV result.position, C[A0.x + 65];\n"
00422         "END\n";
00423 
00424     while(glGetError());
00425     GL_EXTCALL(glGenProgramsARB(1, &prog));
00426     if(!prog) {
00427         ERR("Failed to create an ARB offset limit test program\n");
00428     }
00429     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
00430     GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
00431                                   strlen(testcode), testcode));
00432     if (glGetError())
00433     {
00434         TRACE("OpenGL implementation does not allow indirect addressing offsets > 63\n");
00435         TRACE("error: %s\n", debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
00436         ret = TRUE;
00437     } else TRACE("OpenGL implementation allows offsets > 63\n");
00438 
00439     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
00440     GL_EXTCALL(glDeleteProgramsARB(1, &prog));
00441     checkGLcall("ARB vp offset limit test cleanup");
00442 
00443     return ret;
00444 }
00445 
00446 static DWORD ver_for_ext(enum wined3d_gl_extension ext)
00447 {
00448     unsigned int i;
00449     for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
00450         if(EXTENSION_MAP[i].extension == ext) {
00451             return EXTENSION_MAP[i].version;
00452         }
00453     }
00454     return 0;
00455 }
00456 
00457 static BOOL match_amd_r300_to_500(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
00458         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
00459 {
00460     if (card_vendor != HW_VENDOR_AMD) return FALSE;
00461     if (device == CARD_AMD_RADEON_9500) return TRUE;
00462     if (device == CARD_AMD_RADEON_X700) return TRUE;
00463     if (device == CARD_AMD_RADEON_X1600) return TRUE;
00464     return FALSE;
00465 }
00466 
00467 static BOOL match_geforce5(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
00468         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
00469 {
00470     if (card_vendor == HW_VENDOR_NVIDIA)
00471     {
00472         if (device == CARD_NVIDIA_GEFORCEFX_5200 ||
00473             device == CARD_NVIDIA_GEFORCEFX_5600 ||
00474             device == CARD_NVIDIA_GEFORCEFX_5800)
00475         {
00476             return TRUE;
00477         }
00478     }
00479     return FALSE;
00480 }
00481 
00482 static BOOL match_apple(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
00483         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
00484 {
00485     /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
00486      * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
00487      * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
00488      *
00489      * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
00490      * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
00491      * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
00492      * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
00493      * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
00494      * the chance that other implementations support them is rather small since Win32 QuickTime uses
00495      * DirectDraw, not OpenGL.
00496      *
00497      * This test has been moved into wined3d_guess_gl_vendor()
00498      */
00499     if (gl_vendor == GL_VENDOR_APPLE)
00500     {
00501         return TRUE;
00502     }
00503     return FALSE;
00504 }
00505 
00506 /* Context activation is done by the caller. */
00507 static void test_pbo_functionality(struct wined3d_gl_info *gl_info)
00508 {
00509     /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
00510      * but glTexSubImage from a PBO fails miserably, with the first line repeated over
00511      * all the texture. This function detects this bug by its symptom and disables PBOs
00512      * if the test fails.
00513      *
00514      * The test uploads a 4x4 texture via the PBO in the "native" format GL_BGRA,
00515      * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use
00516      * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data
00517      * read back is compared to the original. If they are equal PBOs are assumed to work,
00518      * otherwise the PBO extension is disabled. */
00519     GLuint texture, pbo;
00520     static const unsigned int pattern[] =
00521     {
00522         0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000,
00523         0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff,
00524         0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
00525         0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
00526     };
00527     unsigned int check[sizeof(pattern) / sizeof(pattern[0])];
00528 
00529     /* No PBO -> No point in testing them. */
00530     if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) return;
00531 
00532     ENTER_GL();
00533 
00534     while (glGetError());
00535     glGenTextures(1, &texture);
00536     glBindTexture(GL_TEXTURE_2D, texture);
00537 
00538     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
00539     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
00540     checkGLcall("Specifying the PBO test texture");
00541 
00542     GL_EXTCALL(glGenBuffersARB(1, &pbo));
00543     GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo));
00544     GL_EXTCALL(glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, sizeof(pattern), pattern, GL_STREAM_DRAW_ARB));
00545     checkGLcall("Specifying the PBO test pbo");
00546 
00547     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
00548     checkGLcall("Loading the PBO test texture");
00549 
00550     GL_EXTCALL(glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0));
00551     LEAVE_GL();
00552 
00553     wglFinish(); /* just to be sure */
00554 
00555     memset(check, 0, sizeof(check));
00556     ENTER_GL();
00557     glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check);
00558     checkGLcall("Reading back the PBO test texture");
00559 
00560     glDeleteTextures(1, &texture);
00561     GL_EXTCALL(glDeleteBuffersARB(1, &pbo));
00562     checkGLcall("PBO test cleanup");
00563 
00564     LEAVE_GL();
00565 
00566     if (memcmp(check, pattern, sizeof(check)))
00567     {
00568         WARN_(d3d_caps)("PBO test failed, read back data doesn't match original.\n");
00569         WARN_(d3d_caps)("Disabling PBOs. This may result in slower performance.\n");
00570         gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE;
00571     }
00572     else
00573     {
00574         TRACE_(d3d_caps)("PBO test successful.\n");
00575     }
00576 }
00577 
00578 static BOOL match_apple_intel(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
00579         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
00580 {
00581     return (card_vendor == HW_VENDOR_INTEL) && (gl_vendor == GL_VENDOR_APPLE);
00582 }
00583 
00584 static BOOL match_apple_nonr500ati(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
00585         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
00586 {
00587     if (gl_vendor != GL_VENDOR_APPLE) return FALSE;
00588     if (card_vendor != HW_VENDOR_AMD) return FALSE;
00589     if (device == CARD_AMD_RADEON_X1600) return FALSE;
00590     return TRUE;
00591 }
00592 
00593 static BOOL match_dx10_capable(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
00594         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
00595 {
00596     /* DX9 cards support 40 single float varyings in hardware, most drivers report 32. ATI misreports
00597      * 44 varyings. So assume that if we have more than 44 varyings we have a dx10 card.
00598      * This detection is for the gl_ClipPos varying quirk. If a d3d9 card really supports more than 44
00599      * varyings and we subtract one in dx9 shaders its not going to hurt us because the dx9 limit is
00600      * hardcoded
00601      *
00602      * dx10 cards usually have 64 varyings */
00603     return gl_info->limits.glsl_varyings > 44;
00604 }
00605 
00606 static BOOL match_not_dx10_capable(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
00607         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
00608 {
00609     return !match_dx10_capable(gl_info, gl_renderer, gl_vendor, card_vendor, device);
00610 }
00611 
00612 /* A GL context is provided by the caller */
00613 static BOOL match_allows_spec_alpha(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
00614         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
00615 {
00616     GLenum error;
00617     DWORD data[16];
00618 
00619     if (!gl_info->supported[EXT_SECONDARY_COLOR]) return FALSE;
00620 
00621     ENTER_GL();
00622     while(glGetError());
00623     GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE, 4, data);
00624     error = glGetError();
00625     LEAVE_GL();
00626 
00627     if(error == GL_NO_ERROR)
00628     {
00629         TRACE("GL Implementation accepts 4 component specular color pointers\n");
00630         return TRUE;
00631     }
00632     else
00633     {
00634         TRACE("GL implementation does not accept 4 component specular colors, error %s\n",
00635               debug_glerror(error));
00636         return FALSE;
00637     }
00638 }
00639 
00640 /* A GL context is provided by the caller */
00641 static BOOL match_broken_nv_clip(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
00642         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
00643 {
00644     GLuint prog;
00645     BOOL ret = FALSE;
00646     GLint pos;
00647     const char *testcode =
00648         "!!ARBvp1.0\n"
00649         "OPTION NV_vertex_program2;\n"
00650         "MOV result.clip[0], 0.0;\n"
00651         "MOV result.position, 0.0;\n"
00652         "END\n";
00653 
00654     if (!gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]) return FALSE;
00655 
00656     ENTER_GL();
00657     while(glGetError());
00658 
00659     GL_EXTCALL(glGenProgramsARB(1, &prog));
00660     if(!prog)
00661     {
00662         ERR("Failed to create the NVvp clip test program\n");
00663         LEAVE_GL();
00664         return FALSE;
00665     }
00666     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
00667     GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
00668                                   strlen(testcode), testcode));
00669     glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
00670     if(pos != -1)
00671     {
00672         WARN("GL_NV_vertex_program2_option result.clip[] test failed\n");
00673         TRACE("error: %s\n", debugstr_a((const char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
00674         ret = TRUE;
00675         while(glGetError());
00676     }
00677     else TRACE("GL_NV_vertex_program2_option result.clip[] test passed\n");
00678 
00679     GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
00680     GL_EXTCALL(glDeleteProgramsARB(1, &prog));
00681     checkGLcall("GL_NV_vertex_program2_option result.clip[] test cleanup");
00682 
00683     LEAVE_GL();
00684     return ret;
00685 }
00686 
00687 /* Context activation is done by the caller. */
00688 static BOOL match_fbo_tex_update(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
00689         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
00690 {
00691     char data[4 * 4 * 4];
00692     GLuint tex, fbo;
00693     GLenum status;
00694 
00695     if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return FALSE;
00696 
00697     memset(data, 0xcc, sizeof(data));
00698 
00699     ENTER_GL();
00700 
00701     glGenTextures(1, &tex);
00702     glBindTexture(GL_TEXTURE_2D, tex);
00703     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00704     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00705     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
00706     checkGLcall("glTexImage2D");
00707 
00708     gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
00709     gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
00710     gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
00711     checkGLcall("glFramebufferTexture2D");
00712 
00713     status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
00714     if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status);
00715     checkGLcall("glCheckFramebufferStatus");
00716 
00717     memset(data, 0x11, sizeof(data));
00718     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
00719     checkGLcall("glTexSubImage2D");
00720 
00721     glClearColor(0.996f, 0.729f, 0.745f, 0.792f);
00722     glClear(GL_COLOR_BUFFER_BIT);
00723     checkGLcall("glClear");
00724 
00725     glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
00726     checkGLcall("glGetTexImage");
00727 
00728     gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
00729     gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
00730     glBindTexture(GL_TEXTURE_2D, 0);
00731     checkGLcall("glBindTexture");
00732 
00733     gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
00734     glDeleteTextures(1, &tex);
00735     checkGLcall("glDeleteTextures");
00736 
00737     LEAVE_GL();
00738 
00739     return *(DWORD *)data == 0x11111111;
00740 }
00741 
00742 /* Context activation is done by the caller. */
00743 static BOOL match_broken_rgba16(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
00744         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
00745 {
00746     /* GL_RGBA16 uses GL_RGBA8 internally on Geforce 7 and older cards.
00747      * This leads to graphical bugs in Half Life 2 and Unreal engine games. */
00748     GLuint tex;
00749     GLint size;
00750 
00751     ENTER_GL();
00752 
00753     glGenTextures(1, &tex);
00754     glBindTexture(GL_TEXTURE_2D, tex);
00755     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT, NULL);
00756     checkGLcall("glTexImage2D");
00757 
00758     glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &size);
00759     checkGLcall("glGetTexLevelParameteriv");
00760     TRACE("Real color depth is %d\n", size);
00761 
00762     glBindTexture(GL_TEXTURE_2D, 0);
00763     checkGLcall("glBindTexture");
00764     glDeleteTextures(1, &tex);
00765     checkGLcall("glDeleteTextures");
00766 
00767     LEAVE_GL();
00768 
00769     return size < 16;
00770 }
00771 
00772 static BOOL match_fglrx(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
00773         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
00774 {
00775     return gl_vendor == GL_VENDOR_FGLRX;
00776 }
00777 
00778 static void quirk_arb_constants(struct wined3d_gl_info *gl_info)
00779 {
00780     TRACE_(d3d_caps)("Using ARB vs constant limit(=%u) for GLSL.\n", gl_info->limits.arb_vs_native_constants);
00781     gl_info->limits.glsl_vs_float_constants = gl_info->limits.arb_vs_native_constants;
00782     TRACE_(d3d_caps)("Using ARB ps constant limit(=%u) for GLSL.\n", gl_info->limits.arb_ps_native_constants);
00783     gl_info->limits.glsl_ps_float_constants = gl_info->limits.arb_ps_native_constants;
00784 }
00785 
00786 static void quirk_apple_glsl_constants(struct wined3d_gl_info *gl_info)
00787 {
00788     quirk_arb_constants(gl_info);
00789     /* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms.
00790      * Beyond that the general uniform isn't optimal, so reserve a number of uniforms. 12 vec4's should
00791      * allow 48 different offsets or other helper immediate values. */
00792     TRACE_(d3d_caps)("Reserving 12 GLSL constants for compiler private use.\n");
00793     gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12);
00794 }
00795 
00796 static void quirk_amd_dx9(struct wined3d_gl_info *gl_info)
00797 {
00798     /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
00799      * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
00800      * If real NP2 textures are used, the driver falls back to software. We could just remove the
00801      * extension and use GL_ARB_texture_rectangle instead, but texture_rectangle is inconvenient
00802      * due to the non-normalized texture coordinates. Thus set an internal extension flag,
00803      * GL_WINE_normalized_texrect, which signals the code that it can use non power of two textures
00804      * as per GL_ARB_texture_non_power_of_two, but has to stick to the texture_rectangle limits.
00805      *
00806      * fglrx doesn't advertise GL_ARB_texture_non_power_of_two, but it advertises opengl 2.0 which
00807      * has this extension promoted to core. The extension loading code sets this extension supported
00808      * due to that, so this code works on fglrx as well. */
00809     if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
00810     {
00811         TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing.\n");
00812         gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
00813         gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] = TRUE;
00814     }
00815 }
00816 
00817 static void quirk_no_np2(struct wined3d_gl_info *gl_info)
00818 {
00819     /*  The nVidia GeForceFX series reports OpenGL 2.0 capabilities with the latest drivers versions, but
00820      *  doesn't explicitly advertise the ARB_tex_npot extension in the GL extension string.
00821      *  This usually means that ARB_tex_npot is supported in hardware as long as the application is staying
00822      *  within the limits enforced by the ARB_texture_rectangle extension. This however is not true for the
00823      *  FX series, which instantly falls back to a slower software path as soon as ARB_tex_npot is used.
00824      *  We therefore completely remove ARB_tex_npot from the list of supported extensions.
00825      *
00826      *  Note that wine_normalized_texrect can't be used in this case because internally it uses ARB_tex_npot,
00827      *  triggering the software fallback. There is not much we can do here apart from disabling the
00828      *  software-emulated extension and reenable ARB_tex_rect (which was previously disabled
00829      *  in wined3d_adapter_init_gl_caps).
00830      *  This fixup removes performance problems on both the FX 5900 and FX 5700 (e.g. for framebuffer
00831      *  post-processing effects in the game "Max Payne 2").
00832      *  The behaviour can be verified through a simple test app attached in bugreport #14724. */
00833     TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing.\n");
00834     gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
00835     gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
00836 }
00837 
00838 static void quirk_texcoord_w(struct wined3d_gl_info *gl_info)
00839 {
00840     /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
00841      * with fixed function fragment processing. Ideally this flag should be detected with a test shader
00842      * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
00843      * do not like vertex shaders in feedback mode and return an error, even though it should be valid
00844      * according to the spec.
00845      *
00846      * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
00847      * makes the shader slower and eats instruction slots which should be available to the d3d app.
00848      *
00849      * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
00850      * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
00851      * this workaround is activated on cards that do not need it, it won't break things, just affect
00852      * performance negatively. */
00853     TRACE("Enabling vertex texture coord fixes in vertex shaders.\n");
00854     gl_info->quirks |= WINED3D_QUIRK_SET_TEXCOORD_W;
00855 }
00856 
00857 static void quirk_clip_varying(struct wined3d_gl_info *gl_info)
00858 {
00859     gl_info->quirks |= WINED3D_QUIRK_GLSL_CLIP_VARYING;
00860 }
00861 
00862 static void quirk_allows_specular_alpha(struct wined3d_gl_info *gl_info)
00863 {
00864     gl_info->quirks |= WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA;
00865 }
00866 
00867 static void quirk_disable_nvvp_clip(struct wined3d_gl_info *gl_info)
00868 {
00869     gl_info->quirks |= WINED3D_QUIRK_NV_CLIP_BROKEN;
00870 }
00871 
00872 static void quirk_fbo_tex_update(struct wined3d_gl_info *gl_info)
00873 {
00874     gl_info->quirks |= WINED3D_QUIRK_FBO_TEX_UPDATE;
00875 }
00876 
00877 static void quirk_broken_rgba16(struct wined3d_gl_info *gl_info)
00878 {
00879     gl_info->quirks |= WINED3D_QUIRK_BROKEN_RGBA16;
00880 }
00881 
00882 static void quirk_infolog_spam(struct wined3d_gl_info *gl_info)
00883 {
00884     gl_info->quirks |= WINED3D_QUIRK_INFO_LOG_SPAM;
00885 }
00886 
00887 static void quirk_limited_tex_filtering(struct wined3d_gl_info *gl_info)
00888 {
00889     /* Nvidia GeForce 6xxx and 7xxx support accelerated VTF only on a few
00890        selected texture formats. They are apparently the only DX9 class GPUs
00891        supporting VTF.
00892        Also, DX9-era GPUs are somewhat limited with float textures
00893        filtering and blending. */
00894     gl_info->quirks |= WINED3D_QUIRK_LIMITED_TEX_FILTERING;
00895 }
00896 
00897 struct driver_quirk
00898 {
00899     BOOL (*match)(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
00900             enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device);
00901     void (*apply)(struct wined3d_gl_info *gl_info);
00902     const char *description;
00903 };
00904 
00905 static const struct driver_quirk quirk_table[] =
00906 {
00907     {
00908         match_amd_r300_to_500,
00909         quirk_amd_dx9,
00910         "AMD normalized texrect quirk"
00911     },
00912     /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
00913      * used it falls back to software. While the compiler can detect if the shader uses all declared
00914      * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
00915      * using relative addressing falls back to software.
00916      *
00917      * ARB vp gives the correct amount of uniforms, so use it instead of GLSL. */
00918     {
00919         match_apple,
00920         quirk_apple_glsl_constants,
00921         "Apple GLSL uniform override"
00922     },
00923     {
00924         match_geforce5,
00925         quirk_no_np2,
00926         "Geforce 5 NP2 disable"
00927     },
00928     {
00929         match_apple_intel,
00930         quirk_texcoord_w,
00931         "Init texcoord .w for Apple Intel GPU driver"
00932     },
00933     {
00934         match_apple_nonr500ati,
00935         quirk_texcoord_w,
00936         "Init texcoord .w for Apple ATI >= r600 GPU driver"
00937     },
00938     {
00939         match_dx10_capable,
00940         quirk_clip_varying,
00941         "Reserved varying for gl_ClipPos"
00942     },
00943     {
00944         /* GL_EXT_secondary_color does not allow 4 component secondary colors, but most
00945          * GL implementations accept it. The Mac GL is the only implementation known to
00946          * reject it.
00947          *
00948          * If we can pass 4 component specular colors, do it, because (a) we don't have
00949          * to screw around with the data, and (b) the D3D fixed function vertex pipeline
00950          * passes specular alpha to the pixel shader if any is used. Otherwise the
00951          * specular alpha is used to pass the fog coordinate, which we pass to opengl
00952          * via GL_EXT_fog_coord.
00953          */
00954         match_allows_spec_alpha,
00955         quirk_allows_specular_alpha,
00956         "Allow specular alpha quirk"
00957     },
00958     {
00959         match_broken_nv_clip,
00960         quirk_disable_nvvp_clip,
00961         "Apple NV_vertex_program clip bug quirk"
00962     },
00963     {
00964         match_fbo_tex_update,
00965         quirk_fbo_tex_update,
00966         "FBO rebind for attachment updates"
00967     },
00968     {
00969         match_broken_rgba16,
00970         quirk_broken_rgba16,
00971         "True RGBA16 is not available"
00972     },
00973     {
00974         match_fglrx,
00975         quirk_infolog_spam,
00976         "Not printing GLSL infolog"
00977     },
00978     {
00979         match_not_dx10_capable,
00980         quirk_limited_tex_filtering,
00981         "Texture filtering, blending and VTF support is limited"
00982     },
00983 };
00984 
00985 /* Certain applications (Steam) complain if we report an outdated driver version. In general,
00986  * reporting a driver version is moot because we are not the Windows driver, and we have different
00987  * bugs, features, etc.
00988  *
00989  * The driver version has the form "x.y.z.w".
00990  *
00991  * "x" is the Windows version the driver is meant for:
00992  * 4 -> 95/98/NT4
00993  * 5 -> 2000
00994  * 6 -> 2000/XP
00995  * 7 -> Vista
00996  * 8 -> Win 7
00997  *
00998  * "y" is the maximum Direct3D version the driver supports.
00999  * y  -> d3d version mapping:
01000  * 11 -> d3d6
01001  * 12 -> d3d7
01002  * 13 -> d3d8
01003  * 14 -> d3d9
01004  * 15 -> d3d10
01005  * 16 -> d3d10.1
01006  * 17 -> d3d11
01007  *
01008  * "z" is the subversion number.
01009  *
01010  * "w" is the vendor specific driver build number.
01011  */
01012 
01013 struct driver_version_information
01014 {
01015     enum wined3d_display_driver driver;
01016     enum wined3d_driver_model driver_model;
01017     const char *driver_name;            /* name of Windows driver */
01018     WORD version;                       /* version word ('y'), contained in low word of DriverVersion.HighPart */
01019     WORD subversion;                    /* subversion word ('z'), contained in high word of DriverVersion.LowPart */
01020     WORD build;                         /* build number ('w'), contained in low word of DriverVersion.LowPart */
01021 };
01022 
01023 /* The driver version table contains driver information for different devices on several OS versions. */
01024 static const struct driver_version_information driver_version_table[] =
01025 {
01026     /* AMD
01027      * - Radeon HD2x00 (R600) and up supported by current drivers.
01028      * - Radeon 9500 (R300) - X1*00 (R5xx) supported up to Catalyst 9.3 (Linux) and 10.2 (XP/Vista/Win7)
01029      * - Radeon 7xxx (R100) - 9250 (RV250) supported up to Catalyst 6.11 (XP)
01030      * - Rage 128 supported up to XP, latest official build 6.13.3279 dated October 2001 */
01031     {DRIVER_AMD_RAGE_128PRO,    DRIVER_MODEL_NT5X,  "ati2dvaa.dll", 13, 3279,  0},
01032     {DRIVER_AMD_R100,           DRIVER_MODEL_NT5X,  "ati2dvag.dll", 14, 10, 6614},
01033     {DRIVER_AMD_R300,           DRIVER_MODEL_NT5X,  "ati2dvag.dll", 14, 10, 6764},
01034     {DRIVER_AMD_R600,           DRIVER_MODEL_NT5X,  "ati2dvag.dll", 14, 10, 8681},
01035     {DRIVER_AMD_R300,           DRIVER_MODEL_NT6X,  "atiumdag.dll", 14, 10, 741 },
01036     {DRIVER_AMD_R600,           DRIVER_MODEL_NT6X,  "atiumdag.dll", 14, 10, 741 },
01037 
01038     /* Intel
01039      * The drivers are unified but not all versions support all GPUs. At some point the 2k/xp
01040      * drivers used ialmrnt5.dll for GMA800/GMA900 but at some point the file was renamed to
01041      * igxprd32.dll but the GMA800 driver was never updated. */
01042     {DRIVER_INTEL_GMA800,       DRIVER_MODEL_NT5X,  "ialmrnt5.dll", 14, 10, 3889},
01043     {DRIVER_INTEL_GMA900,       DRIVER_MODEL_NT5X,  "igxprd32.dll", 14, 10, 4764},
01044     {DRIVER_INTEL_GMA950,       DRIVER_MODEL_NT5X,  "igxprd32.dll", 14, 10, 4926},
01045     {DRIVER_INTEL_GMA3000,      DRIVER_MODEL_NT5X,  "igxprd32.dll", 14, 10, 5218},
01046     {DRIVER_INTEL_GMA950,       DRIVER_MODEL_NT6X,  "igdumd32.dll", 14, 10, 1504},
01047     {DRIVER_INTEL_GMA3000,      DRIVER_MODEL_NT6X,  "igdumd32.dll", 15, 10, 1666},
01048 
01049     /* Nvidia
01050      * - Geforce6 and newer cards are supported by the current driver (197.x) on XP-Win7
01051      * - GeforceFX support is up to 173.x on <= XP
01052      * - Geforce2MX/3/4 up to 96.x on <= XP
01053      * - TNT/Geforce1/2 up to 71.x on <= XP
01054      * All version numbers used below are from the Linux nvidia drivers. */
01055     {DRIVER_NVIDIA_TNT,         DRIVER_MODEL_NT5X,  "nv4_disp.dll", 14, 10, 7186},
01056     {DRIVER_NVIDIA_GEFORCE2MX,  DRIVER_MODEL_NT5X,  "nv4_disp.dll", 14, 10, 9371},
01057     {DRIVER_NVIDIA_GEFORCEFX,   DRIVER_MODEL_NT5X,  "nv4_disp.dll", 14, 11, 7516},
01058     {DRIVER_NVIDIA_GEFORCE6,    DRIVER_MODEL_NT5X,  "nv4_disp.dll", 15, 12, 6658},
01059     {DRIVER_NVIDIA_GEFORCE6,    DRIVER_MODEL_NT6X,  "nvd3dum.dll",  15, 12, 6658},
01060 };
01061 
01062 struct gpu_description
01063 {
01064     WORD vendor;                    /* reported PCI card vendor ID  */
01065     WORD card;                      /* reported PCI card device ID  */
01066     const char *description;        /* Description of the card e.g. NVIDIA RIVA TNT */
01067     enum wined3d_display_driver driver;
01068     unsigned int vidmem;
01069 };
01070 
01071 /* The amount of video memory stored in the gpu description table is the minimum amount of video memory
01072  * found on a board containing a specific GPU. */
01073 static const struct gpu_description gpu_description_table[] =
01074 {
01075     /* Nvidia cards */
01076     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_RIVA_TNT,           "NVIDIA RIVA TNT",                  DRIVER_NVIDIA_TNT,       16  },
01077     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_RIVA_TNT2,          "NVIDIA RIVA TNT2/TNT2 Pro",        DRIVER_NVIDIA_TNT,       32  },
01078     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE,            "NVIDIA GeForce 256",               DRIVER_NVIDIA_TNT,       32  },
01079     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE2,           "NVIDIA GeForce2 GTS/GeForce2 Pro", DRIVER_NVIDIA_TNT,       32  },
01080     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE2_MX,        "NVIDIA GeForce2 MX/MX 400",        DRIVER_NVIDIA_GEFORCE2MX,32  },
01081     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE3,           "NVIDIA GeForce3",                  DRIVER_NVIDIA_GEFORCE2MX,64  },
01082     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE4_MX,        "NVIDIA GeForce4 MX 460",           DRIVER_NVIDIA_GEFORCE2MX,64  },
01083     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE4_TI4200,    "NVIDIA GeForce4 Ti 4200",          DRIVER_NVIDIA_GEFORCE2MX,64, },
01084     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5200,     "NVIDIA GeForce FX 5200",           DRIVER_NVIDIA_GEFORCEFX, 64  },
01085     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5600,     "NVIDIA GeForce FX 5600",           DRIVER_NVIDIA_GEFORCEFX, 128 },
01086     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5800,     "NVIDIA GeForce FX 5800",           DRIVER_NVIDIA_GEFORCEFX, 256 },
01087     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6200,       "NVIDIA GeForce 6200",              DRIVER_NVIDIA_GEFORCE6,  64  },
01088     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6600GT,     "NVIDIA GeForce 6600 GT",           DRIVER_NVIDIA_GEFORCE6,  128 },
01089     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6800,       "NVIDIA GeForce 6800",              DRIVER_NVIDIA_GEFORCE6,  128 },
01090     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7300,       "NVIDIA GeForce Go 7300",           DRIVER_NVIDIA_GEFORCE6,  256 },
01091     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7400,       "NVIDIA GeForce Go 7400",           DRIVER_NVIDIA_GEFORCE6,  256 },
01092     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7600,       "NVIDIA GeForce 7600 GT",           DRIVER_NVIDIA_GEFORCE6,  256 },
01093     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7800GT,     "NVIDIA GeForce 7800 GT",           DRIVER_NVIDIA_GEFORCE6,  256 },
01094     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8300GS,     "NVIDIA GeForce 8300 GS",           DRIVER_NVIDIA_GEFORCE6,  128 },
01095     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8400GS,     "NVIDIA GeForce 8400 GS",           DRIVER_NVIDIA_GEFORCE6,  128 },
01096     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600GT,     "NVIDIA GeForce 8600 GT",           DRIVER_NVIDIA_GEFORCE6,  256 },
01097     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600MGT,    "NVIDIA GeForce 8600M GT",          DRIVER_NVIDIA_GEFORCE6,  512 },
01098     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTS,    "NVIDIA GeForce 8800 GTS",          DRIVER_NVIDIA_GEFORCE6,  320 },
01099     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTX,    "NVIDIA GeForce 8800 GTX",          DRIVER_NVIDIA_GEFORCE6,  768 },
01100     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9200,       "NVIDIA GeForce 9200",              DRIVER_NVIDIA_GEFORCE6,  256 },
01101     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9400GT,     "NVIDIA GeForce 9400 GT",           DRIVER_NVIDIA_GEFORCE6,  256 },
01102     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9500GT,     "NVIDIA GeForce 9500 GT",           DRIVER_NVIDIA_GEFORCE6,  256 },
01103     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9600GT,     "NVIDIA GeForce 9600 GT",           DRIVER_NVIDIA_GEFORCE6,  384 },
01104     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9800GT,     "NVIDIA GeForce 9800 GT",           DRIVER_NVIDIA_GEFORCE6,  512 },
01105     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_210,        "NVIDIA GeForce 210",               DRIVER_NVIDIA_GEFORCE6,  512 },
01106     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT220,      "NVIDIA GeForce GT 220",            DRIVER_NVIDIA_GEFORCE6,  512 },
01107     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT240,      "NVIDIA GeForce GT 240",            DRIVER_NVIDIA_GEFORCE6,  512 },
01108     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX260,     "NVIDIA GeForce GTX 260",           DRIVER_NVIDIA_GEFORCE6,  1024},
01109     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX275,     "NVIDIA GeForce GTX 275",           DRIVER_NVIDIA_GEFORCE6,  896 },
01110     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX280,     "NVIDIA GeForce GTX 280",           DRIVER_NVIDIA_GEFORCE6,  1024},
01111     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT320M,     "NVIDIA GeForce GT 320M",           DRIVER_NVIDIA_GEFORCE6,  1024},
01112     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT325M,     "NVIDIA GeForce GT 325M",           DRIVER_NVIDIA_GEFORCE6,  1024},
01113     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT330,      "NVIDIA GeForce GT 330",            DRIVER_NVIDIA_GEFORCE6,  1024},
01114     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTS350M,    "NVIDIA GeForce GTS 350M",          DRIVER_NVIDIA_GEFORCE6,  1024},
01115     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT420,      "NVIDIA GeForce GT 420",            DRIVER_NVIDIA_GEFORCE6,  2048},
01116     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT430,      "NVIDIA GeForce GT 430",            DRIVER_NVIDIA_GEFORCE6,  1024},
01117     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT440,      "NVIDIA GeForce GT 440",            DRIVER_NVIDIA_GEFORCE6,  1024},
01118     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTS450,     "NVIDIA GeForce GTS 450",           DRIVER_NVIDIA_GEFORCE6,  1024},
01119     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX460,     "NVIDIA GeForce GTX 460",           DRIVER_NVIDIA_GEFORCE6,  768 },
01120     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX460M,    "NVIDIA GeForce GTX 460M",          DRIVER_NVIDIA_GEFORCE6,  1536},
01121     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX465,     "NVIDIA GeForce GTX 465",           DRIVER_NVIDIA_GEFORCE6,  1024},
01122     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX470,     "NVIDIA GeForce GTX 470",           DRIVER_NVIDIA_GEFORCE6,  1280},
01123     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX480,     "NVIDIA GeForce GTX 480",           DRIVER_NVIDIA_GEFORCE6,  1536},
01124     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT540M,     "NVIDIA GeForce GT 540M",           DRIVER_NVIDIA_GEFORCE6,  1024},
01125     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX550,     "NVIDIA GeForce GTX 550 Ti",        DRIVER_NVIDIA_GEFORCE6,  1024},
01126     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT555M,     "NVIDIA GeForce GT 555M",           DRIVER_NVIDIA_GEFORCE6,  1024},
01127     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX560TI,   "NVIDIA GeForce GTX 560 Ti",        DRIVER_NVIDIA_GEFORCE6,  1024},
01128     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX560,     "NVIDIA GeForce GTX 560",           DRIVER_NVIDIA_GEFORCE6,  1024},
01129     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX570,     "NVIDIA GeForce GTX 570",           DRIVER_NVIDIA_GEFORCE6,  1280},
01130     {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX580,     "NVIDIA GeForce GTX 580",           DRIVER_NVIDIA_GEFORCE6,  1536},
01131 
01132     /* AMD cards */
01133     {HW_VENDOR_AMD,        CARD_AMD_RAGE_128PRO,           "ATI Rage Fury",                    DRIVER_AMD_RAGE_128PRO,  16  },
01134     {HW_VENDOR_AMD,        CARD_AMD_RADEON_7200,           "ATI RADEON 7200 SERIES",           DRIVER_AMD_R100,         32  },
01135     {HW_VENDOR_AMD,        CARD_AMD_RADEON_8500,           "ATI RADEON 8500 SERIES",           DRIVER_AMD_R100,         64  },
01136     {HW_VENDOR_AMD,        CARD_AMD_RADEON_9500,           "ATI Radeon 9500",                  DRIVER_AMD_R300,         64  },
01137     {HW_VENDOR_AMD,        CARD_AMD_RADEON_XPRESS_200M,    "ATI RADEON XPRESS 200M Series",    DRIVER_AMD_R300,         64  },
01138     {HW_VENDOR_AMD,        CARD_AMD_RADEON_X700,           "ATI Radeon X700 SE",               DRIVER_AMD_R300,         128 },
01139     {HW_VENDOR_AMD,        CARD_AMD_RADEON_X1600,          "ATI Radeon X1600 Series",          DRIVER_AMD_R300,         128 },
01140     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD2350,         "ATI Mobility Radeon HD 2350",      DRIVER_AMD_R600,         256 },
01141     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD2600,         "ATI Mobility Radeon HD 2600",      DRIVER_AMD_R600,         256 },
01142     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD2900,         "ATI Radeon HD 2900 XT",            DRIVER_AMD_R600,         512 },
01143     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD3200,         "ATI Radeon HD 3200 Graphics",      DRIVER_AMD_R600,         128 },
01144     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD4350,         "ATI Radeon HD 4350",               DRIVER_AMD_R600,         256 },
01145     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD4600,         "ATI Radeon HD 4600 Series",        DRIVER_AMD_R600,         512 },
01146     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD4700,         "ATI Radeon HD 4700 Series",        DRIVER_AMD_R600,         512 },
01147     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD4800,         "ATI Radeon HD 4800 Series",        DRIVER_AMD_R600,         512 },
01148     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD5400,         "ATI Radeon HD 5400 Series",        DRIVER_AMD_R600,         512 },
01149     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD5600,         "ATI Radeon HD 5600 Series",        DRIVER_AMD_R600,         512 },
01150     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD5700,         "ATI Radeon HD 5700 Series",        DRIVER_AMD_R600,         512 },
01151     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD5800,         "ATI Radeon HD 5800 Series",        DRIVER_AMD_R600,         1024},
01152     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD5900,         "ATI Radeon HD 5900 Series",        DRIVER_AMD_R600,         1024},
01153     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6300,         "AMD Radeon HD 6300 series Graphics", DRIVER_AMD_R600,       1024},
01154     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6400,         "AMD Radeon HD 6400 Series",        DRIVER_AMD_R600,         1024},
01155     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6410D,        "AMD Radeon HD 6410D",              DRIVER_AMD_R600,         1024},
01156     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6550D,        "AMD Radeon HD 6550D",              DRIVER_AMD_R600,         1024},
01157     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6600,         "AMD Radeon HD 6600 Series",        DRIVER_AMD_R600,         1024},
01158     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6600M,        "AMD Radeon HD 6600M Series",       DRIVER_AMD_R600,         512 },
01159     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6800,         "AMD Radeon HD 6800 Series",        DRIVER_AMD_R600,         1024},
01160     {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6900,         "AMD Radeon HD 6900 Series",        DRIVER_AMD_R600,         2048},
01161     /* Intel cards */
01162     {HW_VENDOR_INTEL,      CARD_INTEL_830M,                "Intel(R) 82830M Graphics Controller",                       DRIVER_INTEL_GMA800,  32 },
01163     {HW_VENDOR_INTEL,      CARD_INTEL_855GM,               "Intel(R) 82852/82855 GM/GME Graphics Controller",           DRIVER_INTEL_GMA800,  32 },
01164     {HW_VENDOR_INTEL,      CARD_INTEL_845G,                "Intel(R) 845G",                                             DRIVER_INTEL_GMA800,  32 },
01165     {HW_VENDOR_INTEL,      CARD_INTEL_865G,                "Intel(R) 82865G Graphics Controller",                       DRIVER_INTEL_GMA800,  32 },
01166     {HW_VENDOR_INTEL,      CARD_INTEL_915G,                "Intel(R) 82915G/GV/910GL Express Chipset Family",           DRIVER_INTEL_GMA900,  64 },
01167     {HW_VENDOR_INTEL,      CARD_INTEL_E7221G,              "Intel(R) E7221G",                                           DRIVER_INTEL_GMA900,  64 },
01168     {HW_VENDOR_INTEL,      CARD_INTEL_915GM,               "Mobile Intel(R) 915GM/GMS,910GML Express Chipset Family",   DRIVER_INTEL_GMA900,  64 },
01169     {HW_VENDOR_INTEL,      CARD_INTEL_945G,                "Intel(R) 945G",                                             DRIVER_INTEL_GMA950,  64 },
01170     {HW_VENDOR_INTEL,      CARD_INTEL_945GM,               "Mobile Intel(R) 945GM Express Chipset Family",              DRIVER_INTEL_GMA950,  64 },
01171     {HW_VENDOR_INTEL,      CARD_INTEL_945GME,              "Intel(R) 945GME",                                           DRIVER_INTEL_GMA950,  64 },
01172     {HW_VENDOR_INTEL,      CARD_INTEL_Q35,                 "Intel(R) Q35",                                              DRIVER_INTEL_GMA950,  64 },
01173     {HW_VENDOR_INTEL,      CARD_INTEL_G33,                 "Intel(R) G33",                                              DRIVER_INTEL_GMA950,  64 },
01174     {HW_VENDOR_INTEL,      CARD_INTEL_Q33,                 "Intel(R) Q33",                                              DRIVER_INTEL_GMA950,  64 },
01175     {HW_VENDOR_INTEL,      CARD_INTEL_PNVG,                "Intel(R) IGD",                                              DRIVER_INTEL_GMA950,  64 },
01176     {HW_VENDOR_INTEL,      CARD_INTEL_PNVM,                "Intel(R) IGD",                                              DRIVER_INTEL_GMA950,  64 },
01177     {HW_VENDOR_INTEL,      CARD_INTEL_965Q,                "Intel(R) 965Q",                                             DRIVER_INTEL_GMA3000, 128},
01178     {HW_VENDOR_INTEL,      CARD_INTEL_965G,                "Intel(R) 965G",                                             DRIVER_INTEL_GMA3000, 128},
01179     {HW_VENDOR_INTEL,      CARD_INTEL_946GZ,               "Intel(R) 946GZ",                                            DRIVER_INTEL_GMA3000, 128},
01180     {HW_VENDOR_INTEL,      CARD_INTEL_965GM,               "Mobile Intel(R) 965 Express Chipset Family",                DRIVER_INTEL_GMA3000, 128},
01181     {HW_VENDOR_INTEL,      CARD_INTEL_965GME,              "Intel(R) 965GME",                                           DRIVER_INTEL_GMA3000, 128},
01182     {HW_VENDOR_INTEL,      CARD_INTEL_GM45,                "Mobile Intel(R) GM45 Express Chipset Family",               DRIVER_INTEL_GMA3000, 512},
01183     {HW_VENDOR_INTEL,      CARD_INTEL_IGD,                 "Intel(R) Integrated Graphics Device",                       DRIVER_INTEL_GMA3000, 512},
01184     {HW_VENDOR_INTEL,      CARD_INTEL_G45,                 "Intel(R) G45/G43",                                          DRIVER_INTEL_GMA3000, 512},
01185     {HW_VENDOR_INTEL,      CARD_INTEL_Q45,                 "Intel(R) Q45/Q43",                                          DRIVER_INTEL_GMA3000, 512},
01186     {HW_VENDOR_INTEL,      CARD_INTEL_G41,                 "Intel(R) G41",                                              DRIVER_INTEL_GMA3000, 512},
01187     {HW_VENDOR_INTEL,      CARD_INTEL_B43,                 "Intel(R) B43",                                              DRIVER_INTEL_GMA3000, 512},
01188     {HW_VENDOR_INTEL,      CARD_INTEL_ILKD,                "Intel(R) Ironlake Desktop",                                 DRIVER_INTEL_GMA3000, 1024},
01189     {HW_VENDOR_INTEL,      CARD_INTEL_ILKM,                "Intel(R) Ironlake Mobile",                                  DRIVER_INTEL_GMA3000, 1024},
01190     {HW_VENDOR_INTEL,      CARD_INTEL_SNBD,                "Intel(R) Sandybridge Desktop",                              DRIVER_INTEL_GMA3000, 1024},
01191     {HW_VENDOR_INTEL,      CARD_INTEL_SNBM,                "Intel(R) Sandybridge Mobile",                               DRIVER_INTEL_GMA3000, 1024},
01192     {HW_VENDOR_INTEL,      CARD_INTEL_SNBS,                "Intel(R) Sandybridge Server",                               DRIVER_INTEL_GMA3000, 1024},
01193     {HW_VENDOR_INTEL,      CARD_INTEL_IVBD,                "Intel(R) Ivybridge Desktop",                                DRIVER_INTEL_GMA3000, 1024},
01194     {HW_VENDOR_INTEL,      CARD_INTEL_IVBM,                "Intel(R) Ivybridge Mobile",                                 DRIVER_INTEL_GMA3000, 1024},
01195     {HW_VENDOR_INTEL,      CARD_INTEL_IVBS,                "Intel(R) Ivybridge Server",                                 DRIVER_INTEL_GMA3000, 1024},
01196 };
01197 
01198 static const struct driver_version_information *get_driver_version_info(enum wined3d_display_driver driver,
01199         enum wined3d_driver_model driver_model)
01200 {
01201     unsigned int i;
01202 
01203     TRACE("Looking up version info for driver=%d driver_model=%d\n", driver, driver_model);
01204     for (i = 0; i < (sizeof(driver_version_table) / sizeof(driver_version_table[0])); i++)
01205     {
01206         const struct driver_version_information *entry = &driver_version_table[i];
01207 
01208         if (entry->driver == driver && entry->driver_model == driver_model)
01209         {
01210             TRACE_(d3d_caps)("Found driver '%s' version=%d subversion=%d build=%d\n",
01211                 entry->driver_name, entry->version, entry->subversion, entry->build);
01212 
01213             return entry;
01214         }
01215     }
01216     return NULL;
01217 }
01218 
01219 static void init_driver_info(struct wined3d_driver_info *driver_info,
01220         enum wined3d_pci_vendor vendor, enum wined3d_pci_device device)
01221 {
01222     OSVERSIONINFOW os_version;
01223     WORD driver_os_version;
01224     unsigned int i;
01225     enum wined3d_display_driver driver = DRIVER_UNKNOWN;
01226     enum wined3d_driver_model driver_model;
01227     const struct driver_version_information *version_info;
01228 
01229     if (wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
01230     {
01231         TRACE_(d3d_caps)("Overriding PCI vendor ID with: %04x\n", wined3d_settings.pci_vendor_id);
01232         vendor = wined3d_settings.pci_vendor_id;
01233     }
01234     driver_info->vendor = vendor;
01235 
01236     if (wined3d_settings.pci_device_id != PCI_DEVICE_NONE)
01237     {
01238         TRACE_(d3d_caps)("Overriding PCI device ID with: %04x\n", wined3d_settings.pci_device_id);
01239         device = wined3d_settings.pci_device_id;
01240     }
01241     driver_info->device = device;
01242 
01243     /* Set a default amount of video memory (64MB). In general this code isn't used unless the user
01244      * overrides the pci ids to a card which is not in our database. */
01245     driver_info->vidmem = WINE_DEFAULT_VIDMEM;
01246 
01247     memset(&os_version, 0, sizeof(os_version));
01248     os_version.dwOSVersionInfoSize = sizeof(os_version);
01249     if (!GetVersionExW(&os_version))
01250     {
01251         ERR("Failed to get OS version, reporting 2000/XP.\n");
01252         driver_os_version = 6;
01253         driver_model = DRIVER_MODEL_NT5X;
01254     }
01255     else
01256     {
01257         TRACE("OS version %u.%u.\n", os_version.dwMajorVersion, os_version.dwMinorVersion);
01258         switch (os_version.dwMajorVersion)
01259         {
01260             case 4:
01261                 /* If needed we could distinguish between 9x and NT4, but this code won't make
01262                  * sense for NT4 since it had no way to obtain this info through DirectDraw 3.0.
01263                  */
01264                 driver_os_version = 4;
01265                 driver_model = DRIVER_MODEL_WIN9X;
01266                 break;
01267 
01268             case 5:
01269                 driver_os_version = 6;
01270                 driver_model = DRIVER_MODEL_NT5X;
01271                 break;
01272 
01273             case 6:
01274                 if (os_version.dwMinorVersion == 0)
01275                 {
01276                     driver_os_version = 7;
01277                     driver_model = DRIVER_MODEL_NT6X;
01278                 }
01279                 else
01280                 {
01281                     if (os_version.dwMinorVersion > 1)
01282                     {
01283                         FIXME("Unhandled OS version %u.%u, reporting Win 7.\n",
01284                                 os_version.dwMajorVersion, os_version.dwMinorVersion);
01285                     }
01286                     driver_os_version = 8;
01287                     driver_model = DRIVER_MODEL_NT6X;
01288                 }
01289                 break;
01290 
01291             default:
01292                 FIXME("Unhandled OS version %u.%u, reporting 2000/XP.\n",
01293                         os_version.dwMajorVersion, os_version.dwMinorVersion);
01294                 driver_os_version = 6;
01295                 driver_model = DRIVER_MODEL_NT5X;
01296                 break;
01297         }
01298     }
01299 
01300     /* When we reach this stage we always have a vendor or device id (it can be a default one).
01301      * This means that unless the ids are overriden, we will always find a GPU description. */
01302     for (i = 0; i < (sizeof(gpu_description_table) / sizeof(gpu_description_table[0])); i++)
01303     {
01304         if (vendor == gpu_description_table[i].vendor && device == gpu_description_table[i].card)
01305         {
01306             TRACE_(d3d_caps)("Found card %04x:%04x in driver DB.\n", vendor, device);
01307 
01308             driver_info->description = gpu_description_table[i].description;
01309             driver_info->vidmem = gpu_description_table[i].vidmem * 1024*1024;
01310             driver = gpu_description_table[i].driver;
01311             break;
01312         }
01313     }
01314 
01315     if (wined3d_settings.emulated_textureram)
01316     {
01317         TRACE_(d3d_caps)("Overriding amount of video memory with: %d byte\n", wined3d_settings.emulated_textureram);
01318         driver_info->vidmem = wined3d_settings.emulated_textureram;
01319     }
01320 
01321     /* Try to obtain driver version information for the current Windows version. This fails in
01322      * some cases:
01323      * - the gpu is not available on the currently selected OS version:
01324      *   - Geforce GTX480 on Win98. When running applications in compatibility mode on Windows,
01325      *     version information for the current Windows version is returned instead of faked info.
01326      *     We do the same and assume the default Windows version to emulate is WinXP.
01327      *
01328      *   - Videocard is a Riva TNT but winver is set to win7 (there are no drivers for this beast)
01329      *     For now return the XP driver info. Perhaps later on we should return VESA.
01330      *
01331      * - the gpu is not in our database (can happen when the user overrides the vendor_id / device_id)
01332      *   This could be an indication that our database is not up to date, so this should be fixed.
01333      */
01334     version_info = get_driver_version_info(driver, driver_model);
01335     if (version_info)
01336     {
01337         driver_info->name = version_info->driver_name;
01338         driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, version_info->version);
01339         driver_info->version_low = MAKEDWORD_VERSION(version_info->subversion, version_info->build);
01340     }
01341     else
01342     {
01343         version_info = get_driver_version_info(driver, DRIVER_MODEL_NT5X);
01344         if (version_info)
01345         {
01346             driver_info->name = version_info->driver_name;
01347             driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, version_info->version);
01348             driver_info->version_low = MAKEDWORD_VERSION(version_info->subversion, version_info->build);
01349         }
01350         else
01351         {
01352             driver_info->description = "Direct3D HAL";
01353             driver_info->name = "Display";
01354             driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, 15);
01355             driver_info->version_low = MAKEDWORD_VERSION(8, 6); /* Nvidia RIVA TNT, arbitrary */
01356 
01357             FIXME("Unable to find a driver/device info for vendor_id=%#x device_id=%#x for driver_model=%d\n",
01358                     vendor, device, driver_model);
01359         }
01360     }
01361 
01362     TRACE_(d3d_caps)("Reporting (fake) driver version 0x%08x-0x%08x.\n",
01363             driver_info->version_high, driver_info->version_low);
01364 }
01365 
01366 /* Context activation is done by the caller. */
01367 static void fixup_extensions(struct wined3d_gl_info *gl_info, const char *gl_renderer,
01368         enum wined3d_gl_vendor gl_vendor, enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
01369 {
01370     unsigned int i;
01371 
01372     for (i = 0; i < (sizeof(quirk_table) / sizeof(*quirk_table)); ++i)
01373     {
01374         if (!quirk_table[i].match(gl_info, gl_renderer, gl_vendor, card_vendor, device)) continue;
01375         TRACE_(d3d_caps)("Applying driver quirk \"%s\".\n", quirk_table[i].description);
01376         quirk_table[i].apply(gl_info);
01377     }
01378 
01379     /* Find out if PBOs work as they are supposed to. */
01380     test_pbo_functionality(gl_info);
01381 }
01382 
01383 static DWORD wined3d_parse_gl_version(const char *gl_version)
01384 {
01385     const char *ptr = gl_version;
01386     int major, minor;
01387 
01388     major = atoi(ptr);
01389     if (major <= 0) ERR_(d3d_caps)("Invalid opengl major version: %d.\n", major);
01390 
01391     while (isdigit(*ptr)) ++ptr;
01392     if (*ptr++ != '.') ERR_(d3d_caps)("Invalid opengl version string: %s.\n", debugstr_a(gl_version));
01393 
01394     minor = atoi(ptr);
01395 
01396     TRACE_(d3d_caps)("Found OpenGL version: %d.%d.\n", major, minor);
01397 
01398     return MAKEDWORD_VERSION(major, minor);
01399 }
01400 
01401 static enum wined3d_gl_vendor wined3d_guess_gl_vendor(const struct wined3d_gl_info *gl_info,
01402         const char *gl_vendor_string, const char *gl_renderer)
01403 {
01404 
01405     /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
01406      * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
01407      * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
01408      *
01409      * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
01410      * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
01411      * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
01412      * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
01413      * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
01414      * the chance that other implementations support them is rather small since Win32 QuickTime uses
01415      * DirectDraw, not OpenGL. */
01416     if (gl_info->supported[APPLE_FENCE]
01417             && gl_info->supported[APPLE_CLIENT_STORAGE]
01418             && gl_info->supported[APPLE_FLUSH_RENDER]
01419             && gl_info->supported[APPLE_YCBCR_422])
01420         return GL_VENDOR_APPLE;
01421 
01422     if (strstr(gl_vendor_string, "NVIDIA"))
01423         return GL_VENDOR_NVIDIA;
01424 
01425     if (strstr(gl_vendor_string, "ATI"))
01426         return GL_VENDOR_FGLRX;
01427 
01428     if (strstr(gl_vendor_string, "Intel(R)")
01429             /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */
01430             || strstr(gl_renderer, "Intel")
01431             || strstr(gl_vendor_string, "Intel Inc."))
01432         return GL_VENDOR_INTEL;
01433 
01434     if (strstr(gl_vendor_string, "Mesa")
01435             || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
01436             || strstr(gl_vendor_string, "DRI R300 Project")
01437             || strstr(gl_vendor_string, "X.Org R300 Project")
01438             || strstr(gl_vendor_string, "Tungsten Graphics, Inc")
01439             || strstr(gl_vendor_string, "VMware, Inc.")
01440             || strstr(gl_renderer, "Mesa")
01441             || strstr(gl_renderer, "Gallium"))
01442         return GL_VENDOR_MESA;
01443 
01444     FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_UNKNOWN.\n",
01445             debugstr_a(gl_vendor_string));
01446 
01447     return GL_VENDOR_UNKNOWN;
01448 }
01449 
01450 static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_string, const char *gl_renderer)
01451 {
01452     if (strstr(gl_vendor_string, "NVIDIA")
01453             || strstr(gl_vendor_string, "nouveau"))
01454         return HW_VENDOR_NVIDIA;
01455 
01456     if (strstr(gl_vendor_string, "ATI")
01457             || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
01458             || strstr(gl_vendor_string, "X.Org R300 Project")
01459             || strstr(gl_renderer, "AMD")
01460             || strstr(gl_renderer, "R100")
01461             || strstr(gl_renderer, "R200")
01462             || strstr(gl_renderer, "R300")
01463             || strstr(gl_renderer, "R600")
01464             || strstr(gl_renderer, "R700"))
01465         return HW_VENDOR_AMD;
01466 
01467     if (strstr(gl_vendor_string, "Intel(R)")
01468             /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */
01469             || strstr(gl_renderer, "Intel")
01470             || strstr(gl_renderer, "i915")
01471             || strstr(gl_vendor_string, "Intel Inc."))
01472         return HW_VENDOR_INTEL;
01473 
01474     if (strstr(gl_vendor_string, "Mesa")
01475             || strstr(gl_vendor_string, "Brian Paul")
01476             || strstr(gl_vendor_string, "Tungsten Graphics, Inc")
01477             || strstr(gl_vendor_string, "VMware, Inc."))
01478         return HW_VENDOR_SOFTWARE;
01479 
01480     FIXME_(d3d_caps)("Received unrecognized GL_VENDOR %s. Returning HW_VENDOR_NVIDIA.\n", debugstr_a(gl_vendor_string));
01481 
01482     return HW_VENDOR_NVIDIA;
01483 }
01484 
01485 static UINT d3d_level_from_gl_info(const struct wined3d_gl_info *gl_info)
01486 {
01487     UINT level = 0;
01488 
01489     if (gl_info->supported[ARB_MULTITEXTURE])
01490         level = 6;
01491     if (gl_info->supported[ARB_TEXTURE_COMPRESSION]
01492             && gl_info->supported[ARB_TEXTURE_CUBE_MAP]
01493             && gl_info->supported[ARB_TEXTURE_ENV_DOT3])
01494         level = 7;
01495     if (level == 7 && gl_info->supported[ARB_MULTISAMPLE]
01496             && gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
01497         level = 8;
01498     if (level == 8 && gl_info->supported[ARB_FRAGMENT_PROGRAM]
01499             && gl_info->supported[ARB_VERTEX_SHADER])
01500         level = 9;
01501     if (level == 9 && gl_info->supported[EXT_GPU_SHADER4])
01502         level = 10;
01503 
01504     return level;
01505 }
01506 
01507 static enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info *gl_info,
01508         const char *gl_renderer)
01509 {
01510     UINT d3d_level = d3d_level_from_gl_info(gl_info);
01511     unsigned int i;
01512 
01513     if (d3d_level >= 10)
01514     {
01515         static const struct
01516         {
01517             const char *renderer;
01518             enum wined3d_pci_device id;
01519         }
01520         cards[] =
01521         {
01522             {"GTX 580",     CARD_NVIDIA_GEFORCE_GTX580},    /* Geforce 500 - highend */
01523             {"GTX 570",     CARD_NVIDIA_GEFORCE_GTX570},    /* Geforce 500 - midend high */
01524             {"GTX 560 Ti",  CARD_NVIDIA_GEFORCE_GTX560TI},  /* Geforce 500 - midend */
01525             {"GTX 560",     CARD_NVIDIA_GEFORCE_GTX560},    /* Geforce 500 - midend */
01526             {"GT 555M",     CARD_NVIDIA_GEFORCE_GT555M},    /* Geforce 500 - midend mobile */
01527             {"GTX 550 Ti",  CARD_NVIDIA_GEFORCE_GTX550},    /* Geforce 500 - midend */
01528             {"GT 540M",     CARD_NVIDIA_GEFORCE_GT540M},    /* Geforce 500 - midend mobile */
01529             {"GTX 480",     CARD_NVIDIA_GEFORCE_GTX480},    /* Geforce 400 - highend */
01530             {"GTX 470",     CARD_NVIDIA_GEFORCE_GTX470},    /* Geforce 400 - midend high */
01531             {"GTX 465",     CARD_NVIDIA_GEFORCE_GTX465},    /* Geforce 400 - midend */
01532             {"GTX 460M",    CARD_NVIDIA_GEFORCE_GTX460M},   /* Geforce 400 - highend mobile */
01533             {"GTX 460",     CARD_NVIDIA_GEFORCE_GTX460},    /* Geforce 400 - midend */
01534             {"GTS 450",     CARD_NVIDIA_GEFORCE_GTS450},    /* Geforce 400 - midend low */
01535             {"GT 440",      CARD_NVIDIA_GEFORCE_GT440},     /* Geforce 400 - lowend */
01536             {"GT 430",      CARD_NVIDIA_GEFORCE_GT430},     /* Geforce 400 - lowend */
01537             {"GT 420",      CARD_NVIDIA_GEFORCE_GT420},     /* Geforce 400 - lowend */
01538             {"GT 330",      CARD_NVIDIA_GEFORCE_GT330},     /* Geforce 300 - highend */
01539             {"GTS 360M",    CARD_NVIDIA_GEFORCE_GTS350M},   /* Geforce 300 - highend mobile */
01540             {"GTS 350M",    CARD_NVIDIA_GEFORCE_GTS350M},   /* Geforce 300 - highend mobile */
01541             {"GT 330M",     CARD_NVIDIA_GEFORCE_GT325M},    /* Geforce 300 - midend mobile */
01542             {"GT 325M",     CARD_NVIDIA_GEFORCE_GT325M},    /* Geforce 300 - midend mobile */
01543             {"GT 320M",     CARD_NVIDIA_GEFORCE_GT320M},    /* Geforce 300 - midend mobile */
01544             {"GTX 295",     CARD_NVIDIA_GEFORCE_GTX280},    /* Geforce 200 - highend */
01545             {"GTX 285",     CARD_NVIDIA_GEFORCE_GTX280},    /* Geforce 200 - highend */
01546             {"GTX 280",     CARD_NVIDIA_GEFORCE_GTX280},    /* Geforce 200 - highend */
01547             {"GTX 275",     CARD_NVIDIA_GEFORCE_GTX275},    /* Geforce 200 - midend high */
01548             {"GTX 260",     CARD_NVIDIA_GEFORCE_GTX260},    /* Geforce 200 - midend */
01549             {"GT 240",      CARD_NVIDIA_GEFORCE_GT240},     /* Geforce 200 - midend */
01550             {"GT 220",      CARD_NVIDIA_GEFORCE_GT220},     /* Geforce 200 - lowend */
01551             {"Geforce 310", CARD_NVIDIA_GEFORCE_210},       /* Geforce 200 - lowend */
01552             {"Geforce 305", CARD_NVIDIA_GEFORCE_210},       /* Geforce 200 - lowend */
01553             {"Geforce 210", CARD_NVIDIA_GEFORCE_210},       /* Geforce 200 - lowend */
01554             {"G 210",       CARD_NVIDIA_GEFORCE_210},       /* Geforce 200 - lowend */
01555             {"GTS 250",     CARD_NVIDIA_GEFORCE_9800GT},    /* Geforce 9 - highend / Geforce 200 - midend */
01556             {"GTS 150",     CARD_NVIDIA_GEFORCE_9800GT},    /* Geforce 9 - highend / Geforce 200 - midend */
01557             {"9800",        CARD_NVIDIA_GEFORCE_9800GT},    /* Geforce 9 - highend / Geforce 200 - midend */
01558             {"GT 140",      CARD_NVIDIA_GEFORCE_9600GT},    /* Geforce 9 - midend */
01559             {"9600",        CARD_NVIDIA_GEFORCE_9600GT},    /* Geforce 9 - midend */
01560             {"GT 130",      CARD_NVIDIA_GEFORCE_9500GT},    /* Geforce 9 - midend low / Geforce 200 - low */
01561             {"GT 120",      CARD_NVIDIA_GEFORCE_9500GT},    /* Geforce 9 - midend low / Geforce 200 - low */
01562             {"9500",        CARD_NVIDIA_GEFORCE_9500GT},    /* Geforce 9 - midend low / Geforce 200 - low */
01563             {"9400",        CARD_NVIDIA_GEFORCE_9400GT},    /* Geforce 9 - lowend */
01564             {"9300",        CARD_NVIDIA_GEFORCE_9200},      /* Geforce 9 - lowend low */
01565             {"9200",        CARD_NVIDIA_GEFORCE_9200},      /* Geforce 9 - lowend low */
01566             {"9100",        CARD_NVIDIA_GEFORCE_9200},      /* Geforce 9 - lowend low */
01567             {"G 100",       CARD_NVIDIA_GEFORCE_9200},      /* Geforce 9 - lowend low */
01568             {"8800 GTX",    CARD_NVIDIA_GEFORCE_8800GTX},   /* Geforce 8 - highend high */
01569             {"8800",        CARD_NVIDIA_GEFORCE_8800GTS},   /* Geforce 8 - highend */
01570             {"8600 M",      CARD_NVIDIA_GEFORCE_8600MGT},   /* Geforce 8 - midend mobile */
01571             {"8700",        CARD_NVIDIA_GEFORCE_8600GT},    /* Geforce 8 - midend */
01572             {"8600",        CARD_NVIDIA_GEFORCE_8600GT},    /* Geforce 8 - midend */
01573             {"8500",        CARD_NVIDIA_GEFORCE_8400GS},    /* Geforce 8 - mid-lowend */
01574             {"8400",        CARD_NVIDIA_GEFORCE_8400GS},    /* Geforce 8 - mid-lowend */
01575             {"8300",        CARD_NVIDIA_GEFORCE_8300GS},    /* Geforce 8 - lowend */
01576             {"8200",        CARD_NVIDIA_GEFORCE_8300GS},    /* Geforce 8 - lowend */
01577             {"8100",        CARD_NVIDIA_GEFORCE_8300GS},    /* Geforce 8 - lowend */
01578         };
01579 
01580         for (i = 0; i < sizeof(cards) / sizeof(*cards); ++i)
01581         {
01582             if (strstr(gl_renderer, cards[i].renderer))
01583                 return cards[i].id;
01584         }
01585 
01586         /* Geforce8-compatible fall back if the GPU is not in the list yet */
01587         return CARD_NVIDIA_GEFORCE_8300GS;
01588     }
01589 
01590     /* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
01591      * shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
01592      */
01593     if (d3d_level >= 9 && gl_info->supported[NV_VERTEX_PROGRAM3])
01594     {
01595         static const struct
01596         {
01597             const char *renderer;
01598             enum wined3d_pci_device id;
01599         }
01600         cards[] =
01601         {
01602             {"Quadro FX 5", CARD_NVIDIA_GEFORCE_7800GT},    /* Geforce 7 - highend */
01603             {"Quadro FX 4", CARD_NVIDIA_GEFORCE_7800GT},    /* Geforce 7 - highend */
01604             {"7950",        CARD_NVIDIA_GEFORCE_7800GT},    /* Geforce 7 - highend */
01605             {"7900",        CARD_NVIDIA_GEFORCE_7800GT},    /* Geforce 7 - highend */
01606             {"7800",        CARD_NVIDIA_GEFORCE_7800GT},    /* Geforce 7 - highend */
01607             {"7700",        CARD_NVIDIA_GEFORCE_7600},      /* Geforce 7 - midend */
01608             {"7600",        CARD_NVIDIA_GEFORCE_7600},      /* Geforce 7 - midend */
01609             {"7400",        CARD_NVIDIA_GEFORCE_7400},      /* Geforce 7 - lower medium */
01610             {"7300",        CARD_NVIDIA_GEFORCE_7300},      /* Geforce 7 - lowend */
01611             {"6800",        CARD_NVIDIA_GEFORCE_6800},      /* Geforce 6 - highend */
01612             {"6700",        CARD_NVIDIA_GEFORCE_6600GT},    /* Geforce 6 - midend */
01613             {"6610",        CARD_NVIDIA_GEFORCE_6600GT},    /* Geforce 6 - midend */
01614             {"6600",        CARD_NVIDIA_GEFORCE_6600GT},    /* Geforce 6 - midend */
01615         };
01616 
01617         for (i = 0; i < sizeof(cards) / sizeof(*cards); ++i)
01618         {
01619             if (strstr(gl_renderer, cards[i].renderer))
01620                 return cards[i].id;
01621         }
01622 
01623         /* Geforce 6/7 - lowend */
01624         return CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400/7500 */
01625     }
01626 
01627     if (d3d_level >= 9)
01628     {
01629         /* GeforceFX - highend */
01630         if (strstr(gl_renderer, "5800")
01631                 || strstr(gl_renderer, "5900")
01632                 || strstr(gl_renderer, "5950")
01633                 || strstr(gl_renderer, "Quadro FX"))
01634         {
01635             return CARD_NVIDIA_GEFORCEFX_5800;
01636         }
01637 
01638         /* GeforceFX - midend */
01639         if (strstr(gl_renderer, "5600")
01640                 || strstr(gl_renderer, "5650")
01641                 || strstr(gl_renderer, "5700")
01642                 || strstr(gl_renderer, "5750"))
01643         {
01644             return CARD_NVIDIA_GEFORCEFX_5600;
01645         }
01646 
01647         /* GeforceFX - lowend */
01648         return CARD_NVIDIA_GEFORCEFX_5200; /* GeforceFX 5100/5200/5250/5300/5500 */
01649     }
01650 
01651     if (d3d_level >= 8)
01652     {
01653         if (strstr(gl_renderer, "GeForce4 Ti") || strstr(gl_renderer, "Quadro4"))
01654         {
01655             return CARD_NVIDIA_GEFORCE4_TI4200; /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800, Quadro4 */
01656         }
01657 
01658         return CARD_NVIDIA_GEFORCE3; /* Geforce3 standard/Ti200/Ti500, Quadro DCC */
01659     }
01660 
01661     if (d3d_level >= 7)
01662     {
01663         if (strstr(gl_renderer, "GeForce4 MX"))
01664         {
01665             return CARD_NVIDIA_GEFORCE4_MX; /* MX420/MX440/MX460/MX4000 */
01666         }
01667 
01668         if (strstr(gl_renderer, "GeForce2 MX") || strstr(gl_renderer, "Quadro2 MXR"))
01669         {
01670             return CARD_NVIDIA_GEFORCE2_MX; /* Geforce2 standard/MX100/MX200/MX400, Quadro2 MXR */
01671         }
01672 
01673         if (strstr(gl_renderer, "GeForce2") || strstr(gl_renderer, "Quadro2"))
01674         {
01675             return CARD_NVIDIA_GEFORCE2; /* Geforce2 GTS/Pro/Ti/Ultra, Quadro2 */
01676         }
01677 
01678         return CARD_NVIDIA_GEFORCE; /* Geforce 256/DDR, Quadro */
01679     }
01680 
01681     if (strstr(gl_renderer, "TNT2"))
01682     {
01683         return CARD_NVIDIA_RIVA_TNT2; /* Riva TNT2 standard/M64/Pro/Ultra */
01684     }
01685 
01686     return CARD_NVIDIA_RIVA_TNT; /* Riva TNT, Vanta */
01687 }
01688 
01689 static enum wined3d_pci_device select_card_amd_binary(const struct wined3d_gl_info *gl_info,
01690         const char *gl_renderer)
01691 {
01692     UINT d3d_level = d3d_level_from_gl_info(gl_info);
01693 
01694     /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
01695      *
01696      * Beware: renderer string do not match exact card model,
01697      * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */
01698     if (d3d_level >= 10)
01699     {
01700         unsigned int i;
01701 
01702         static const struct
01703         {
01704             const char *renderer;
01705             enum wined3d_pci_device id;
01706         }
01707         cards[] =
01708         {
01709             /* Northern Islands */
01710             {"HD 6900", CARD_AMD_RADEON_HD6900},
01711             {"HD 6800", CARD_AMD_RADEON_HD6800},
01712             {"HD 6630M",CARD_AMD_RADEON_HD6600M},
01713             {"HD 6600M",CARD_AMD_RADEON_HD6600M},
01714             {"HD 6600", CARD_AMD_RADEON_HD6600},
01715             {"HD 6500M",CARD_AMD_RADEON_HD6600M},
01716             {"HD 6500", CARD_AMD_RADEON_HD6600},
01717             {"HD 6400", CARD_AMD_RADEON_HD6400},
01718             {"HD 6300", CARD_AMD_RADEON_HD6300},
01719             {"HD 6200", CARD_AMD_RADEON_HD6300},
01720             /* Evergreen */
01721             {"HD 5870", CARD_AMD_RADEON_HD5800},    /* Radeon EG CYPRESS PRO */
01722             {"HD 5850", CARD_AMD_RADEON_HD5800},    /* Radeon EG CYPRESS XT */
01723             {"HD 5800", CARD_AMD_RADEON_HD5800},    /* Radeon EG CYPRESS HD58xx generic renderer string */
01724             {"HD 5770", CARD_AMD_RADEON_HD5700},    /* Radeon EG JUNIPER XT */
01725             {"HD 5750", CARD_AMD_RADEON_HD5700},    /* Radeon EG JUNIPER LE */
01726             {"HD 5700", CARD_AMD_RADEON_HD5700},    /* Radeon EG JUNIPER HD57xx generic renderer string */
01727             {"HD 5670", CARD_AMD_RADEON_HD5600},    /* Radeon EG REDWOOD XT */
01728             {"HD 5570", CARD_AMD_RADEON_HD5600},    /* Radeon EG REDWOOD PRO mapped to HD5600 series */
01729             {"HD 5550", CARD_AMD_RADEON_HD5600},    /* Radeon EG REDWOOD LE mapped to HD5600 series */
01730             {"HD 5450", CARD_AMD_RADEON_HD5400},    /* Radeon EG CEDAR PRO */
01731             /* R700 */
01732             {"HD 4890", CARD_AMD_RADEON_HD4800},    /* Radeon RV790 */
01733             {"HD 4870", CARD_AMD_RADEON_HD4800},    /* Radeon RV770 */
01734             {"HD 4850", CARD_AMD_RADEON_HD4800},    /* Radeon RV770 */
01735             {"HD 4830", CARD_AMD_RADEON_HD4800},    /* Radeon RV770 */
01736             {"HD 4800", CARD_AMD_RADEON_HD4800},    /* Radeon RV7xx HD48xx generic renderer string */
01737             {"HD 4770", CARD_AMD_RADEON_HD4700},    /* Radeon RV740 */
01738             {"HD 4700", CARD_AMD_RADEON_HD4700},    /* Radeon RV7xx HD47xx generic renderer string */
01739             {"HD 4670", CARD_AMD_RADEON_HD4600},    /* Radeon RV730 */
01740             {"HD 4650", CARD_AMD_RADEON_HD4600},    /* Radeon RV730 */
01741             {"HD 4600", CARD_AMD_RADEON_HD4600},    /* Radeon RV730 */
01742             {"HD 4550", CARD_AMD_RADEON_HD4350},    /* Radeon RV710 */
01743             {"HD 4350", CARD_AMD_RADEON_HD4350},    /* Radeon RV710 */
01744             /* R600/R700 integrated */
01745             {"HD 3300", CARD_AMD_RADEON_HD3200},
01746             {"HD 3200", CARD_AMD_RADEON_HD3200},
01747             {"HD 3100", CARD_AMD_RADEON_HD3200},
01748             /* R600 */
01749             {"HD 3870", CARD_AMD_RADEON_HD2900},    /* HD2900/HD3800 - highend */
01750             {"HD 3850", CARD_AMD_RADEON_HD2900},    /* HD2900/HD3800 - highend */
01751             {"HD 2900", CARD_AMD_RADEON_HD2900},    /* HD2900/HD3800 - highend */
01752             {"HD 3830", CARD_AMD_RADEON_HD2600},    /* China-only midend */
01753             {"HD 3690", CARD_AMD_RADEON_HD2600},    /* HD2600/HD3600 - midend */
01754             {"HD 3650", CARD_AMD_RADEON_HD2600},    /* HD2600/HD3600 - midend */
01755             {"HD 2600", CARD_AMD_RADEON_HD2600},    /* HD2600/HD3600 - midend */
01756             {"HD 3470", CARD_AMD_RADEON_HD2350},    /* HD2350/HD2400/HD3400 - lowend */
01757             {"HD 3450", CARD_AMD_RADEON_HD2350},    /* HD2350/HD2400/HD3400 - lowend */
01758             {"HD 3430", CARD_AMD_RADEON_HD2350},    /* HD2350/HD2400/HD3400 - lowend */
01759             {"HD 3400", CARD_AMD_RADEON_HD2350},    /* HD2350/HD2400/HD3400 - lowend */
01760             {"HD 2400", CARD_AMD_RADEON_HD2350},    /* HD2350/HD2400/HD3400 - lowend */
01761             {"HD 2350", CARD_AMD_RADEON_HD2350},    /* HD2350/HD2400/HD3400 - lowend */
01762         };
01763 
01764         for (i = 0; i < sizeof(cards) / sizeof(*cards); ++i)
01765         {
01766             if (strstr(gl_renderer, cards[i].renderer))
01767                 return cards[i].id;
01768         }
01769 
01770         /* Default for when no GPU has been found */
01771         return CARD_AMD_RADEON_HD3200;
01772     }
01773 
01774     if (d3d_level >= 9)
01775     {
01776         /* Radeon R5xx */
01777         if (strstr(gl_renderer, "X1600")
01778                 || strstr(gl_renderer, "X1650")
01779                 || strstr(gl_renderer, "X1800")
01780                 || strstr(gl_renderer, "X1900")
01781                 || strstr(gl_renderer, "X1950"))
01782         {
01783             return CARD_AMD_RADEON_X1600;
01784         }
01785 
01786         /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300/X2500/HD2300 (lowend R5xx)
01787          * Note X2300/X2500/HD2300 are R5xx GPUs with a 2xxx naming but they are still DX9-only */
01788         if (strstr(gl_renderer, "X700")
01789                 || strstr(gl_renderer, "X800")
01790                 || strstr(gl_renderer, "X850")
01791                 || strstr(gl_renderer, "X1300")
01792                 || strstr(gl_renderer, "X1400")
01793                 || strstr(gl_renderer, "X1450")
01794                 || strstr(gl_renderer, "X1550")
01795                 || strstr(gl_renderer, "X2300")
01796                 || strstr(gl_renderer, "X2500")
01797                 || strstr(gl_renderer, "HD 2300")
01798                 )
01799         {
01800             return CARD_AMD_RADEON_X700;
01801         }
01802 
01803         /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
01804         if (strstr(gl_renderer, "Radeon Xpress"))
01805         {
01806             return CARD_AMD_RADEON_XPRESS_200M;
01807         }
01808 
01809         /* Radeon R3xx */
01810         return CARD_AMD_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
01811     }
01812 
01813     if (d3d_level >= 8)
01814         return CARD_AMD_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
01815 
01816     if (d3d_level >= 7)
01817         return CARD_AMD_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
01818 
01819     return CARD_AMD_RAGE_128PRO;
01820 }
01821 
01822 static enum wined3d_pci_device select_card_intel(const struct wined3d_gl_info *gl_info,
01823         const char *gl_renderer)
01824 {
01825     unsigned int i;
01826 
01827     static const struct
01828     {
01829         const char *renderer;
01830         enum wined3d_pci_device id;
01831     }
01832     cards[] =
01833     {
01834         /* Ivybridge */
01835         {"Ivybridge Server",            CARD_INTEL_IVBS},
01836         {"Ivybridge Mobile",            CARD_INTEL_IVBM},
01837         {"Ivybridge Desktop",           CARD_INTEL_IVBD},
01838         /* Sandybridge */
01839         {"Sandybridge Server",          CARD_INTEL_SNBS},
01840         {"Sandybridge Mobile",          CARD_INTEL_SNBM},
01841         {"Sandybridge Desktop",         CARD_INTEL_SNBD},
01842         /* Ironlake */
01843         {"Ironlake Mobile",             CARD_INTEL_ILKM},
01844         {"Ironlake Desktop",            CARD_INTEL_ILKD},
01845         /* G4x */
01846         {"B43",                         CARD_INTEL_B43},
01847         {"G41",                         CARD_INTEL_G41},
01848         {"G45",                         CARD_INTEL_G45},
01849         {"Q45",                         CARD_INTEL_Q45},
01850         {"Integrated Graphics Device",  CARD_INTEL_IGD},
01851         {"GM45",                        CARD_INTEL_GM45},
01852         /* i965 */
01853         {"965GME",                      CARD_INTEL_965GME},
01854         {"965GM",                       CARD_INTEL_965GM},
01855         {"X3100",                       CARD_INTEL_965GM},  /* MacOS */
01856         {"946GZ",                       CARD_INTEL_946GZ},
01857         {"965G",                        CARD_INTEL_965G},
01858         {"965Q",                        CARD_INTEL_965Q},
01859         /* i945 */
01860         {"Pineview M",                  CARD_INTEL_PNVM},
01861         {"Pineview G",                  CARD_INTEL_PNVG},
01862         {"IGD",                         CARD_INTEL_PNVG},
01863         {"Q33",                         CARD_INTEL_Q33},
01864         {"G33",                         CARD_INTEL_G33},
01865         {"Q35",                         CARD_INTEL_Q35},
01866         {"945GME",                      CARD_INTEL_945GME},
01867         {"945GM",                       CARD_INTEL_945GM},
01868         {"GMA 950",                     CARD_INTEL_945GM},  /* MacOS */
01869         {"945G",                        CARD_INTEL_945G},
01870         /* i915 */
01871         {"915GM",                       CARD_INTEL_915GM},
01872         {"E7221G",                      CARD_INTEL_E7221G},
01873         {"915G",                        CARD_INTEL_915G},
01874         /* i8xx */
01875         {"865G",                        CARD_INTEL_865G},
01876         {"845G",                        CARD_INTEL_845G},
01877         {"855GM",                       CARD_INTEL_855GM},
01878         {"830M",                        CARD_INTEL_830M},
01879     };
01880 
01881     for (i = 0; i < sizeof(cards) / sizeof(*cards); ++i)
01882     {
01883         if (strstr(gl_renderer, cards[i].renderer))
01884             return cards[i].id;
01885     }
01886 
01887     return CARD_INTEL_915G;
01888 }
01889 
01890 static enum wined3d_pci_device select_card_amd_mesa(const struct wined3d_gl_info *gl_info,
01891         const char *gl_renderer)
01892 {
01893     UINT d3d_level;
01894     unsigned int i;
01895 
01896     /* See http://developer.amd.com/drivers/pc_vendor_id/Pages/default.aspx
01897      *
01898      * Beware: renderer string do not match exact card model,
01899      * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */
01900     if (strstr(gl_renderer, "Gallium"))
01901     {
01902         /* 20101109 - These are never returned by current Gallium radeon
01903          * drivers: R700, RV790, R680, RV535, RV516, R410, RS485, RV360, RV351.
01904          *
01905          * These are returned but not handled: RC410, RV380. */
01906         static const struct
01907         {
01908             const char *renderer;
01909             enum wined3d_pci_device id;
01910         }
01911         cards[] =
01912         {
01913             /* Northern Islands */
01914             {"CAYMAN",  CARD_AMD_RADEON_HD6900},
01915             {"BARTS",   CARD_AMD_RADEON_HD6800},
01916             {"TURKS",   CARD_AMD_RADEON_HD6600},
01917             {"SUMO2",   CARD_AMD_RADEON_HD6410D},   /* SUMO2 first, because we do a strstr(). */
01918             {"SUMO",    CARD_AMD_RADEON_HD6550D},
01919             {"CAICOS",  CARD_AMD_RADEON_HD6400},
01920             {"PALM",    CARD_AMD_RADEON_HD6300},
01921             /* Evergreen */
01922             {"HEMLOCK", CARD_AMD_RADEON_HD5900},
01923             {"CYPRESS", CARD_AMD_RADEON_HD5800},
01924             {"JUNIPER", CARD_AMD_RADEON_HD5700},
01925             {"REDWOOD", CARD_AMD_RADEON_HD5600},
01926             {"CEDAR",   CARD_AMD_RADEON_HD5400},
01927             /* R700 */
01928             {"R700",    CARD_AMD_RADEON_HD4800},    /* HD4800 - highend */
01929             {"RV790",   CARD_AMD_RADEON_HD4800},
01930             {"RV770",   CARD_AMD_RADEON_HD4800},
01931             {"RV740",   CARD_AMD_RADEON_HD4700},    /* HD4700 - midend */
01932             {"RV730",   CARD_AMD_RADEON_HD4600},    /* HD4600 - midend */
01933             {"RV710",   CARD_AMD_RADEON_HD4350},    /* HD4500/HD4350 - lowend */
01934             /* R600/R700 integrated */
01935             {"RS880",   CARD_AMD_RADEON_HD3200},
01936             {"RS780",   CARD_AMD_RADEON_HD3200},
01937             /* R600 */
01938             {"R680",    CARD_AMD_RADEON_HD2900},    /* HD2900/HD3800 - highend */
01939             {"R600",    CARD_AMD_RADEON_HD2900},
01940             {"RV670",   CARD_AMD_RADEON_HD2900},
01941             {"RV635",   CARD_AMD_RADEON_HD2600},    /* HD2600/HD3600 - midend; HD3830 is China-only midend */
01942             {"RV630",   CARD_AMD_RADEON_HD2600},
01943             {"RV620",   CARD_AMD_RADEON_HD2350},    /* HD2350/HD2400/HD3400 - lowend */
01944             {"RV610",   CARD_AMD_RADEON_HD2350},
01945             /* R500 */
01946             {"R580",    CARD_AMD_RADEON_X1600},
01947             {"R520",    CARD_AMD_RADEON_X1600},
01948             {"RV570",   CARD_AMD_RADEON_X1600},
01949             {"RV560",   CARD_AMD_RADEON_X1600},
01950             {"RV535",   CARD_AMD_RADEON_X1600},
01951             {"RV530",   CARD_AMD_RADEON_X1600},
01952             {"RV516",   CARD_AMD_RADEON_X700},      /* X700 is actually R400. */
01953             {"RV515",   CARD_AMD_RADEON_X700},
01954             /* R400 */
01955             {"R481",    CARD_AMD_RADEON_X700},
01956             {"R480",    CARD_AMD_RADEON_X700},
01957             {"R430",    CARD_AMD_RADEON_X700},
01958             {"R423",    CARD_AMD_RADEON_X700},
01959             {"R420",    CARD_AMD_RADEON_X700},
01960             {"R410",    CARD_AMD_RADEON_X700},
01961             {"RV410",   CARD_AMD_RADEON_X700},
01962             /* Radeon Xpress - onboard, DX9b, Shader 2.0, 300-400MHz */
01963             {"RS740",   CARD_AMD_RADEON_XPRESS_200M},
01964             {"RS690",   CARD_AMD_RADEON_XPRESS_200M},
01965             {"RS600",   CARD_AMD_RADEON_XPRESS_200M},
01966             {"RS485",   CARD_AMD_RADEON_XPRESS_200M},
01967             {"RS482",   CARD_AMD_RADEON_XPRESS_200M},
01968             {"RS480",   CARD_AMD_RADEON_XPRESS_200M},
01969             {"RS400",   CARD_AMD_RADEON_XPRESS_200M},
01970             /* R300 */
01971             {"R360",    CARD_AMD_RADEON_9500},
01972             {"R350",    CARD_AMD_RADEON_9500},
01973             {"R300",    CARD_AMD_RADEON_9500},
01974             {"RV370",   CARD_AMD_RADEON_9500},
01975             {"RV360",   CARD_AMD_RADEON_9500},
01976             {"RV351",   CARD_AMD_RADEON_9500},
01977             {"RV350",   CARD_AMD_RADEON_9500},
01978         };
01979 
01980         for (i = 0; i < sizeof(cards) / sizeof(*cards); ++i)
01981         {
01982             if (strstr(gl_renderer, cards[i].renderer))
01983                 return cards[i].id;
01984         }
01985     }
01986 
01987     d3d_level = d3d_level_from_gl_info(gl_info);
01988     if (d3d_level >= 10)
01989         return CARD_AMD_RADEON_HD2600;
01990 
01991     if (d3d_level >= 9)
01992     {
01993         static const struct
01994         {
01995             const char *renderer;
01996             enum wined3d_pci_device id;
01997         }
01998         cards[] =
01999         {
02000             /* R700 */
02001             {"(R700",   CARD_AMD_RADEON_HD4800},    /* HD4800 - highend */
02002             {"(RV790",  CARD_AMD_RADEON_HD4800},
02003             {"(RV770",  CARD_AMD_RADEON_HD4800},
02004             {"(RV740",  CARD_AMD_RADEON_HD4700},    /* HD4700 - midend */
02005             {"(RV730",  CARD_AMD_RADEON_HD4600},    /* HD4600 - midend */
02006             {"(RV710",  CARD_AMD_RADEON_HD4350},    /* HD4500/HD4350 - lowend */
02007             /* R600/R700 integrated */
02008             {"RS880",   CARD_AMD_RADEON_HD3200},
02009             {"RS780",   CARD_AMD_RADEON_HD3200},
02010             /* R600 */
02011             {"(R680",   CARD_AMD_RADEON_HD2900},    /* HD2900/HD3800 - highend */
02012             {"(R600",   CARD_AMD_RADEON_HD2900},
02013             {"(RV670",  CARD_AMD_RADEON_HD2900},
02014             {"(RV635",  CARD_AMD_RADEON_HD2600},    /* HD2600/HD3600 - midend; HD3830 is China-only midend */
02015             {"(RV630",  CARD_AMD_RADEON_HD2600},
02016             {"(RV620",  CARD_AMD_RADEON_HD2350},    /* HD2300/HD2400/HD3400 - lowend */
02017             {"(RV610",  CARD_AMD_RADEON_HD2350},
02018         };
02019 
02020         for (i = 0; i < sizeof(cards) / sizeof(*cards); ++i)
02021         {
02022             if (strstr(gl_renderer, cards[i].renderer))
02023                 return cards[i].id;
02024         }
02025 
02026         return CARD_AMD_RADEON_9500;
02027     }
02028 
02029     if (d3d_level >= 8)
02030         return CARD_AMD_RADEON_8500; /* Radeon 8500/9000/9100/9200/9300 */
02031 
02032     if (d3d_level >= 7)
02033         return CARD_AMD_RADEON_7200; /* Radeon 7000/7100/7200/7500 */
02034 
02035     return CARD_AMD_RAGE_128PRO;
02036 }
02037 
02038 static enum wined3d_pci_device select_card_nvidia_mesa(const struct wined3d_gl_info *gl_info,
02039         const char *gl_renderer)
02040 {
02041     UINT d3d_level;
02042 
02043     if (strstr(gl_renderer, "Gallium"))
02044     {
02045         unsigned int i;
02046 
02047         static const struct
02048         {
02049             const char *renderer;
02050             enum wined3d_pci_device id;
02051         }
02052         cards[] =
02053         {
02054             {"NVC8",    CARD_NVIDIA_GEFORCE_GTX570},
02055             {"NVC4",    CARD_NVIDIA_GEFORCE_GTX460},
02056             {"NVC3",    CARD_NVIDIA_GEFORCE_GT440},
02057             {"NVC0",    CARD_NVIDIA_GEFORCE_GTX480},
02058             {"NVAF",    CARD_NVIDIA_GEFORCE_GT320M},
02059             {"NVAC",    CARD_NVIDIA_GEFORCE_8200},
02060             {"NVAA",    CARD_NVIDIA_GEFORCE_8200},
02061             {"NVA8",    CARD_NVIDIA_GEFORCE_210},
02062             {"NVA5",    CARD_NVIDIA_GEFORCE_GT220},
02063             {"NVA3",    CARD_NVIDIA_GEFORCE_GT240},
02064             {"NVA0",    CARD_NVIDIA_GEFORCE_GTX280},
02065             {"NV98",    CARD_NVIDIA_GEFORCE_9200},
02066             {"NV96",    CARD_NVIDIA_GEFORCE_9400GT},
02067             {"NV94",    CARD_NVIDIA_GEFORCE_9600GT},
02068             {"NV92",    CARD_NVIDIA_GEFORCE_9800GT},
02069             {"NV86",    CARD_NVIDIA_GEFORCE_8500GT},
02070             {"NV84",    CARD_NVIDIA_GEFORCE_8600GT},
02071             {"NV68",    CARD_NVIDIA_GEFORCE_6200},      /* 7050 */
02072             {"NV67",    CARD_NVIDIA_GEFORCE_6200},      /* 7000M */
02073             {"NV63",    CARD_NVIDIA_GEFORCE_6200},      /* 7100 */
02074             {"NV50",    CARD_NVIDIA_GEFORCE_8800GTX},
02075             {"NV4E",    CARD_NVIDIA_GEFORCE_6200},      /* 6100 Go / 6150 Go */
02076             {"NV4C",    CARD_NVIDIA_GEFORCE_6200},      /* 6150SE */
02077             {"NV4B",    CARD_NVIDIA_GEFORCE_7600},
02078             {"NV4A",    CARD_NVIDIA_GEFORCE_6200},
02079             {"NV49",    CARD_NVIDIA_GEFORCE_7800GT},    /* 7900 */
02080             {"NV47",    CARD_NVIDIA_GEFORCE_7800GT},
02081             {"NV46",    CARD_NVIDIA_GEFORCE_7400},
02082             {"NV45",    CARD_NVIDIA_GEFORCE_6800},
02083             {"NV44",    CARD_NVIDIA_GEFORCE_6200},
02084             {"NV43",    CARD_NVIDIA_GEFORCE_6600GT},
02085             {"NV42",    CARD_NVIDIA_GEFORCE_6800},
02086             {"NV41",    CARD_NVIDIA_GEFORCE_6800},
02087             {"NV40",    CARD_NVIDIA_GEFORCE_6800},
02088             {"NV38",    CARD_NVIDIA_GEFORCEFX_5800},    /* FX 5950 Ultra */
02089             {"NV36",    CARD_NVIDIA_GEFORCEFX_5800},    /* FX 5700/5750 */
02090             {"NV35",    CARD_NVIDIA_GEFORCEFX_5800},    /* FX 5900 */
02091             {"NV34",    CARD_NVIDIA_GEFORCEFX_5200},
02092             {"NV31",    CARD_NVIDIA_GEFORCEFX_5600},
02093             {"NV30",    CARD_NVIDIA_GEFORCEFX_5800},
02094             {"NV28",    CARD_NVIDIA_GEFORCE4_TI4200},
02095             {"NV25",    CARD_NVIDIA_GEFORCE4_TI4200},
02096             {"NV20",    CARD_NVIDIA_GEFORCE3},
02097             {"NV1F",    CARD_NVIDIA_GEFORCE4_MX},       /* GF4 MX IGP */
02098             {"NV1A",    CARD_NVIDIA_GEFORCE2},          /* GF2 IGP */
02099             {"NV18",    CARD_NVIDIA_GEFORCE4_MX},
02100             {"NV17",    CARD_NVIDIA_GEFORCE4_MX},
02101             {"NV16",    CARD_NVIDIA_GEFORCE2},
02102             {"NV15",    CARD_NVIDIA_GEFORCE2},
02103             {"NV11",    CARD_NVIDIA_GEFORCE2_MX},
02104             {"NV10",    CARD_NVIDIA_GEFORCE},
02105             {"NV05",    CARD_NVIDIA_RIVA_TNT2},
02106             {"NV04",    CARD_NVIDIA_RIVA_TNT},
02107             {"NV03",    CARD_NVIDIA_RIVA_128},
02108         };
02109 
02110         for (i = 0; i < sizeof(cards) / sizeof(*cards); ++i)
02111         {
02112             if (strstr(gl_renderer, cards[i].renderer))
02113                 return cards[i].id;
02114         }
02115     }
02116 
02117     FIXME_(d3d_caps)("Unknown renderer %s.\n", debugstr_a(gl_renderer));
02118 
02119     d3d_level = d3d_level_from_gl_info(gl_info);
02120     if (d3d_level >= 9)
02121         return CARD_NVIDIA_GEFORCEFX_5600;
02122     if (d3d_level >= 8)
02123         return CARD_NVIDIA_GEFORCE3;
02124     if (d3d_level >= 7)
02125         return CARD_NVIDIA_GEFORCE;
02126     if (d3d_level >= 6)
02127         return CARD_NVIDIA_RIVA_TNT;
02128     return CARD_NVIDIA_RIVA_128;
02129 }
02130 
02131 
02132 struct vendor_card_selection
02133 {
02134     enum wined3d_gl_vendor gl_vendor;
02135     enum wined3d_pci_vendor card_vendor;
02136     const char *description;        /* Description of the card selector i.e. Apple OS/X Intel */
02137     enum wined3d_pci_device (*select_card)(const struct wined3d_gl_info *gl_info, const char *gl_renderer);
02138 };
02139 
02140 static const struct vendor_card_selection vendor_card_select_table[] =
02141 {
02142     {GL_VENDOR_NVIDIA, HW_VENDOR_NVIDIA,  "Nvidia binary driver",     select_card_nvidia_binary},
02143     {GL_VENDOR_APPLE,  HW_VENDOR_NVIDIA,  "Apple OSX NVidia binary driver",   select_card_nvidia_binary},
02144     {GL_VENDOR_APPLE,  HW_VENDOR_AMD,     "Apple OSX AMD/ATI binary driver",  select_card_amd_binary},
02145     {GL_VENDOR_APPLE,  HW_VENDOR_INTEL,   "Apple OSX Intel binary driver",    select_card_intel},
02146     {GL_VENDOR_FGLRX,  HW_VENDOR_AMD,     "AMD/ATI binary driver",    select_card_amd_binary},
02147     {GL_VENDOR_MESA,   HW_VENDOR_AMD,     "Mesa AMD/ATI driver",      select_card_amd_mesa},
02148     {GL_VENDOR_MESA,   HW_VENDOR_NVIDIA,  "Mesa Nouveau driver",      select_card_nvidia_mesa},
02149     {GL_VENDOR_MESA,   HW_VENDOR_INTEL,   "Mesa Intel driver",        select_card_intel},
02150     {GL_VENDOR_INTEL,  HW_VENDOR_INTEL,   "Mesa Intel driver",        select_card_intel}
02151 };
02152 
02153 
02154 static enum wined3d_pci_device wined3d_guess_card(const struct wined3d_gl_info *gl_info, const char *gl_renderer,
02155         enum wined3d_gl_vendor *gl_vendor, enum wined3d_pci_vendor *card_vendor)
02156 {
02157     UINT d3d_level;
02158 
02159     /* Above is a list of Nvidia and ATI GPUs. Both vendors have dozens of
02160      * different GPUs with roughly the same features. In most cases GPUs from a
02161      * certain family differ in clockspeeds, the amount of video memory and the
02162      * number of shader pipelines.
02163      *
02164      * A Direct3D device object contains the PCI id (vendor + device) of the
02165      * videocard which is used for rendering. Various applications use this
02166      * information to get a rough estimation of the features of the card and
02167      * some might use it for enabling 3d effects only on certain types of
02168      * videocards. In some cases games might even use it to work around bugs
02169      * which happen on certain videocards/driver combinations. The problem is
02170      * that OpenGL only exposes a rendering string containing the name of the
02171      * videocard and not the PCI id.
02172      *
02173      * Various games depend on the PCI id, so somehow we need to provide one.
02174      * A simple option is to parse the renderer string and translate this to
02175      * the right PCI id. This is a lot of work because there are more than 200
02176      * GPUs just for Nvidia. Various cards share the same renderer string, so
02177      * the amount of code might be 'small' but there are quite a number of
02178      * exceptions which would make this a pain to maintain. Another way would
02179      * be to query the PCI id from the operating system (assuming this is the
02180      * videocard which is used for rendering which is not always the case).
02181      * This would work but it is not very portable. Second it would not work
02182      * well in, let's say, a remote X situation in which the amount of 3d
02183      * features which can be used is limited.
02184      *
02185      * As said most games only use the PCI id to get an indication of the
02186      * capabilities of the card. It doesn't really matter if the given id is
02187      * the correct one if we return the id of a card with similar 3d features.
02188      *
02189      * The code below checks the OpenGL capabilities of a videocard and matches
02190      * that to a certain level of Direct3D functionality. Once a card passes
02191      * the Direct3D9 check, we know that the card (in case of Nvidia) is at
02192      * least a GeforceFX. To give a better estimate we do a basic check on the
02193      * renderer string but if that won't pass we return a default card. This
02194      * way is better than maintaining a full card database as even without a
02195      * full database we can return a card with similar features. Second the
02196      * size of the database can be made quite small because when you know what
02197      * type of 3d functionality a card has, you know to which GPU family the
02198      * GPU must belong. Because of this you only have to check a small part of
02199      * the renderer string to distinguishes between different models from that
02200      * family.
02201      *
02202      * The code also selects a default amount of video memory which we will
02203      * use for an estimation of the amount of free texture memory. In case of
02204      * real D3D the amount of texture memory includes video memory and system
02205      * memory (to be specific AGP memory or in case of PCIE TurboCache /
02206      * HyperMemory). We don't know how much system memory can be addressed by
02207      * the system but we can make a reasonable estimation about the amount of
02208      * video memory. If the value is slightly wrong it doesn't matter as we
02209      * didn't include AGP-like memory which makes the amount of addressable
02210      * memory higher and second OpenGL isn't that critical it moves to system
02211      * memory behind our backs if really needed. Note that the amount of video
02212      * memory can be overruled using a registry setting. */
02213 
02214     int i;
02215 
02216     for (i = 0; i < (sizeof(vendor_card_select_table) / sizeof(*vendor_card_select_table)); ++i)
02217     {
02218         if ((vendor_card_select_table[i].gl_vendor != *gl_vendor)
02219             || (vendor_card_select_table[i].card_vendor != *card_vendor))
02220                 continue;
02221         TRACE_(d3d_caps)("Applying card_selector \"%s\".\n", vendor_card_select_table[i].description);
02222         return vendor_card_select_table[i].select_card(gl_info, gl_renderer);
02223     }
02224 
02225     FIXME_(d3d_caps)("No card selector available for GL vendor %#x and card vendor %04x (using GL_RENDERER %s).\n",
02226             *gl_vendor, *card_vendor, debugstr_a(gl_renderer));
02227 
02228     /* Default to generic Nvidia hardware based on the supported OpenGL extensions. The choice
02229      * for Nvidia was because the hardware and drivers they make are of good quality. This makes
02230      * them a good generic choice. */
02231     *card_vendor = HW_VENDOR_NVIDIA;
02232     d3d_level = d3d_level_from_gl_info(gl_info);
02233     if (d3d_level >= 9)
02234         return CARD_NVIDIA_GEFORCEFX_5600;
02235     if (d3d_level >= 8)
02236         return CARD_NVIDIA_GEFORCE3;
02237     if (d3d_level >= 7)
02238         return CARD_NVIDIA_GEFORCE;
02239     if (d3d_level >= 6)
02240         return CARD_NVIDIA_RIVA_TNT;
02241     return CARD_NVIDIA_RIVA_128;
02242 }
02243 
02244 static const struct fragment_pipeline *select_fragment_implementation(const struct wined3d_gl_info *gl_info)
02245 {
02246     int vs_selected_mode, ps_selected_mode;
02247 
02248     select_shader_mode(gl_info, &ps_selected_mode, &vs_selected_mode);
02249     if ((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL)
02250             && gl_info->supported[ARB_FRAGMENT_PROGRAM]) return &arbfp_fragment_pipeline;
02251     else if (ps_selected_mode == SHADER_ATI) return &atifs_fragment_pipeline;
02252     else if (gl_info->supported[NV_REGISTER_COMBINERS]
02253             && gl_info->supported[NV_TEXTURE_SHADER2]) return &nvts_fragment_pipeline;
02254     else if (gl_info->supported[NV_REGISTER_COMBINERS]) return &nvrc_fragment_pipeline;
02255     else return &ffp_fragment_pipeline;
02256 }
02257 
02258 static const struct wined3d_shader_backend_ops *select_shader_backend(const struct wined3d_gl_info *gl_info)
02259 {
02260     int vs_selected_mode, ps_selected_mode;
02261 
02262     select_shader_mode(gl_info, &ps_selected_mode, &vs_selected_mode);
02263     if (vs_selected_mode == SHADER_GLSL || ps_selected_mode == SHADER_GLSL) return &glsl_shader_backend;
02264     if (vs_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_ARB) return &arb_program_shader_backend;
02265     return &none_shader_backend;
02266 }
02267 
02268 static const struct blit_shader *select_blit_implementation(const struct wined3d_gl_info *gl_info)
02269 {
02270     int vs_selected_mode, ps_selected_mode;
02271 
02272     select_shader_mode(gl_info, &ps_selected_mode, &vs_selected_mode);
02273     if ((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL)
02274             && gl_info->supported[ARB_FRAGMENT_PROGRAM]) return &arbfp_blit;
02275     else return &ffp_blit;
02276 }
02277 
02278 static void load_gl_funcs(struct wined3d_gl_info *gl_info, DWORD gl_version)
02279 {
02280     DWORD ver;
02281 
02282 #define USE_GL_FUNC(type, pfn, ext, replace) \
02283     if (gl_info->supported[ext]) gl_info->pfn = (type)pwglGetProcAddress(#pfn); \
02284     else if ((ver = ver_for_ext(ext)) && ver <= gl_version) gl_info->pfn = (type)pwglGetProcAddress(#replace); \
02285     else gl_info->pfn = NULL;
02286 
02287     GL_EXT_FUNCS_GEN;
02288 #undef USE_GL_FUNC
02289 
02290 #define USE_GL_FUNC(type, pfn, ext, replace) gl_info->pfn = (type)pwglGetProcAddress(#pfn);
02291     WGL_EXT_FUNCS_GEN;
02292 #undef USE_GL_FUNC
02293 }
02294 
02295 /* Context activation is done by the caller. */
02296 static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
02297 {
02298     struct wined3d_driver_info *driver_info = &adapter->driver_info;
02299     struct wined3d_gl_info *gl_info = &adapter->gl_info;
02300     const char *GL_Extensions    = NULL;
02301     const char *WGL_Extensions   = NULL;
02302     const char *gl_vendor_str, *gl_renderer_str, *gl_version_str;
02303     struct fragment_caps fragment_caps;
02304     enum wined3d_gl_vendor gl_vendor;
02305     enum wined3d_pci_vendor card_vendor;
02306     enum wined3d_pci_device device;
02307     GLint       gl_max;
02308     GLfloat     gl_floatv[2];
02309     unsigned    i;
02310     HDC         hdc;
02311     DWORD gl_version;
02312     size_t len;
02313 
02314     TRACE_(d3d_caps)("(%p)\n", gl_info);
02315 
02316     ENTER_GL();
02317 
02318     gl_renderer_str = (const char *)glGetString(GL_RENDERER);
02319     TRACE_(d3d_caps)("GL_RENDERER: %s.\n", debugstr_a(gl_renderer_str));
02320     if (!gl_renderer_str)
02321     {
02322         LEAVE_GL();
02323         ERR_(d3d_caps)("Received a NULL GL_RENDERER.\n");
02324         return FALSE;
02325     }
02326 
02327     gl_vendor_str = (const char *)glGetString(GL_VENDOR);
02328     TRACE_(d3d_caps)("GL_VENDOR: %s.\n", debugstr_a(gl_vendor_str));
02329     if (!gl_vendor_str)
02330     {
02331         LEAVE_GL();
02332         ERR_(d3d_caps)("Received a NULL GL_VENDOR.\n");
02333         return FALSE;
02334     }
02335 
02336     /* Parse the GL_VERSION field into major and minor information */
02337     gl_version_str = (const char *)glGetString(GL_VERSION);
02338     TRACE_(d3d_caps)("GL_VERSION: %s.\n", debugstr_a(gl_version_str));
02339     if (!gl_version_str)
02340     {
02341         LEAVE_GL();
02342         ERR_(d3d_caps)("Received a NULL GL_VERSION.\n");
02343         return FALSE;
02344     }
02345     gl_version = wined3d_parse_gl_version(gl_version_str);
02346 
02347     /*
02348      * Initialize openGL extension related variables
02349      *  with Default values
02350      */
02351     memset(gl_info->supported, 0, sizeof(gl_info->supported));
02352     gl_info->limits.blends = 1;
02353     gl_info->limits.buffers = 1;
02354     gl_info->limits.textures = 1;
02355     gl_info->limits.texture_coords = 1;
02356     gl_info->limits.fragment_samplers = 1;
02357     gl_info->limits.vertex_samplers = 0;
02358     gl_info->limits.combined_samplers = gl_info->limits.fragment_samplers + gl_info->limits.vertex_samplers;
02359     gl_info->limits.sampler_stages = 1;
02360     gl_info->limits.vertex_attribs = 16;
02361     gl_info->limits.glsl_vs_float_constants = 0;
02362     gl_info->limits.glsl_ps_float_constants = 0;
02363     gl_info->limits.arb_vs_float_constants = 0;
02364     gl_info->limits.arb_vs_native_constants = 0;
02365     gl_info->limits.arb_vs_instructions = 0;
02366     gl_info->limits.arb_vs_temps = 0;
02367     gl_info->limits.arb_ps_float_constants = 0;
02368     gl_info->limits.arb_ps_local_constants = 0;
02369     gl_info->limits.arb_ps_instructions = 0;
02370     gl_info->limits.arb_ps_temps = 0;
02371 
02372     /* Retrieve opengl defaults */
02373     glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
02374     gl_info->limits.clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max);
02375     TRACE_(d3d_caps)("ClipPlanes support - num Planes=%d\n", gl_max);
02376 
02377     glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
02378     gl_info->limits.lights = gl_max;
02379     TRACE_(d3d_caps)("Lights support - max lights=%d\n", gl_max);
02380 
02381     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max);
02382     gl_info->limits.texture_size = gl_max;
02383     TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
02384 
02385     glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv);
02386     gl_info->limits.pointsize_min = gl_floatv[0];
02387     gl_info->limits.pointsize_max = gl_floatv[1];
02388     TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
02389 
02390     /* Parse the gl supported features, in theory enabling parts of our code appropriately. */
02391     GL_Extensions = (const char *)glGetString(GL_EXTENSIONS);
02392     if (!GL_Extensions)
02393     {
02394         LEAVE_GL();
02395         ERR_(d3d_caps)("Received a NULL GL_EXTENSIONS.\n");
02396         return FALSE;
02397     }
02398 
02399     LEAVE_GL();
02400 
02401     TRACE_(d3d_caps)("GL_Extensions reported:\n");
02402 
02403     gl_info->supported[WINED3D_GL_EXT_NONE] = TRUE;
02404 
02405     while (*GL_Extensions)
02406     {
02407         const char *start;
02408 
02409         while (isspace(*GL_Extensions)) ++GL_Extensions;
02410         start = GL_Extensions;
02411         while (!isspace(*GL_Extensions) && *GL_Extensions) ++GL_Extensions;
02412 
02413         len = GL_Extensions - start;
02414         if (!len) continue;
02415 
02416         TRACE_(d3d_caps)("- %s\n", debugstr_an(start, len));
02417 
02418         for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i)
02419         {
02420             if (len == strlen(EXTENSION_MAP[i].extension_string)
02421                     && !memcmp(start, EXTENSION_MAP[i].extension_string, len))
02422             {
02423                 TRACE_(d3d_caps)(" FOUND: %s support.\n", EXTENSION_MAP[i].extension_string);
02424                 gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
02425                 break;
02426             }
02427         }
02428     }
02429 
02430     /* Now work out what GL support this card really has */
02431     load_gl_funcs( gl_info, gl_version );
02432 
02433     ENTER_GL();
02434 
02435     /* Now mark all the extensions supported which are included in the opengl core version. Do this *after*
02436      * loading the functions, otherwise the code above will load the extension entry points instead of the
02437      * core functions, which may not work. */
02438     for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i)
02439     {
02440         if (!gl_info->supported[EXTENSION_MAP[i].extension]
02441                 && EXTENSION_MAP[i].version <= gl_version && EXTENSION_MAP[i].version)
02442         {
02443             TRACE_(d3d_caps)(" GL CORE: %s support.\n", EXTENSION_MAP[i].extension_string);
02444             gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
02445         }
02446     }
02447 
02448     if (gl_version >= MAKEDWORD_VERSION(2, 0)) gl_info->supported[WINED3D_GL_VERSION_2_0] = TRUE;
02449 
02450     if (gl_info->supported[APPLE_FENCE])
02451     {
02452         /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
02453          * The apple extension interacts with some other apple exts. Disable the NV
02454          * extension if the apple one is support to prevent confusion in other parts
02455          * of the code. */
02456         gl_info->supported[NV_FENCE] = FALSE;
02457     }
02458     if (gl_info->supported[APPLE_FLOAT_PIXELS])
02459     {
02460         /* GL_APPLE_float_pixels == GL_ARB_texture_float + GL_ARB_half_float_pixel
02461          *
02462          * The enums are the same:
02463          * GL_RGBA16F_ARB     = GL_RGBA_FLOAT16_APPLE = 0x881A
02464          * GL_RGB16F_ARB      = GL_RGB_FLOAT16_APPLE  = 0x881B
02465          * GL_RGBA32F_ARB     = GL_RGBA_FLOAT32_APPLE = 0x8814
02466          * GL_RGB32F_ARB      = GL_RGB_FLOAT32_APPLE  = 0x8815
02467          * GL_HALF_FLOAT_ARB  = GL_HALF_APPLE         = 0x140B
02468          */
02469         if (!gl_info->supported[ARB_TEXTURE_FLOAT])
02470         {
02471             TRACE_(d3d_caps)(" IMPLIED: GL_ARB_texture_float support(from GL_APPLE_float_pixels.\n");
02472             gl_info->supported[ARB_TEXTURE_FLOAT] = TRUE;
02473         }
02474         if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
02475         {
02476             TRACE_(d3d_caps)(" IMPLIED: GL_ARB_half_float_pixel support(from GL_APPLE_float_pixels.\n");
02477             gl_info->supported[ARB_HALF_FLOAT_PIXEL] = TRUE;
02478         }
02479     }
02480     if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
02481     {
02482         /* GL_ARB_map_buffer_range and GL_APPLE_flush_buffer_range provide the same
02483          * functionality. Prefer the ARB extension */
02484         gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] = FALSE;
02485     }
02486     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
02487     {
02488         TRACE_(d3d_caps)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support.\n");
02489         gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
02490     }
02491     if (!gl_info->supported[ARB_DEPTH_CLAMP] && gl_info->supported[NV_DEPTH_CLAMP])
02492     {
02493         TRACE_(d3d_caps)(" IMPLIED: ARB_depth_clamp support (by NV_depth_clamp).\n");
02494         gl_info->supported[ARB_DEPTH_CLAMP] = TRUE;
02495     }
02496     if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] && gl_info->supported[EXT_VERTEX_ARRAY_BGRA])
02497     {
02498         TRACE_(d3d_caps)(" IMPLIED: ARB_vertex_array_bgra support (by EXT_vertex_array_bgra).\n");
02499         gl_info->supported[ARB_VERTEX_ARRAY_BGRA] = TRUE;
02500     }
02501     if (!gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] && gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
02502     {
02503         TRACE_(d3d_caps)(" IMPLIED: ARB_texture_compression_rgtc support (by EXT_texture_compression_rgtc).\n");
02504         gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] = TRUE;
02505     }
02506     if (gl_info->supported[NV_TEXTURE_SHADER2])
02507     {
02508         if (gl_info->supported[NV_REGISTER_COMBINERS])
02509         {
02510             /* Also disable ATI_FRAGMENT_SHADER if register combiners and texture_shader2
02511              * are supported. The nv extensions provide the same functionality as the
02512              * ATI one, and a bit more(signed pixelformats). */
02513             gl_info->supported[ATI_FRAGMENT_SHADER] = FALSE;
02514         }
02515     }
02516 
02517     if (gl_info->supported[ARB_MAP_BUFFER_ALIGNMENT])
02518     {
02519         glGetIntegerv(GL_MIN_MAP_BUFFER_ALIGNMENT, &gl_max);
02520         TRACE_(d3d_caps)("Minimum buffer map alignment: %d.\n", gl_max);
02521     }
02522     else
02523     {
02524         WARN_(d3d_caps)("Driver doesn't guarantee a minimum buffer map alignment.\n");
02525     }
02526     if (gl_info->supported[NV_REGISTER_COMBINERS])
02527     {
02528         glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &gl_max);
02529         gl_info->limits.general_combiners = gl_max;
02530         TRACE_(d3d_caps)("Max general combiners: %d.\n", gl_max);
02531     }
02532     if (gl_info->supported[ARB_DRAW_BUFFERS])
02533     {
02534         glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
02535         gl_info->limits.buffers = gl_max;
02536         TRACE_(d3d_caps)("Max draw buffers: %u.\n", gl_max);
02537     }
02538     if (gl_info->supported[ARB_MULTITEXTURE])
02539     {
02540         glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
02541         gl_info->limits.textures = min(MAX_TEXTURES, gl_max);
02542         TRACE_(d3d_caps)("Max textures: %d.\n", gl_info->limits.textures);
02543         glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &gl_max);
02544         gl_info->limits.texture_coords = min(MAX_TEXTURES, gl_max);
02545         TRACE_(d3d_caps)("Max texture coords: %d.\n", gl_info->limits.texture_coords);
02546 
02547         if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
02548         {
02549             GLint tmp;
02550             glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
02551             gl_info->limits.fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp);
02552         }
02553         else
02554         {
02555             gl_info->limits.fragment_samplers = max(gl_info->limits.fragment_samplers, gl_max);
02556         }
02557         TRACE_(d3d_caps)("Max fragment samplers: %d.\n", gl_info->limits.fragment_samplers);
02558 
02559         if (gl_info->supported[ARB_VERTEX_SHADER])
02560         {
02561             GLint tmp;
02562             glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
02563             gl_info->limits.vertex_samplers = tmp;
02564             glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp);
02565             gl_info->limits.combined_samplers = tmp;
02566             glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &tmp);
02567             gl_info->limits.vertex_attribs = tmp;
02568 
02569             /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
02570              * is known at shader link time. In a vertex shader + pixel shader combination this isn't
02571              * an issue because then the sampler setup only depends on the two shaders. If a pixel
02572              * shader is used with fixed function vertex processing we're fine too because fixed function
02573              * vertex processing doesn't use any samplers. If fixed function fragment processing is
02574              * used we have to make sure that all vertex sampler setups are valid together with all
02575              * possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES
02576              * <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards).
02577              * dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and
02578              * dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have
02579              * a fixed function pipeline anymore.
02580              *
02581              * So this is just a check to check that our assumption holds true. If not, write a warning
02582              * and reduce the number of vertex samplers or probably disable vertex texture fetch. */
02583             if (gl_info->limits.vertex_samplers && gl_info->limits.combined_samplers < 12
02584                     && MAX_TEXTURES + gl_info->limits.vertex_samplers > gl_info->limits.combined_samplers)
02585             {
02586                 FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers.\n",
02587                         gl_info->limits.vertex_samplers, gl_info->limits.combined_samplers);
02588                 FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers.\n");
02589                 if (gl_info->limits.combined_samplers > MAX_TEXTURES)
02590                     gl_info->limits.vertex_samplers = gl_info->limits.combined_samplers - MAX_TEXTURES;
02591                 else
02592                     gl_info->limits.vertex_samplers = 0;
02593             }
02594         }
02595         else
02596         {
02597             gl_info->limits.combined_samplers = gl_info->limits.fragment_samplers;
02598         }
02599         TRACE_(d3d_caps)("Max vertex samplers: %u.\n", gl_info->limits.vertex_samplers);
02600         TRACE_(d3d_caps)("Max combined samplers: %u.\n", gl_info->limits.combined_samplers);
02601     }
02602     if (gl_info->supported[ARB_VERTEX_BLEND])
02603     {
02604         glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
02605         gl_info->limits.blends = gl_max;
02606         TRACE_(d3d_caps)("Max blends: %u.\n", gl_info->limits.blends);
02607     }
02608     if (gl_info->supported[EXT_TEXTURE3D])
02609     {
02610         glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
02611         gl_info->limits.texture3d_size = gl_max;
02612         TRACE_(d3d_caps)("Max texture3D size: %d.\n", gl_info->limits.texture3d_size);
02613     }
02614     if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
02615     {
02616         glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
02617         gl_info->limits.anisotropy = gl_max;
02618         TRACE_(d3d_caps)("Max anisotropy: %d.\n", gl_info->limits.anisotropy);
02619     }
02620     if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
02621     {
02622         GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
02623         gl_info->limits.arb_ps_float_constants = gl_max;
02624         TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM float constants: %d.\n", gl_info->limits.arb_ps_float_constants);
02625         GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
02626         gl_info->limits.arb_ps_native_constants = gl_max;
02627         TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native float constants: %d.\n",
02628                 gl_info->limits.arb_ps_native_constants);
02629         GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
02630         gl_info->limits.arb_ps_temps = gl_max;
02631         TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_ps_temps);
02632         GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
02633         gl_info->limits.arb_ps_instructions = gl_max;
02634         TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM native instructions: %d.\n", gl_info->limits.arb_ps_instructions);
02635         GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &gl_max));
02636         gl_info->limits.arb_ps_local_constants = gl_max;
02637         TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM local parameters: %d.\n", gl_info->limits.arb_ps_instructions);
02638     }
02639     if (gl_info->supported[ARB_VERTEX_PROGRAM])
02640     {
02641         GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
02642         gl_info->limits.arb_vs_float_constants = gl_max;
02643         TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM float constants: %d.\n", gl_info->limits.arb_vs_float_constants);
02644         GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
02645         gl_info->limits.arb_vs_native_constants = gl_max;
02646         TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native float constants: %d.\n",
02647                 gl_info->limits.arb_vs_native_constants);
02648         GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
02649         gl_info->limits.arb_vs_temps = gl_max;
02650         TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_vs_temps);
02651         GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
02652         gl_info->limits.arb_vs_instructions = gl_max;
02653         TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM native instructions: %d.\n", gl_info->limits.arb_vs_instructions);
02654 
02655         if (test_arb_vs_offset_limit(gl_info)) gl_info->quirks |= WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT;
02656     }
02657     if (gl_info->supported[ARB_VERTEX_SHADER])
02658     {
02659         glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
02660         gl_info->limits.glsl_vs_float_constants = gl_max / 4;
02661         TRACE_(d3d_caps)("Max ARB_VERTEX_SHADER float constants: %u.\n", gl_info->limits.glsl_vs_float_constants);
02662     }
02663     if (gl_info->supported[ARB_FRAGMENT_SHADER])
02664     {
02665         glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
02666         gl_info->limits.glsl_ps_float_constants = gl_max / 4;
02667         TRACE_(d3d_caps)("Max ARB_FRAGMENT_SHADER float constants: %u.\n", gl_info->limits.glsl_ps_float_constants);
02668         glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max);
02669         gl_info->limits.glsl_varyings = gl_max;
02670         TRACE_(d3d_caps)("Max GLSL varyings: %u (%u 4 component varyings).\n", gl_max, gl_max / 4);
02671     }
02672     if (gl_info->supported[ARB_SHADING_LANGUAGE_100])
02673     {
02674         const char *str = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION_ARB);
02675         unsigned int major, minor;
02676 
02677         TRACE_(d3d_caps)("GLSL version string: %s.\n", debugstr_a(str));
02678 
02679         /* The format of the GLSL version string is "major.minor[.release] [vendor info]". */
02680         sscanf(str, "%u.%u", &major, &minor);
02681         gl_info->glsl_version = MAKEDWORD_VERSION(major, minor);
02682     }
02683     if (gl_info->supported[NV_LIGHT_MAX_EXPONENT])
02684     {
02685         glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess);
02686     }
02687     else
02688     {
02689         gl_info->limits.shininess = 128.0f;
02690     }
02691     if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
02692     {
02693         /* If we have full NP2 texture support, disable
02694          * GL_ARB_texture_rectangle because we will never use it.
02695          * This saves a few redundant glDisable calls. */
02696         gl_info->supported[ARB_TEXTURE_RECTANGLE] = FALSE;
02697     }
02698     if (gl_info->supported[ATI_FRAGMENT_SHADER])
02699     {
02700         /* Disable NV_register_combiners and fragment shader if this is supported.
02701          * generally the NV extensions are preferred over the ATI ones, and this
02702          * extension is disabled if register_combiners and texture_shader2 are both
02703          * supported. So we reach this place only if we have incomplete NV dxlevel 8
02704          * fragment processing support. */
02705         gl_info->supported[NV_REGISTER_COMBINERS] = FALSE;
02706         gl_info->supported[NV_REGISTER_COMBINERS2] = FALSE;
02707         gl_info->supported[NV_TEXTURE_SHADER] = FALSE;
02708         gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
02709     }
02710     if (gl_info->supported[NV_HALF_FLOAT])
02711     {
02712         /* GL_ARB_half_float_vertex is a subset of GL_NV_half_float. */
02713         gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE;
02714     }
02715     checkGLcall("extension detection");
02716 
02717     LEAVE_GL();
02718 
02719     adapter->fragment_pipe = select_fragment_implementation(gl_info);
02720     adapter->shader_backend = select_shader_backend(gl_info);
02721     adapter->blitter = select_blit_implementation(gl_info);
02722 
02723     adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
02724     gl_info->limits.texture_stages = fragment_caps.MaxTextureBlendStages;
02725     TRACE_(d3d_caps)("Max texture stages: %u.\n", gl_info->limits.texture_stages);
02726 
02727     /* In some cases the number of texture stages can be larger than the number
02728      * of samplers. The GF4 for example can use only 2 samplers (no fragment
02729      * shaders), but 8 texture stages (register combiners). */
02730     gl_info->limits.sampler_stages = max(gl_info->limits.fragment_samplers, gl_info->limits.texture_stages);
02731 
02732     if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
02733     {
02734         gl_info->fbo_ops.glIsRenderbuffer = gl_info->glIsRenderbuffer;
02735         gl_info->fbo_ops.glBindRenderbuffer = gl_info->glBindRenderbuffer;
02736         gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->glDeleteRenderbuffers;
02737         gl_info->fbo_ops.glGenRenderbuffers = gl_info->glGenRenderbuffers;
02738         gl_info->fbo_ops.glRenderbufferStorage = gl_info->glRenderbufferStorage;
02739         gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->glRenderbufferStorageMultisample;
02740         gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->glGetRenderbufferParameteriv;
02741         gl_info->fbo_ops.glIsFramebuffer = gl_info->glIsFramebuffer;
02742         gl_info->fbo_ops.glBindFramebuffer = gl_info->glBindFramebuffer;
02743         gl_info->fbo_ops.glDeleteFramebuffers = gl_info->glDeleteFramebuffers;
02744         gl_info->fbo_ops.glGenFramebuffers = gl_info->glGenFramebuffers;
02745         gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->glCheckFramebufferStatus;
02746         gl_info->fbo_ops.glFramebufferTexture1D = gl_info->glFramebufferTexture1D;
02747         gl_info->fbo_ops.glFramebufferTexture2D = gl_info->glFramebufferTexture2D;
02748         gl_info->fbo_ops.glFramebufferTexture3D = gl_info->glFramebufferTexture3D;
02749         gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->glFramebufferRenderbuffer;
02750         gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv = gl_info->glGetFramebufferAttachmentParameteriv;
02751         gl_info->fbo_ops.glBlitFramebuffer = gl_info->glBlitFramebuffer;
02752         gl_info->fbo_ops.glGenerateMipmap = gl_info->glGenerateMipmap;
02753         if (wined3d_settings.allow_multisampling)
02754         {
02755             glGetIntegerv(GL_MAX_SAMPLES, &gl_max);
02756             gl_info->limits.samples = gl_max;
02757         }
02758     }
02759     else
02760     {
02761         if (gl_info->supported[EXT_FRAMEBUFFER_OBJECT])
02762         {
02763             gl_info->fbo_ops.glIsRenderbuffer = gl_info->glIsRenderbufferEXT;
02764             gl_info->fbo_ops.glBindRenderbuffer = gl_info->glBindRenderbufferEXT;
02765             gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->glDeleteRenderbuffersEXT;
02766             gl_info->fbo_ops.glGenRenderbuffers = gl_info->glGenRenderbuffersEXT;
02767             gl_info->fbo_ops.glRenderbufferStorage = gl_info->glRenderbufferStorageEXT;
02768             gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->glGetRenderbufferParameterivEXT;
02769             gl_info->fbo_ops.glIsFramebuffer = gl_info->glIsFramebufferEXT;
02770             gl_info->fbo_ops.glBindFramebuffer = gl_info->glBindFramebufferEXT;
02771             gl_info->fbo_ops.glDeleteFramebuffers = gl_info->glDeleteFramebuffersEXT;
02772             gl_info->fbo_ops.glGenFramebuffers = gl_info->glGenFramebuffersEXT;
02773             gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->glCheckFramebufferStatusEXT;
02774             gl_info->fbo_ops.glFramebufferTexture1D = gl_info->glFramebufferTexture1DEXT;
02775             gl_info->fbo_ops.glFramebufferTexture2D = gl_info->glFramebufferTexture2DEXT;
02776             gl_info->fbo_ops.glFramebufferTexture3D = gl_info->glFramebufferTexture3DEXT;
02777             gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->glFramebufferRenderbufferEXT;
02778             gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv = gl_info->glGetFramebufferAttachmentParameterivEXT;
02779             gl_info->fbo_ops.glGenerateMipmap = gl_info->glGenerateMipmapEXT;
02780         }
02781         else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
02782         {
02783             WARN_(d3d_caps)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n");
02784             wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
02785         }
02786         if (gl_info->supported[EXT_FRAMEBUFFER_BLIT])
02787         {
02788             gl_info->fbo_ops.glBlitFramebuffer = gl_info->glBlitFramebufferEXT;
02789         }
02790         if (gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE])
02791         {
02792             gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->glRenderbufferStorageMultisampleEXT;
02793             if (wined3d_settings.allow_multisampling)
02794             {
02795                 glGetIntegerv(GL_MAX_SAMPLES, &gl_max);
02796                 gl_info->limits.samples = gl_max;
02797             }
02798         }
02799     }
02800 
02801     /* MRTs are currently only supported when FBOs are used. */
02802     if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
02803     {
02804         gl_info->limits.buffers = 1;
02805     }
02806 
02807     gl_vendor = wined3d_guess_gl_vendor(gl_info, gl_vendor_str, gl_renderer_str);
02808     card_vendor = wined3d_guess_card_vendor(gl_vendor_str, gl_renderer_str);
02809     TRACE_(d3d_caps)("found GL_VENDOR (%s)->(0x%04x/0x%04x)\n", debugstr_a(gl_vendor_str), gl_vendor, card_vendor);
02810 
02811     device = wined3d_guess_card(gl_info, gl_renderer_str, &gl_vendor, &card_vendor);
02812     TRACE_(d3d_caps)("FOUND (fake) card: 0x%x (vendor id), 0x%x (device id)\n", card_vendor, device);
02813 
02814     gl_info->wrap_lookup[WINED3D_TADDRESS_WRAP - WINED3D_TADDRESS_WRAP] = GL_REPEAT;
02815     gl_info->wrap_lookup[WINED3D_TADDRESS_MIRROR - WINED3D_TADDRESS_WRAP] =
02816             gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT;
02817     gl_info->wrap_lookup[WINED3D_TADDRESS_CLAMP - WINED3D_TADDRESS_WRAP] = GL_CLAMP_TO_EDGE;
02818     gl_info->wrap_lookup[WINED3D_TADDRESS_BORDER - WINED3D_TADDRESS_WRAP] =
02819             gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
02820     gl_info->wrap_lookup[WINED3D_TADDRESS_MIRROR_ONCE - WINED3D_TADDRESS_WRAP] =
02821             gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] ? GL_MIRROR_CLAMP_TO_EDGE_ATI : GL_REPEAT;
02822 
02823     /* Make sure there's an active HDC else the WGL extensions will fail */
02824     hdc = pwglGetCurrentDC();
02825     if (hdc) {
02826         /* Not all GL drivers might offer WGL extensions e.g. VirtualBox */
02827         if(GL_EXTCALL(wglGetExtensionsStringARB))
02828             WGL_Extensions = GL_EXTCALL(wglGetExtensionsStringARB(hdc));
02829 
02830         if (!WGL_Extensions)
02831         {
02832             ERR("   WGL_Extensions returns NULL\n");
02833         }
02834         else
02835         {
02836             TRACE_(d3d_caps)("WGL_Extensions reported:\n");
02837             while (*WGL_Extensions)
02838             {
02839                 const char *Start;
02840                 char ThisExtn[256];
02841 
02842                 while (isspace(*WGL_Extensions)) WGL_Extensions++;
02843                 Start = WGL_Extensions;
02844                 while (!isspace(*WGL_Extensions) && *WGL_Extensions) ++WGL_Extensions;
02845 
02846                 len = WGL_Extensions - Start;
02847                 if (!len || len >= sizeof(ThisExtn))
02848                     continue;
02849 
02850                 memcpy(ThisExtn, Start, len);
02851                 ThisExtn[len] = '\0';
02852                 TRACE_(d3d_caps)("- %s\n", debugstr_a(ThisExtn));
02853 
02854                 if (!strcmp(ThisExtn, "WGL_ARB_pixel_format")) {
02855                     gl_info->supported[WGL_ARB_PIXEL_FORMAT] = TRUE;
02856                     TRACE_(d3d_caps)("FOUND: WGL_ARB_pixel_format support\n");
02857                 }
02858                 if (!strcmp(ThisExtn, "WGL_EXT_swap_control")) {
02859                     gl_info->supported[WGL_EXT_SWAP_CONTROL] = TRUE;
02860                     TRACE_(d3d_caps)("FOUND: WGL_EXT_swap_control support\n");
02861                 }
02862                 if (!strcmp(ThisExtn, "WGL_WINE_pixel_format_passthrough")) {
02863                     gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH] = TRUE;
02864                     TRACE_(d3d_caps)("FOUND: WGL_WINE_pixel_format_passthrough support\n");
02865                 }
02866             }
02867         }
02868     }
02869 
02870     fixup_extensions(gl_info, gl_renderer_str, gl_vendor, card_vendor, device);
02871     init_driver_info(driver_info, card_vendor, device);
02872     add_gl_compat_wrappers(gl_info);
02873 
02874     return TRUE;
02875 }
02876 
02877 UINT CDECL wined3d_get_adapter_count(const struct wined3d *wined3d)
02878 {
02879     TRACE_(d3d_caps)("wined3d %p, reporting %u adapters.\n",
02880             wined3d, wined3d->adapter_count);
02881 
02882     return wined3d->adapter_count;
02883 }
02884 
02885 HRESULT CDECL wined3d_register_software_device(struct wined3d *wined3d, void *init_function)
02886 {
02887     FIXME("wined3d %p, init_function %p stub!\n", wined3d, init_function);
02888 
02889     return WINED3D_OK;
02890 }
02891 
02892 HMONITOR CDECL wined3d_get_adapter_monitor(const struct wined3d *wined3d, UINT adapter_idx)
02893 {
02894     TRACE_(d3d_caps)("wined3d %p, adapter_idx %u.\n", wined3d, adapter_idx);
02895 
02896     if (adapter_idx >= wined3d->adapter_count)
02897         return NULL;
02898 
02899     return MonitorFromPoint(wined3d->adapters[adapter_idx].monitorPoint, MONITOR_DEFAULTTOPRIMARY);
02900 }
02901 
02902 /* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
02903      of the same bpp but different resolutions                                  */
02904 
02905 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
02906 UINT CDECL wined3d_get_adapter_mode_count(const struct wined3d *wined3d, UINT adapter_idx,
02907         enum wined3d_format_id format_id)
02908 {
02909     TRACE_(d3d_caps)("wined3d %p, adapter_idx %u, format %s.\n", wined3d, adapter_idx, debug_d3dformat(format_id));
02910 
02911     if (adapter_idx >= wined3d->adapter_count)
02912         return 0;
02913 
02914     /* TODO: Store modes per adapter and read it from the adapter structure */
02915     if (!adapter_idx)
02916     {
02917         const struct wined3d_format *format = wined3d_get_format(&wined3d->adapters[adapter_idx].gl_info, format_id);
02918         UINT format_bits = format->byte_count * CHAR_BIT;
02919         unsigned int i = 0;
02920         unsigned int j = 0;
02921         DEVMODEW mode;
02922 
02923         memset(&mode, 0, sizeof(mode));
02924         mode.dmSize = sizeof(mode);
02925 
02926         while (EnumDisplaySettingsExW(NULL, j, &mode, 0))
02927         {
02928             ++j;
02929 
02930             if (format_id == WINED3DFMT_UNKNOWN)
02931             {
02932                 /* This is for D3D8, do not enumerate P8 here */
02933                 if (mode.dmBitsPerPel == 32 || mode.dmBitsPerPel == 16) ++i;
02934             }
02935             else if (mode.dmBitsPerPel == format_bits)
02936             {
02937                 ++i;
02938             }
02939         }
02940 
02941         TRACE_(d3d_caps)("Returning %u matching modes (out of %u total) for adapter %u.\n", i, j, adapter_idx);
02942 
02943         return i;
02944     }
02945     else
02946     {
02947         FIXME_(d3d_caps)("Adapter not primary display.\n");
02948     }
02949 
02950     return 0;
02951 }
02952 
02953 /* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
02954 HRESULT CDECL wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT adapter_idx,
02955         enum wined3d_format_id format_id, UINT mode_idx, struct wined3d_display_mode *mode)
02956 {
02957     TRACE_(d3d_caps)("wined3d %p, adapter_idx %u, format %s, mode_idx %u, mode %p.\n",
02958             wined3d, adapter_idx, debug_d3dformat(format_id), mode_idx, mode);
02959 
02960     /* Validate the parameters as much as possible */
02961     if (!mode || adapter_idx >= wined3d->adapter_count
02962             || mode_idx >= wined3d_get_adapter_mode_count(wined3d, adapter_idx, format_id))
02963     {
02964         return WINED3DERR_INVALIDCALL;
02965     }
02966 
02967     /* TODO: Store modes per adapter and read it from the adapter structure */
02968     if (!adapter_idx)
02969     {
02970         const struct wined3d_format *format = wined3d_get_format(&wined3d->adapters[adapter_idx].gl_info, format_id);
02971         UINT format_bits = format->byte_count * CHAR_BIT;
02972         DEVMODEW DevModeW;
02973         int ModeIdx = 0;
02974         UINT i = 0;
02975         int j = 0;
02976 
02977         ZeroMemory(&DevModeW, sizeof(DevModeW));
02978         DevModeW.dmSize = sizeof(DevModeW);
02979 
02980         /* If we are filtering to a specific format (D3D9), then need to skip
02981            all unrelated modes, but if mode is irrelevant (D3D8), then we can
02982            just count through the ones with valid bit depths */
02983         while (i <= mode_idx && EnumDisplaySettingsExW(NULL, j++, &DevModeW, 0))
02984         {
02985             if (format_id == WINED3DFMT_UNKNOWN)
02986             {
02987                 /* This is for D3D8, do not enumerate P8 here */
02988                 if (DevModeW.dmBitsPerPel == 32 || DevModeW.dmBitsPerPel == 16) ++i;
02989             }
02990             else if (DevModeW.dmBitsPerPel == format_bits)
02991             {
02992                 ++i;
02993             }
02994         }
02995 
02996         if (!i)
02997         {
02998             TRACE_(d3d_caps)("No modes found for format (%x - %s)\n", format_id, debug_d3dformat(format_id));
02999             return WINED3DERR_INVALIDCALL;
03000         }
03001         ModeIdx = j - 1;
03002 
03003         /* Now get the display mode via the calculated index */
03004         if (EnumDisplaySettingsExW(NULL, ModeIdx, &DevModeW, 0))
03005         {
03006             mode->width = DevModeW.dmPelsWidth;
03007             mode->height = DevModeW.dmPelsHeight;
03008             mode->refresh_rate = DEFAULT_REFRESH_RATE;
03009             if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
03010                 mode->refresh_rate = DevModeW.dmDisplayFrequency;
03011 
03012             if (format_id == WINED3DFMT_UNKNOWN)
03013                 mode->format_id = pixelformat_for_depth(DevModeW.dmBitsPerPel);
03014             else
03015                 mode->format_id = format_id;
03016         }
03017         else
03018         {
03019             TRACE_(d3d_caps)("Requested mode %u out of range.\n", mode_idx);
03020             return WINED3DERR_INVALIDCALL;
03021         }
03022 
03023         TRACE_(d3d_caps)("W %d H %d rr %d fmt (%x - %s) bpp %u\n",
03024                 mode->width, mode->height, mode->refresh_rate, mode->format_id,
03025                 debug_d3dformat(mode->format_id), DevModeW.dmBitsPerPel);
03026     }
03027     else
03028     {
03029         FIXME_(d3d_caps)("Adapter not primary display\n");
03030     }
03031 
03032     return WINED3D_OK;
03033 }
03034 
03035 HRESULT CDECL wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UINT adapter_idx,
03036         struct wined3d_display_mode *mode)
03037 {
03038     TRACE("wined3d %p, adapter_idx %u, display_mode %p.\n", wined3d, adapter_idx, mode);
03039 
03040     if (!mode || adapter_idx >= wined3d->adapter_count)
03041         return WINED3DERR_INVALIDCALL;
03042 
03043     if (!adapter_idx)
03044     {
03045         DEVMODEW DevModeW;
03046         unsigned int bpp;
03047 
03048         ZeroMemory(&DevModeW, sizeof(DevModeW));
03049         DevModeW.dmSize = sizeof(DevModeW);
03050 
03051         EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &DevModeW, 0);
03052         mode->width = DevModeW.dmPelsWidth;
03053         mode->height = DevModeW.dmPelsHeight;
03054         bpp = DevModeW.dmBitsPerPel;
03055         mode->refresh_rate = DEFAULT_REFRESH_RATE;
03056         if (DevModeW.dmFields & DM_DISPLAYFREQUENCY)
03057             mode->refresh_rate = DevModeW.dmDisplayFrequency;
03058         mode->format_id = pixelformat_for_depth(bpp);
03059     }
03060     else
03061     {
03062         FIXME_(d3d_caps)("Adapter not primary display\n");
03063     }
03064 
03065     TRACE_(d3d_caps)("returning w:%d, h:%d, ref:%d, fmt:%s\n", mode->width,
03066           mode->height, mode->refresh_rate, debug_d3dformat(mode->format_id));
03067     return WINED3D_OK;
03068 }
03069 
03070 /* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
03071    and fields being inserted in the middle, a new structure is used in place    */
03072 HRESULT CDECL wined3d_get_adapter_identifier(const struct wined3d *wined3d,
03073         UINT adapter_idx, DWORD flags, struct wined3d_adapter_identifier *identifier)
03074 {
03075     const struct wined3d_adapter *adapter;
03076     size_t len;
03077 
03078     TRACE_(d3d_caps)("wined3d %p, adapter_idx %u, flags %#x, indentifier %p.\n",
03079             wined3d, adapter_idx, flags, identifier);
03080 
03081     if (adapter_idx >= wined3d->adapter_count)
03082         return WINED3DERR_INVALIDCALL;
03083 
03084     adapter = &wined3d->adapters[adapter_idx];
03085 
03086     /* Return the information requested */
03087     TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
03088 
03089     if (identifier->driver_size)
03090     {
03091         const char *name = adapter->driver_info.name;
03092         len = min(strlen(name), identifier->driver_size - 1);
03093         memcpy(identifier->driver, name, len);
03094         identifier->driver[len] = '\0';
03095     }
03096 
03097     if (identifier->description_size)
03098     {
03099         const char *description = adapter->driver_info.description;
03100         len = min(strlen(description), identifier->description_size - 1);
03101         memcpy(identifier->description, description, len);
03102         identifier->description[len] = '\0';
03103     }
03104 
03105     /* Note that d3d8 doesn't supply a device name. */
03106     if (identifier->device_name_size)
03107     {
03108         static const char *device_name = "\\\\.\\DISPLAY1"; /* FIXME: May depend on desktop? */
03109 
03110         len = strlen(device_name);
03111         if (len >= identifier->device_name_size)
03112         {
03113             ERR("Device name size too small.\n");
03114             return WINED3DERR_INVALIDCALL;
03115         }
03116 
03117         memcpy(identifier->device_name, device_name, len);
03118         identifier->device_name[len] = '\0';
03119     }
03120 
03121     identifier->driver_version.u.HighPart = adapter->driver_info.version_high;
03122     identifier->driver_version.u.LowPart = adapter->driver_info.version_low;
03123     identifier->vendor_id = adapter->driver_info.vendor;
03124     identifier->device_id = adapter->driver_info.device;
03125     identifier->subsystem_id = 0;
03126     identifier->revision = 0;
03127     memcpy(&identifier->device_identifier, &IID_D3DDEVICE_D3DUID, sizeof(identifier->device_identifier));
03128     identifier->whql_level = (flags & WINED3DENUM_NO_WHQL_LEVEL) ? 0 : 1;
03129     memcpy(&identifier->adapter_luid, &adapter->luid, sizeof(identifier->adapter_luid));
03130     identifier->video_memory = adapter->TextureRam;
03131 
03132     return WINED3D_OK;
03133 }
03134 
03135 static BOOL wined3d_check_pixel_format_color(const struct wined3d_gl_info *gl_info,
03136         const struct wined3d_pixel_format *cfg, const struct wined3d_format *format)
03137 {
03138     BYTE redSize, greenSize, blueSize, alphaSize, colorBits;
03139 
03140     /* Float formats need FBOs. If FBOs are used this function isn't called */
03141     if (format->flags & WINED3DFMT_FLAG_FLOAT) return FALSE;
03142 
03143     if(cfg->iPixelType == WGL_TYPE_RGBA_ARB) { /* Integer RGBA formats */
03144         if (!getColorBits(format, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
03145         {
03146             ERR("Unable to check compatibility for format %s.\n", debug_d3dformat(format->id));
03147             return FALSE;
03148         }
03149 
03150         if(cfg->redSize < redSize)
03151             return FALSE;
03152 
03153         if(cfg->greenSize < greenSize)
03154             return FALSE;
03155 
03156         if(cfg->blueSize < blueSize)
03157             return FALSE;
03158 
03159         if(cfg->alphaSize < alphaSize)
03160             return FALSE;
03161 
03162         return TRUE;
03163     }
03164 
03165     /* Probably a RGBA_float or color index mode */
03166     return FALSE;
03167 }
03168 
03169 static BOOL wined3d_check_pixel_format_depth(const struct wined3d_gl_info *gl_info,
03170         const struct wined3d_pixel_format *cfg, const struct wined3d_format *format)
03171 {
03172     BYTE depthSize, stencilSize;
03173     BOOL lockable = FALSE;
03174 
03175     if (!getDepthStencilBits(format, &depthSize, &stencilSize))
03176     {
03177         ERR("Unable to check compatibility for format %s.\n", debug_d3dformat(format->id));
03178         return FALSE;
03179     }
03180 
03181     /* Float formats need FBOs. If FBOs are used this function isn't called */
03182     if (format->flags & WINED3DFMT_FLAG_FLOAT) return FALSE;
03183 
03184     if ((format->id == WINED3DFMT_D16_LOCKABLE) || (format->id == WINED3DFMT_D32_FLOAT))
03185         lockable = TRUE;
03186 
03187     /* On some modern cards like the Geforce8/9 GLX doesn't offer some dephthstencil formats which D3D9 reports.
03188      * We can safely report 'compatible' formats (e.g. D24 can be used for D16) as long as we aren't dealing with
03189      * a lockable format. This also helps D3D <= 7 as they expect D16 which isn't offered without this on Geforce8 cards. */
03190     if(!(cfg->depthSize == depthSize || (!lockable && cfg->depthSize > depthSize)))
03191         return FALSE;
03192 
03193     /* Some cards like Intel i915 ones only offer D24S8 but lots of games also need a format without stencil, so
03194      * allow more stencil bits than requested. */
03195     if(cfg->stencilSize < stencilSize)
03196         return FALSE;
03197 
03198     return TRUE;
03199 }
03200 
03201 HRESULT CDECL wined3d_check_depth_stencil_match(const struct wined3d *wined3d,
03202         UINT adapter_idx, enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id,
03203         enum wined3d_format_id render_target_format_id, enum wined3d_format_id depth_stencil_format_id)
03204 {
03205     const struct wined3d_format *rt_format;
03206     const struct wined3d_format *ds_format;
03207     const struct wined3d_adapter *adapter;
03208 
03209     TRACE_(d3d_caps)("wined3d %p, adapter_idx %u, device_type %s,\n"
03210             "adapter_format %s, render_target_format %s, depth_stencil_format %s.\n",
03211             wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(adapter_format_id),
03212             debug_d3dformat(render_target_format_id), debug_d3dformat(depth_stencil_format_id));
03213 
03214     if (adapter_idx >= wined3d->adapter_count)
03215         return WINED3DERR_INVALIDCALL;
03216 
03217     adapter = &wined3d->adapters[adapter_idx];
03218     rt_format = wined3d_get_format(&adapter->gl_info, render_target_format_id);
03219     ds_format = wined3d_get_format(&adapter->gl_info, depth_stencil_format_id);
03220     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
03221     {
03222         if ((rt_format->flags & WINED3DFMT_FLAG_RENDERTARGET)
03223                 && (ds_format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
03224         {
03225             TRACE_(d3d_caps)("Formats match.\n");
03226             return WINED3D_OK;
03227         }
03228     }
03229     else
03230     {
03231         const struct wined3d_pixel_format *cfgs;
03232         unsigned int cfg_count;
03233         unsigned int i;
03234 
03235         cfgs = adapter->cfgs;
03236         cfg_count = adapter->cfg_count;
03237         for (i = 0; i < cfg_count; ++i)
03238         {
03239             if (wined3d_check_pixel_format_color(&adapter->gl_info, &cfgs[i], rt_format)
03240                     && wined3d_check_pixel_format_depth(&adapter->gl_info, &cfgs[i], ds_format))
03241             {
03242                 TRACE_(d3d_caps)("Formats match.\n");
03243                 return WINED3D_OK;
03244             }
03245         }
03246     }
03247 
03248     TRACE_(d3d_caps)("Unsupported format pair: %s and %s.\n",
03249             debug_d3dformat(render_target_format_id),
03250             debug_d3dformat(depth_stencil_format_id));
03251 
03252     return WINED3DERR_NOTAVAILABLE;
03253 }
03254 
03255 HRESULT CDECL wined3d_check_device_multisample_type(const struct wined3d *wined3d, UINT adapter_idx,
03256         enum wined3d_device_type device_type, enum wined3d_format_id surface_format_id, BOOL windowed,
03257         enum wined3d_multisample_type multisample_type, DWORD *quality_levels)
03258 {
03259     const struct wined3d_gl_info *gl_info;
03260 
03261     TRACE_(d3d_caps)("wined3d %p, adapter_idx %u, device_type %s, surface_format %s,\n"
03262             "windowed %#x, multisample_type %#x, quality_levels %p.\n",
03263             wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(surface_format_id),
03264             windowed, multisample_type, quality_levels);
03265 
03266     if (adapter_idx >= wined3d->adapter_count)
03267         return WINED3DERR_INVALIDCALL;
03268 
03269     gl_info = &wined3d->adapters[adapter_idx].gl_info;
03270 
03271     if (multisample_type > gl_info->limits.samples)
03272     {
03273         TRACE("Returning not supported.\n");
03274         if (quality_levels)
03275             *quality_levels = 0;
03276 
03277         return WINED3DERR_NOTAVAILABLE;
03278     }
03279 
03280     if (quality_levels)
03281     {
03282         if (multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE)
03283             /* FIXME: This is probably wrong. */
03284             *quality_levels = gl_info->limits.samples;
03285         else
03286             *quality_levels = 1;
03287     }
03288 
03289     return WINED3D_OK;
03290 }
03291 
03292 /* Check if we support bumpmapping for a format */
03293 static BOOL CheckBumpMapCapability(const struct wined3d_adapter *adapter, const struct wined3d_format *format)
03294 {
03295     /* Ask the fixed function pipeline implementation if it can deal
03296      * with the conversion. If we've got a GL extension giving native
03297      * support this will be an identity conversion. */
03298     return (format->flags & WINED3DFMT_FLAG_BUMPMAP)
03299             && adapter->fragment_pipe->color_fixup_supported(format->color_fixup);
03300 }
03301 
03302 /* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
03303 static BOOL CheckDepthStencilCapability(const struct wined3d_adapter *adapter,
03304         const struct wined3d_format *display_format, const struct wined3d_format *ds_format)
03305 {
03306     /* Only allow depth/stencil formats */
03307     if (!(ds_format->depth_size || ds_format->stencil_size)) return FALSE;
03308 
03309     /* Blacklist formats not supported on Windows */
03310     switch (ds_format->id)
03311     {
03312         case WINED3DFMT_S1_UINT_D15_UNORM: /* Breaks the shadowvol2 dx7 sdk sample */
03313         case WINED3DFMT_S4X4_UINT_D24_UNORM:
03314             TRACE_(d3d_caps)("[FAILED] - not supported on windows\n");
03315             return FALSE;
03316 
03317         default:
03318             break;
03319     }
03320 
03321     if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
03322     {
03323         /* With FBOs WGL limitations do not apply, but the format needs to be FBO attachable */
03324         if (ds_format->flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) return TRUE;
03325     }
03326     else
03327     {
03328         unsigned int i;
03329 
03330         /* Walk through all WGL pixel formats to find a match */
03331         for (i = 0; i < adapter->cfg_count; ++i)
03332         {
03333             const struct wined3d_pixel_format *cfg = &adapter->cfgs[i];
03334             if (wined3d_check_pixel_format_color(&adapter->gl_info, cfg, display_format)
03335                     && wined3d_check_pixel_format_depth(&adapter->gl_info, cfg, ds_format))
03336                 return TRUE;
03337         }
03338     }
03339 
03340     return FALSE;
03341 }
03342 
03343 static BOOL CheckFilterCapability(const struct wined3d_adapter *adapter, const struct wined3d_format *format)
03344 {
03345     /* The flags entry of a format contains the filtering capability */
03346     if ((format->flags & WINED3DFMT_FLAG_FILTERING)
03347             || !(adapter->gl_info.quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING))
03348         return TRUE;
03349 
03350     return FALSE;
03351 }
03352 
03353 /* Check the render target capabilities of a format */
03354 static BOOL CheckRenderTargetCapability(const struct wined3d_adapter *adapter,
03355         const struct wined3d_format *adapter_format, const struct wined3d_format *check_format)
03356 {
03357     /* Filter out non-RT formats */
03358     if (!(check_format->flags & WINED3DFMT_FLAG_RENDERTARGET)) return FALSE;
03359     if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER)
03360     {
03361         BYTE AdapterRed, AdapterGreen, AdapterBlue, AdapterAlpha, AdapterTotalSize;
03362         BYTE CheckRed, CheckGreen, CheckBlue, CheckAlpha, CheckTotalSize;
03363         const struct wined3d_pixel_format *cfgs = adapter->cfgs;
03364         unsigned int i;
03365 
03366         getColorBits(adapter_format, &AdapterRed, &AdapterGreen, &AdapterBlue, &AdapterAlpha, &AdapterTotalSize);
03367         getColorBits(check_format, &CheckRed, &CheckGreen, &CheckBlue, &CheckAlpha, &CheckTotalSize);
03368 
03369         /* In backbuffer mode the front and backbuffer share the same WGL pixelformat.
03370          * The format must match in RGB, alpha is allowed to be different. (Only the backbuffer can have alpha) */
03371         if(!((AdapterRed == CheckRed) && (AdapterGreen == CheckGreen) && (AdapterBlue == CheckBlue))) {
03372             TRACE_(d3d_caps)("[FAILED]\n");
03373             return FALSE;
03374         }
03375 
03376         /* Check if there is a WGL pixel format matching the requirements, the format should also be window
03377          * drawable (not offscreen; e.g. Nvidia offers R5G6B5 for pbuffers even when X is running at 24bit) */
03378         for (i = 0; i < adapter->cfg_count; ++i)
03379         {
03380             if (cfgs[i].windowDrawable
03381                     && wined3d_check_pixel_format_color(&adapter->gl_info, &cfgs[i], check_format))
03382             {
03383                 TRACE_(d3d_caps)("Pixel format %d is compatible with format %s.\n",
03384                         cfgs[i].iPixelFormat, debug_d3dformat(check_format->id));
03385                 return TRUE;
03386             }
03387         }
03388     }
03389     else if(wined3d_settings.offscreen_rendering_mode == ORM_FBO)
03390     {
03391         /* For now return TRUE for FBOs until we have some proper checks.
03392          * Note that this function will only be called when the format is around for texturing. */
03393         return TRUE;
03394     }
03395     return FALSE;
03396 }
03397 
03398 static BOOL CheckSrgbReadCapability(const struct wined3d_adapter *adapter, const struct wined3d_format *format)
03399 {
03400     return format->flags & WINED3DFMT_FLAG_SRGB_READ;
03401 }
03402 
03403 static BOOL CheckSrgbWriteCapability(const struct wined3d_adapter *adapter, const struct wined3d_format *format)
03404 {
03405     /* Only offer SRGB writing on X8R8G8B8/A8R8G8B8 when we use ARB or GLSL shaders as we are
03406      * doing the color fixup in shaders.
03407      * Note Windows drivers (at least on the Geforce 8800) also offer this on R5G6B5. */
03408     if (format->flags & WINED3DFMT_FLAG_SRGB_WRITE)
03409     {
03410         int vs_selected_mode;
03411         int ps_selected_mode;
03412         select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
03413 
03414         if((ps_selected_mode == SHADER_ARB) || (ps_selected_mode == SHADER_GLSL)) {
03415             TRACE_(d3d_caps)("[OK]\n");
03416             return TRUE;
03417         }
03418     }
03419 
03420     TRACE_(d3d_caps)("[FAILED] - sRGB writes not supported by format %s.\n", debug_d3dformat(format->id));
03421     return FALSE;
03422 }
03423 
03424 /* Check if a format support blending in combination with pixel shaders */
03425 static BOOL CheckPostPixelShaderBlendingCapability(const struct wined3d_adapter *adapter,
03426         const struct wined3d_format *format)
03427 {
03428     /* The flags entry of a format contains the post pixel shader blending capability */
03429     if (format->flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) return TRUE;
03430 
03431     return FALSE;
03432 }
03433 
03434 static BOOL CheckWrapAndMipCapability(const struct wined3d_adapter *adapter, const struct wined3d_format *format)
03435 {
03436     /* OpenGL supports mipmapping on all formats basically. Wrapping is unsupported,
03437      * but we have to report mipmapping so we cannot reject this flag. Tests show that
03438      * windows reports WRAPANDMIP on unfilterable surfaces as well, apparently to show
03439      * that wrapping is supported. The lack of filtering will sort out the mipmapping
03440      * capability anyway.
03441      *
03442      * For now lets report this on all formats, but in the future we may want to
03443      * restrict it to some should games need that
03444      */
03445     return TRUE;
03446 }
03447 
03448 /* Check if a texture format is supported on the given adapter */
03449 static BOOL CheckTextureCapability(const struct wined3d_adapter *adapter, const struct wined3d_format *format)
03450 {
03451     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
03452 
03453     switch (format->id)
03454     {
03455         /*****
03456          *  supported: RGB(A) formats
03457          */
03458         case WINED3DFMT_B8G8R8_UNORM:
03459             TRACE_(d3d_caps)("[FAILED] - Not enumerated on Windows\n");
03460             return FALSE;
03461         case WINED3DFMT_B8G8R8A8_UNORM:
03462         case WINED3DFMT_B8G8R8X8_UNORM:
03463         case WINED3DFMT_B5G6R5_UNORM:
03464         case WINED3DFMT_B5G5R5X1_UNORM:
03465         case WINED3DFMT_B5G5R5A1_UNORM:
03466         case WINED3DFMT_B4G4R4A4_UNORM:
03467         case WINED3DFMT_A8_UNORM:
03468         case WINED3DFMT_B4G4R4X4_UNORM:
03469         case WINED3DFMT_R8G8B8A8_UNORM:
03470         case WINED3DFMT_R8G8B8X8_UNORM:
03471         case WINED3DFMT_B10G10R10A2_UNORM:
03472         case WINED3DFMT_R10G10B10A2_UNORM:
03473         case WINED3DFMT_R16G16_UNORM:
03474             TRACE_(d3d_caps)("[OK]\n");
03475             return TRUE;
03476 
03477         case WINED3DFMT_B2G3R3_UNORM:
03478             TRACE_(d3d_caps)("[FAILED] - Not supported on Windows\n");
03479             return FALSE;
03480 
03481         /*****
03482          *  Not supported: Palettized
03483          *  Only some Geforce/Voodoo3/G400 cards offer 8-bit textures in case of <=Direct3D7.
03484          *  Since it is not widely available, don't offer it. Further no Windows driver offers
03485          *  WINED3DFMT_P8_UINT_A8_NORM, so don't offer it either.
03486          */
03487         case WINED3DFMT_P8_UINT:
03488         case WINED3DFMT_P8_UINT_A8_UNORM:
03489             return FALSE;
03490 
03491         /*****
03492          *  Supported: (Alpha)-Luminance
03493          */
03494         case WINED3DFMT_L8_UNORM:
03495         case WINED3DFMT_L8A8_UNORM:
03496         case WINED3DFMT_L16_UNORM:
03497             TRACE_(d3d_caps)("[OK]\n");
03498             return TRUE;
03499 
03500         /* Not supported on Windows, thus disabled */
03501         case WINED3DFMT_L4A4_UNORM:
03502             TRACE_(d3d_caps)("[FAILED] - not supported on windows\n");
03503             return FALSE;
03504 
03505         /*****
03506          *  Supported: Depth/Stencil formats
03507          */
03508         case WINED3DFMT_D16_LOCKABLE:
03509         case WINED3DFMT_D16_UNORM:
03510         case WINED3DFMT_X8D24_UNORM:
03511         case WINED3DFMT_D24_UNORM_S8_UINT:
03512         case WINED3DFMT_S8_UINT_D24_FLOAT:
03513         case WINED3DFMT_D32_UNORM:
03514         case WINED3DFMT_D32_FLOAT:
03515             return TRUE;
03516 
03517         case WINED3DFMT_INTZ:
03518             if (gl_info->supported[EXT_PACKED_DEPTH_STENCIL]
03519                     || gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
03520                 return TRUE;
03521             return FALSE;
03522 
03523         /* Not supported on Windows */
03524         case WINED3DFMT_S1_UINT_D15_UNORM:
03525         case WINED3DFMT_S4X4_UINT_D24_UNORM:
03526             TRACE_(d3d_caps)("[FAILED] - not supported on windows\n");
03527             return FALSE;
03528 
03529         /*****
03530          *  Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
03531          *  GL_NV_texture_shader). Emulated by shaders
03532          */
03533         case WINED3DFMT_R8G8_SNORM:
03534         case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
03535         case WINED3DFMT_R5G5_SNORM_L6_UNORM:
03536         case WINED3DFMT_R8G8B8A8_SNORM:
03537         case WINED3DFMT_R16G16_SNORM:
03538             /* Ask the shader backend if it can deal with the conversion. If
03539              * we've got a GL extension giving native support this will be an
03540              * identity conversion. */
03541             if (adapter->shader_backend->shader_color_fixup_supported(format->color_fixup))
03542             {
03543                 TRACE_(d3d_caps)("[OK]\n");
03544                 return TRUE;
03545             }
03546             TRACE_(d3d_caps)("[FAILED]\n");
03547             return FALSE;
03548 
03549         case WINED3DFMT_DXT1:
03550         case WINED3DFMT_DXT2:
03551         case WINED3DFMT_DXT3:
03552         case WINED3DFMT_DXT4:
03553         case WINED3DFMT_DXT5:
03554             if (gl_info->supported[EXT_TEXTURE_COMPRESSION_S3TC])
03555             {
03556                 TRACE_(d3d_caps)("[OK]\n");
03557                 return TRUE;
03558             }
03559             TRACE_(d3d_caps)("[FAILED]\n");
03560             return FALSE;
03561 
03562 
03563         /*****
03564          *  Odd formats - not supported
03565          */
03566         case WINED3DFMT_VERTEXDATA:
03567         case WINED3DFMT_R16_UINT:
03568         case WINED3DFMT_R32_UINT:
03569         case WINED3DFMT_R16G16B16A16_SNORM:
03570         case WINED3DFMT_R10G10B10_SNORM_A2_UNORM:
03571         case WINED3DFMT_R10G11B11_SNORM:
03572         case WINED3DFMT_R16:
03573         case WINED3DFMT_AL16:
03574             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
03575             return FALSE;
03576 
03577         /*****
03578          *  WINED3DFMT_R8G8_SNORM_Cx: Not supported right now
03579          */
03580         case WINED3DFMT_R8G8_SNORM_Cx:
03581             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
03582             return FALSE;
03583 
03584         /* YUV formats */
03585         case WINED3DFMT_UYVY:
03586         case WINED3DFMT_YUY2:
03587             if (gl_info->supported[APPLE_YCBCR_422])
03588             {
03589                 TRACE_(d3d_caps)("[OK]\n");
03590                 return TRUE;
03591             }
03592             TRACE_(d3d_caps)("[FAILED]\n");
03593             return FALSE;
03594         case WINED3DFMT_YV12:
03595             TRACE_(d3d_caps)("[FAILED]\n");
03596             return FALSE;
03597 
03598         case WINED3DFMT_R16G16B16A16_UNORM:
03599             if (gl_info->quirks & WINED3D_QUIRK_BROKEN_RGBA16)
03600             {
03601                 TRACE_(d3d_caps)("[FAILED]\n");
03602                 return FALSE;
03603             }
03604             TRACE_(d3d_caps)("[OK]\n");
03605             return TRUE;
03606 
03607             /* Not supported */
03608         case WINED3DFMT_B2G3R3A8_UNORM:
03609             TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
03610             return FALSE;
03611 
03612             /* Floating point formats */
03613         case WINED3DFMT_R16_FLOAT:
03614         case WINED3DFMT_R16G16_FLOAT:
03615         case WINED3DFMT_R16G16B16A16_FLOAT:
03616             if (gl_info->supported[ARB_TEXTURE_FLOAT] && gl_info->supported[ARB_HALF_FLOAT_PIXEL])
03617             {
03618                 TRACE_(d3d_caps)("[OK]\n");
03619                 return TRUE;
03620             }
03621             TRACE_(d3d_caps)("[FAILED]\n");
03622             return FALSE;
03623 
03624         case WINED3DFMT_R32_FLOAT:
03625         case WINED3DFMT_R32G32_FLOAT:
03626         case WINED3DFMT_R32G32B32A32_FLOAT:
03627             if (gl_info->supported[ARB_TEXTURE_FLOAT])
03628             {
03629                 TRACE_(d3d_caps)("[OK]\n");
03630                 return TRUE;
03631             }
03632             TRACE_(d3d_caps)("[FAILED]\n");
03633             return FALSE;
03634 
03635         /* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
03636          * instancing. To query if the card supports instancing CheckDeviceFormat with the special format
03637          * MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
03638          * We can do instancing with all shader versions, but we need vertex shaders.
03639          *
03640          * Additionally applications have to set the D3DRS_POINTSIZE render state to MAKEFOURCC('I','N','S','T') once
03641          * to enable instancing. WineD3D doesn't need that and just ignores it.
03642          *
03643          * With Shader Model 3.0 capable cards Instancing 'just works' in Windows.
03644          */
03645         case WINED3DFMT_INST:
03646             TRACE("ATI Instancing check hack\n");
03647             if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_VERTEX_SHADER])
03648             {
03649                 TRACE_(d3d_caps)("[OK]\n");
03650                 return TRUE;
03651             }
03652             TRACE_(d3d_caps)("[FAILED]\n");
03653             return FALSE;
03654 
03655         /* Some weird FOURCC formats */
03656         case WINED3DFMT_R8G8_B8G8:
03657         case WINED3DFMT_G8R8_G8B8:
03658         case WINED3DFMT_MULTI2_ARGB8:
03659             TRACE_(d3d_caps)("[FAILED]\n");
03660             return FALSE;
03661 
03662         /* Vendor specific formats */
03663         case WINED3DFMT_ATI2N:
03664             if (gl_info->supported[ATI_TEXTURE_COMPRESSION_3DC]
03665                     || gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC])
03666             {
03667                 if (adapter->shader_backend->shader_color_fixup_supported(format->color_fixup)
03668                         && adapter->fragment_pipe->color_fixup_supported(format->color_fixup))
03669                 {
03670                     TRACE_(d3d_caps)("[OK]\n");
03671                     return TRUE;
03672                 }
03673 
03674                 TRACE_(d3d_caps)("[OK]\n");
03675                 return TRUE;
03676             }
03677             TRACE_(d3d_caps)("[FAILED]\n");
03678             return FALSE;
03679 
03680         /* Depth bound test. To query if the card supports it CheckDeviceFormat with the special
03681          * format MAKEFOURCC('N','V','D','B') is used.
03682          * It is enabled by setting D3DRS_ADAPTIVETESS_X render state to MAKEFOURCC('N','V','D','B') and
03683          * then controlled by setting D3DRS_ADAPTIVETESS_Z (zMin) and D3DRS_ADAPTIVETESS_W (zMax)
03684          * to test value.
03685          */
03686         case WINED3DFMT_NVDB:
03687             if (gl_info->supported[EXT_DEPTH_BOUNDS_TEST])
03688             {
03689                 TRACE_(d3d_caps)("[OK]\n");
03690                 return TRUE;
03691             }
03692             TRACE_(d3d_caps)("[FAILED]\n");
03693             return FALSE;
03694 
03695         case WINED3DFMT_NVHU:
03696         case WINED3DFMT_NVHS:
03697             /* These formats seem to be similar to the HILO formats in GL_NV_texture_shader. NVHU
03698              * is said to be GL_UNSIGNED_HILO16, NVHS GL_SIGNED_HILO16. Rumours say that d3d computes
03699              * a 3rd channel similarly to D3DFMT_CxV8U8(So NVHS could be called D3DFMT_CxV16U16).
03700              * ATI refused to support formats which can easily be emulated with pixel shaders, so
03701              * Applications have to deal with not having NVHS and NVHU.
03702              */
03703             TRACE_(d3d_caps)("[FAILED]\n");
03704             return FALSE;
03705 
03706         case WINED3DFMT_NULL:
03707             if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
03708                 return TRUE;
03709             return FALSE;
03710 
03711         case WINED3DFMT_UNKNOWN:
03712             return FALSE;
03713 
03714         default:
03715             ERR("Unhandled format %s.\n", debug_d3dformat(format->id));
03716             break;
03717     }
03718     return FALSE;
03719 }
03720 
03721 static BOOL CheckSurfaceCapability(const struct wined3d_adapter *adapter,
03722         const struct wined3d_format *adapter_format,
03723         const struct wined3d_format *check_format,
03724         WINED3DSURFTYPE SurfaceType)
03725 {
03726     if (SurfaceType == SURFACE_GDI)
03727     {
03728         switch (check_format->id)
03729         {
03730             case WINED3DFMT_B8G8R8_UNORM:
03731                 TRACE_(d3d_caps)("[FAILED] - Not enumerated on Windows\n");
03732                 return FALSE;
03733             case WINED3DFMT_B8G8R8A8_UNORM:
03734             case WINED3DFMT_B8G8R8X8_UNORM:
03735             case WINED3DFMT_B5G6R5_UNORM:
03736             case WINED3DFMT_B5G5R5X1_UNORM:
03737             case WINED3DFMT_B5G5R5A1_UNORM:
03738             case WINED3DFMT_B4G4R4A4_UNORM:
03739             case WINED3DFMT_B2G3R3_UNORM:
03740             case WINED3DFMT_A8_UNORM:
03741             case WINED3DFMT_B2G3R3A8_UNORM:
03742             case WINED3DFMT_B4G4R4X4_UNORM:
03743             case WINED3DFMT_R10G10B10A2_UNORM:
03744             case WINED3DFMT_R8G8B8A8_UNORM:
03745             case WINED3DFMT_R8G8B8X8_UNORM:
03746             case WINED3DFMT_R16G16_UNORM:
03747             case WINED3DFMT_B10G10R10A2_UNORM:
03748             case WINED3DFMT_R16G16B16A16_UNORM:
03749             case WINED3DFMT_P8_UINT:
03750                 TRACE_(d3d_caps)("[OK]\n");
03751                 return TRUE;
03752             default:
03753                 TRACE_(d3d_caps)("[FAILED] - not available on GDI surfaces\n");
03754                 return FALSE;
03755         }
03756     }
03757 
03758     /* All format that are supported for textures are supported for surfaces as well */
03759     if (CheckTextureCapability(adapter, check_format)) return TRUE;
03760     /* All depth stencil formats are supported on surfaces */
03761     if (CheckDepthStencilCapability(adapter, adapter_format, check_format)) return TRUE;
03762 
03763     /* If opengl can't process the format natively, the blitter may be able to convert it */
03764     if (adapter->blitter->blit_supported(&adapter->gl_info, WINED3D_BLIT_OP_COLOR_BLIT,
03765             NULL, WINED3D_POOL_DEFAULT, 0, check_format,
03766             NULL, WINED3D_POOL_DEFAULT, 0, adapter_format))
03767     {
03768         TRACE_(d3d_caps)("[OK]\n");
03769         return TRUE;
03770     }
03771 
03772     /* Reject other formats */
03773     TRACE_(d3d_caps)("[FAILED]\n");
03774     return FALSE;
03775 }
03776 
03777 static BOOL CheckVertexTextureCapability(const struct wined3d_adapter *adapter,
03778         const struct wined3d_format *format)
03779 {
03780     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
03781 
03782     if (!gl_info->limits.vertex_samplers || !(format->flags & WINED3DFMT_FLAG_VTF))
03783         return FALSE;
03784 
03785     switch (format->id)
03786     {
03787         case WINED3DFMT_R32G32B32A32_FLOAT:
03788         case WINED3DFMT_R32_FLOAT:
03789             return TRUE;
03790         default:
03791             return !(gl_info->quirks & WINED3D_QUIRK_LIMITED_TEX_FILTERING);
03792     }
03793 }
03794 
03795 HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT adapter_idx,
03796         enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id, DWORD usage,
03797         enum wined3d_resource_type resource_type, enum wined3d_format_id check_format_id, WINED3DSURFTYPE surface_type)
03798 {
03799     const struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx];
03800     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
03801     const struct wined3d_format *adapter_format = wined3d_get_format(gl_info, adapter_format_id);
03802     const struct wined3d_format *format = wined3d_get_format(gl_info, check_format_id);
03803     DWORD usage_caps = 0;
03804 
03805     TRACE_(d3d_caps)("wined3d %p, adapter_idx %u, device_type %s, adapter_format %s, usage %s, %s,\n"
03806             "resource_type %s, check_format %s, surface_type %#x.\n",
03807             wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(adapter_format_id),
03808             debug_d3dusage(usage), debug_d3dusagequery(usage), debug_d3dresourcetype(resource_type),
03809             debug_d3dformat(check_format_id), surface_type);
03810 
03811     if (adapter_idx >= wined3d->adapter_count)
03812         return WINED3DERR_INVALIDCALL;
03813 
03814     switch (resource_type)
03815     {
03816         case WINED3D_RTYPE_CUBE_TEXTURE:
03817             /* Cubetexture allows:
03818              *      - WINED3DUSAGE_AUTOGENMIPMAP
03819              *      - WINED3DUSAGE_DEPTHSTENCIL
03820              *      - WINED3DUSAGE_DYNAMIC
03821              *      - WINED3DUSAGE_NONSECURE (d3d9ex)
03822              *      - WINED3DUSAGE_RENDERTARGET
03823              *      - WINED3DUSAGE_SOFTWAREPROCESSING
03824              *      - WINED3DUSAGE_QUERY_WRAPANDMIP
03825              */
03826             if (surface_type != SURFACE_OPENGL)
03827             {
03828                 TRACE_(d3d_caps)("[FAILED]\n");
03829                 return WINED3DERR_NOTAVAILABLE;
03830             }
03831 
03832             if (!gl_info->supported[ARB_TEXTURE_CUBE_MAP])
03833             {
03834                 TRACE_(d3d_caps)("[FAILED] - No cube texture support\n");
03835                 return WINED3DERR_NOTAVAILABLE;
03836             }
03837 
03838             if (!CheckTextureCapability(adapter, format))
03839             {
03840                 TRACE_(d3d_caps)("[FAILED] - Cube texture format not supported\n");
03841                 return WINED3DERR_NOTAVAILABLE;
03842             }
03843 
03844             if (usage & WINED3DUSAGE_AUTOGENMIPMAP)
03845             {
03846                 if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
03847                     /* When autogenmipmap isn't around continue and return
03848                      * WINED3DOK_NOAUTOGEN instead of D3D_OK. */
03849                     TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
03850                 else
03851                     usage_caps |= WINED3DUSAGE_AUTOGENMIPMAP;
03852             }
03853 
03854             /* Always report dynamic locking. */
03855             if (usage & WINED3DUSAGE_DYNAMIC)
03856                 usage_caps |= WINED3DUSAGE_DYNAMIC;
03857 
03858             if (usage & WINED3DUSAGE_RENDERTARGET)
03859             {
03860                 if (!CheckRenderTargetCapability(adapter, adapter_format, format))
03861                 {
03862                     TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
03863                     return WINED3DERR_NOTAVAILABLE;
03864                 }
03865                 usage_caps |= WINED3DUSAGE_RENDERTARGET;
03866             }
03867 
03868             /* Always report software processing. */
03869             if (usage & WINED3DUSAGE_SOFTWAREPROCESSING)
03870                 usage_caps |= WINED3DUSAGE_SOFTWAREPROCESSING;
03871 
03872             if (usage & WINED3DUSAGE_QUERY_FILTER)
03873             {
03874                 if (!CheckFilterCapability(adapter, format))
03875                 {
03876                     TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
03877                     return WINED3DERR_NOTAVAILABLE;
03878                 }
03879                 usage_caps |= WINED3DUSAGE_QUERY_FILTER;
03880             }
03881 
03882             if (usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
03883             {
03884                 if (!CheckPostPixelShaderBlendingCapability(adapter, format))
03885                 {
03886                     TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
03887                     return WINED3DERR_NOTAVAILABLE;
03888                 }
03889                 usage_caps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
03890             }
03891 
03892             if (usage & WINED3DUSAGE_QUERY_SRGBREAD)
03893             {
03894                 if (!CheckSrgbReadCapability(adapter, format))
03895                 {
03896                     TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
03897                     return WINED3DERR_NOTAVAILABLE;
03898                 }
03899                 usage_caps |= WINED3DUSAGE_QUERY_SRGBREAD;
03900             }
03901 
03902             if (usage & WINED3DUSAGE_QUERY_SRGBWRITE)
03903             {
03904                 if (!CheckSrgbWriteCapability(adapter, format))
03905                 {
03906                     TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
03907                     return WINED3DERR_NOTAVAILABLE;
03908                 }
03909                 usage_caps |= WINED3DUSAGE_QUERY_SRGBWRITE;
03910             }
03911 
03912             if (usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
03913             {
03914                 if (!CheckVertexTextureCapability(adapter, format))
03915                 {
03916                     TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
03917                     return WINED3DERR_NOTAVAILABLE;
03918                 }
03919                 usage_caps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
03920             }
03921 
03922             if (usage & WINED3DUSAGE_QUERY_WRAPANDMIP)
03923             {
03924                 if (!CheckWrapAndMipCapability(adapter, format))
03925                 {
03926                     TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
03927                     return WINED3DERR_NOTAVAILABLE;
03928                 }
03929                 usage_caps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
03930             }
03931             break;
03932 
03933         case WINED3D_RTYPE_SURFACE:
03934             /* Surface allows:
03935              *      - WINED3DUSAGE_DEPTHSTENCIL
03936              *      - WINED3DUSAGE_NONSECURE (d3d9ex)
03937              *      - WINED3DUSAGE_RENDERTARGET
03938              */
03939             if (!CheckSurfaceCapability(adapter, adapter_format, format, surface_type))
03940             {
03941                 TRACE_(d3d_caps)("[FAILED] - Not supported for plain surfaces\n");
03942                 return WINED3DERR_NOTAVAILABLE;
03943             }
03944 
03945             if (usage & WINED3DUSAGE_DEPTHSTENCIL)
03946             {
03947                 if (!CheckDepthStencilCapability(adapter, adapter_format, format))
03948                 {
03949                     TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n");
03950                     return WINED3DERR_NOTAVAILABLE;
03951                 }
03952                 usage_caps |= WINED3DUSAGE_DEPTHSTENCIL;
03953             }
03954 
03955             if (usage & WINED3DUSAGE_RENDERTARGET)
03956             {
03957                 if (!CheckRenderTargetCapability(adapter, adapter_format, format))
03958                 {
03959                     TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
03960                     return WINED3DERR_NOTAVAILABLE;
03961                 }
03962                 usage_caps |= WINED3DUSAGE_RENDERTARGET;
03963             }
03964 
03965             if (usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
03966             {
03967                 if (!CheckPostPixelShaderBlendingCapability(adapter, format))
03968                 {
03969                     TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
03970                     return WINED3DERR_NOTAVAILABLE;
03971                 }
03972                 usage_caps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
03973             }
03974             break;
03975 
03976         case WINED3D_RTYPE_TEXTURE:
03977             /* Texture allows:
03978              *      - WINED3DUSAGE_AUTOGENMIPMAP
03979              *      - WINED3DUSAGE_DEPTHSTENCIL
03980              *      - WINED3DUSAGE_DMAP
03981              *      - WINED3DUSAGE_DYNAMIC
03982              *      - WINED3DUSAGE_NONSECURE (d3d9ex)
03983              *      - WINED3DUSAGE_RENDERTARGET
03984              *      - WINED3DUSAGE_SOFTWAREPROCESSING
03985              *      - WINED3DUSAGE_TEXTAPI (d3d9ex)
03986              *      - WINED3DUSAGE_QUERY_WRAPANDMIP
03987              */
03988             if (surface_type != SURFACE_OPENGL)
03989             {
03990                 TRACE_(d3d_caps)("[FAILED]\n");
03991                 return WINED3DERR_NOTAVAILABLE;
03992             }
03993 
03994             if (!CheckTextureCapability(adapter, format))
03995             {
03996                 TRACE_(d3d_caps)("[FAILED] - Texture format not supported\n");
03997                 return WINED3DERR_NOTAVAILABLE;
03998             }
03999 
04000             if (usage & WINED3DUSAGE_AUTOGENMIPMAP)
04001             {
04002                 if (!gl_info->supported[SGIS_GENERATE_MIPMAP])
04003                     /* When autogenmipmap isn't around continue and return
04004                      * WINED3DOK_NOAUTOGEN instead of D3D_OK. */
04005                     TRACE_(d3d_caps)("[FAILED] - No autogenmipmap support, but continuing\n");
04006                 else
04007                     usage_caps |= WINED3DUSAGE_AUTOGENMIPMAP;
04008             }
04009 
04010             /* Always report dynamic locking. */
04011             if (usage & WINED3DUSAGE_DYNAMIC)
04012                 usage_caps |= WINED3DUSAGE_DYNAMIC;
04013 
04014             if (usage & WINED3DUSAGE_RENDERTARGET)
04015             {
04016                 if (!CheckRenderTargetCapability(adapter, adapter_format, format))
04017                 {
04018                     TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
04019                     return WINED3DERR_NOTAVAILABLE;
04020                 }
04021                 usage_caps |= WINED3DUSAGE_RENDERTARGET;
04022             }
04023 
04024             /* Always report software processing. */
04025             if (usage & WINED3DUSAGE_SOFTWAREPROCESSING)
04026                 usage_caps |= WINED3DUSAGE_SOFTWAREPROCESSING;
04027 
04028             if (usage & WINED3DUSAGE_QUERY_FILTER)
04029             {
04030                 if (!CheckFilterCapability(adapter, format))
04031                 {
04032                     TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
04033                     return WINED3DERR_NOTAVAILABLE;
04034                 }
04035                 usage_caps |= WINED3DUSAGE_QUERY_FILTER;
04036             }
04037 
04038             if (usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP)
04039             {
04040                 if (!CheckBumpMapCapability(adapter, format))
04041                 {
04042                     TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n");
04043                     return WINED3DERR_NOTAVAILABLE;
04044                 }
04045                 usage_caps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP;
04046             }
04047 
04048             if (usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
04049             {
04050                 if (!CheckPostPixelShaderBlendingCapability(adapter, format))
04051                 {
04052                     TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
04053                     return WINED3DERR_NOTAVAILABLE;
04054                 }
04055                 usage_caps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
04056             }
04057 
04058             if (usage & WINED3DUSAGE_QUERY_SRGBREAD)
04059             {
04060                 if (!CheckSrgbReadCapability(adapter, format))
04061                 {
04062                     TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
04063                     return WINED3DERR_NOTAVAILABLE;
04064                 }
04065                 usage_caps |= WINED3DUSAGE_QUERY_SRGBREAD;
04066             }
04067 
04068             if (usage & WINED3DUSAGE_QUERY_SRGBWRITE)
04069             {
04070                 if (!CheckSrgbWriteCapability(adapter, format))
04071                 {
04072                     TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
04073                     return WINED3DERR_NOTAVAILABLE;
04074                 }
04075                 usage_caps |= WINED3DUSAGE_QUERY_SRGBWRITE;
04076             }
04077 
04078             if (usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
04079             {
04080                 if (!CheckVertexTextureCapability(adapter, format))
04081                 {
04082                     TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
04083                     return WINED3DERR_NOTAVAILABLE;
04084                 }
04085                 usage_caps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
04086             }
04087 
04088             if (usage & WINED3DUSAGE_QUERY_WRAPANDMIP)
04089             {
04090                 if (!CheckWrapAndMipCapability(adapter, format))
04091                 {
04092                     TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
04093                     return WINED3DERR_NOTAVAILABLE;
04094                 }
04095                 usage_caps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
04096             }
04097 
04098             if (usage & WINED3DUSAGE_DEPTHSTENCIL)
04099             {
04100                 if (!CheckDepthStencilCapability(adapter, adapter_format, format))
04101                 {
04102                     TRACE_(d3d_caps)("[FAILED] - No depth stencil support\n");
04103                     return WINED3DERR_NOTAVAILABLE;
04104                 }
04105                 if ((format->flags & WINED3DFMT_FLAG_SHADOW) && !gl_info->supported[ARB_SHADOW])
04106                 {
04107                     TRACE_(d3d_caps)("[FAILED] - No shadow sampler support.\n");
04108                     return WINED3DERR_NOTAVAILABLE;
04109                 }
04110                 usage_caps |= WINED3DUSAGE_DEPTHSTENCIL;
04111             }
04112             break;
04113 
04114         case WINED3D_RTYPE_VOLUME_TEXTURE:
04115         case WINED3D_RTYPE_VOLUME:
04116             /* Volume is to VolumeTexture what Surface is to Texture, but its
04117              * usage caps are not documented. Most driver seem to offer
04118              * (nearly) the same on Volume and VolumeTexture, so do that too.
04119              *
04120              * Volumetexture allows:
04121              *      - D3DUSAGE_DYNAMIC
04122              *      - D3DUSAGE_NONSECURE (d3d9ex)
04123              *      - D3DUSAGE_SOFTWAREPROCESSING
04124              *      - D3DUSAGE_QUERY_WRAPANDMIP
04125              */
04126             if (surface_type != SURFACE_OPENGL)
04127             {
04128                 TRACE_(d3d_caps)("[FAILED]\n");
04129                 return WINED3DERR_NOTAVAILABLE;
04130             }
04131 
04132             if (!gl_info->supported[EXT_TEXTURE3D])
04133             {
04134                 TRACE_(d3d_caps)("[FAILED] - No volume texture support\n");
04135                 return WINED3DERR_NOTAVAILABLE;
04136             }
04137 
04138             if (!CheckTextureCapability(adapter, format))
04139             {
04140                 TRACE_(d3d_caps)("[FAILED] - Format not supported\n");
04141                 return WINED3DERR_NOTAVAILABLE;
04142             }
04143 
04144             /* Filter formats that need conversion; For one part, this
04145              * conversion is unimplemented, and volume textures are huge, so
04146              * it would be a big performance hit. Unless we hit an application
04147              * needing one of those formats, don't advertize them to avoid
04148              * leading applications into temptation. The windows drivers don't
04149              * support most of those formats on volumes anyway, except for
04150              * WINED3DFMT_R32_FLOAT. */
04151             switch (check_format_id)
04152             {
04153                 case WINED3DFMT_P8_UINT:
04154                 case WINED3DFMT_L4A4_UNORM:
04155                 case WINED3DFMT_R32_FLOAT:
04156                 case WINED3DFMT_R16_FLOAT:
04157                 case WINED3DFMT_R8G8_SNORM_L8X8_UNORM:
04158                 case WINED3DFMT_R5G5_SNORM_L6_UNORM:
04159                 case WINED3DFMT_R16G16_UNORM:
04160                     TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
04161                     return WINED3DERR_NOTAVAILABLE;
04162 
04163                 case WINED3DFMT_R8G8B8A8_SNORM:
04164                 case WINED3DFMT_R16G16_SNORM:
04165                     if (!gl_info->supported[NV_TEXTURE_SHADER])
04166                     {
04167                         TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
04168                         return WINED3DERR_NOTAVAILABLE;
04169                     }
04170                     break;
04171 
04172                 case WINED3DFMT_R8G8_SNORM:
04173                     if (!gl_info->supported[NV_TEXTURE_SHADER])
04174                     {
04175                         TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
04176                         return WINED3DERR_NOTAVAILABLE;
04177                     }
04178                     break;
04179 
04180                 case WINED3DFMT_DXT1:
04181                 case WINED3DFMT_DXT2:
04182                 case WINED3DFMT_DXT3:
04183                 case WINED3DFMT_DXT4:
04184                 case WINED3DFMT_DXT5:
04185                     /* The GL_EXT_texture_compression_s3tc spec requires that
04186                      * loading an s3tc compressed texture results in an error.
04187                      * While the D3D refrast does support s3tc volumes, at
04188                      * least the nvidia windows driver does not, so we're free
04189                      * not to support this format. */
04190                     TRACE_(d3d_caps)("[FAILED] - DXTn does not support 3D textures\n");
04191                     return WINED3DERR_NOTAVAILABLE;
04192 
04193                 default:
04194                     /* Do nothing, continue with checking the format below */
04195                     break;
04196             }
04197 
04198             /* Always report dynamic locking. */
04199             if (usage & WINED3DUSAGE_DYNAMIC)
04200                 usage_caps |= WINED3DUSAGE_DYNAMIC;
04201 
04202             /* Always report software processing. */
04203             if (usage & WINED3DUSAGE_SOFTWAREPROCESSING)
04204                 usage_caps |= WINED3DUSAGE_SOFTWAREPROCESSING;
04205 
04206             if (usage & WINED3DUSAGE_QUERY_FILTER)
04207             {
04208                 if (!CheckFilterCapability(adapter, format))
04209                 {
04210                     TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
04211                     return WINED3DERR_NOTAVAILABLE;
04212                 }
04213                 usage_caps |= WINED3DUSAGE_QUERY_FILTER;
04214             }
04215 
04216             if (usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
04217             {
04218                 if (!CheckPostPixelShaderBlendingCapability(adapter, format))
04219                 {
04220                     TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
04221                     return WINED3DERR_NOTAVAILABLE;
04222                 }
04223                 usage_caps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
04224             }
04225 
04226             if (usage & WINED3DUSAGE_QUERY_SRGBREAD)
04227             {
04228                 if (!CheckSrgbReadCapability(adapter, format))
04229                 {
04230                     TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
04231                     return WINED3DERR_NOTAVAILABLE;
04232                 }
04233                 usage_caps |= WINED3DUSAGE_QUERY_SRGBREAD;
04234             }
04235 
04236             if (usage & WINED3DUSAGE_QUERY_SRGBWRITE)
04237             {
04238                 if (!CheckSrgbWriteCapability(adapter, format))
04239                 {
04240                     TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
04241                     return WINED3DERR_NOTAVAILABLE;
04242                 }
04243                 usage_caps |= WINED3DUSAGE_QUERY_SRGBWRITE;
04244             }
04245 
04246             if (usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
04247             {
04248                 if (!CheckVertexTextureCapability(adapter, format))
04249                 {
04250                     TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
04251                     return WINED3DERR_NOTAVAILABLE;
04252                 }
04253                 usage_caps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
04254             }
04255 
04256             if (usage & WINED3DUSAGE_QUERY_WRAPANDMIP)
04257             {
04258                 if (!CheckWrapAndMipCapability(adapter, format))
04259                 {
04260                     TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
04261                     return WINED3DERR_NOTAVAILABLE;
04262                 }
04263                 usage_caps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
04264             }
04265             break;
04266 
04267         default:
04268             FIXME_(d3d_caps)("Unhandled resource type %s.\n", debug_d3dresourcetype(resource_type));
04269             return WINED3DERR_NOTAVAILABLE;
04270     }
04271 
04272     /* When the usage_caps exactly matches usage return WINED3D_OK except for
04273      * the situation in which WINED3DUSAGE_AUTOGENMIPMAP isn't around, then
04274      * WINED3DOK_NOAUTOGEN is returned if all the other usage flags match. */
04275     if (usage_caps == usage)
04276         return WINED3D_OK;
04277     if (usage_caps == (usage & ~WINED3DUSAGE_AUTOGENMIPMAP))
04278         return WINED3DOK_NOAUTOGEN;
04279 
04280     TRACE_(d3d_caps)("[FAILED] - Usage %#x requested for format %s and resource_type %s but only %#x is available.\n",
04281             usage, debug_d3dformat(check_format_id), debug_d3dresourcetype(resource_type), usage_caps);
04282 
04283     return WINED3DERR_NOTAVAILABLE;
04284 }
04285 
04286 HRESULT CDECL wined3d_check_device_format_conversion(const struct wined3d *wined3d, UINT adapter_idx,
04287         enum wined3d_device_type device_type, enum wined3d_format_id src_format, enum wined3d_format_id dst_format)
04288 {
04289     FIXME("wined3d %p, adapter_idx %u, device_type %s, src_format %s, dst_format %s stub!\n",
04290             wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(src_format),
04291             debug_d3dformat(dst_format));
04292 
04293     return WINED3D_OK;
04294 }
04295 
04296 HRESULT CDECL wined3d_check_device_type(const struct wined3d *wined3d, UINT adapter_idx,
04297         enum wined3d_device_type device_type, enum wined3d_format_id display_format,
04298         enum wined3d_format_id backbuffer_format, BOOL windowed)
04299 {
04300     UINT mode_count;
04301     HRESULT hr;
04302 
04303     TRACE("wined3d %p, adapter_idx %u, device_type %s, display_format %s, backbuffer_format %s, windowed %#x.\n",
04304             wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(display_format),
04305             debug_d3dformat(backbuffer_format), windowed);
04306 
04307     if (adapter_idx >= wined3d->adapter_count)
04308         return WINED3DERR_INVALIDCALL;
04309 
04310     /* The task of this function is to check whether a certain display / backbuffer format
04311      * combination is available on the given adapter. In fullscreen mode microsoft specified
04312      * that the display format shouldn't provide alpha and that ignoring alpha the backbuffer
04313      * and display format should match exactly.
04314      * In windowed mode format conversion can occur and this depends on the driver. When format
04315      * conversion is done, this function should nevertheless fail and applications need to use
04316      * CheckDeviceFormatConversion.
04317      * At the moment we assume that fullscreen and windowed have the same capabilities. */
04318 
04319     /* There are only 4 display formats. */
04320     if (!(display_format == WINED3DFMT_B5G6R5_UNORM
04321             || display_format == WINED3DFMT_B5G5R5X1_UNORM
04322             || display_format == WINED3DFMT_B8G8R8X8_UNORM
04323             || display_format == WINED3DFMT_B10G10R10A2_UNORM))
04324     {
04325         TRACE_(d3d_caps)("Format %s is not supported as display format.\n", debug_d3dformat(display_format));
04326         return WINED3DERR_NOTAVAILABLE;
04327     }
04328 
04329     /* If the requested display format is not available, don't continue. */
04330     mode_count = wined3d_get_adapter_mode_count(wined3d, adapter_idx, display_format);
04331     if (!mode_count)
04332     {
04333         TRACE_(d3d_caps)("No available modes for display format %s.\n", debug_d3dformat(display_format));
04334         return WINED3DERR_NOTAVAILABLE;
04335     }
04336 
04337     /* Windowed mode allows you to specify WINED3DFMT_UNKNOWN for the backbuffer format,
04338      * it means 'reuse' the display format for the backbuffer. */
04339     if (!windowed && backbuffer_format == WINED3DFMT_UNKNOWN)
04340     {
04341         TRACE_(d3d_caps)("backbuffer_format WINED3FMT_UNKNOWN only available in windowed mode.\n");
04342         return WINED3DERR_NOTAVAILABLE;
04343     }
04344 
04345     /* In FULLSCREEN mode WINED3DFMT_B5G6R5_UNORM can only be mixed with
04346      * backbuffer format WINED3DFMT_B5G6R5_UNORM. */
04347     if (display_format == WINED3DFMT_B5G6R5_UNORM && backbuffer_format != WINED3DFMT_B5G6R5_UNORM)
04348     {
04349         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s / %s.\n",
04350                 debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
04351         return WINED3DERR_NOTAVAILABLE;
04352     }
04353 
04354     /* In FULLSCREEN mode WINED3DFMT_B5G5R5X1_UNORM can only be mixed with
04355      * backbuffer formats WINED3DFMT_B5G5R5X1_UNORM and
04356      * WINED3DFMT_B5G5R5A1_UNORM. */
04357     if (display_format == WINED3DFMT_B5G5R5X1_UNORM
04358             && !(backbuffer_format == WINED3DFMT_B5G5R5X1_UNORM || backbuffer_format == WINED3DFMT_B5G5R5A1_UNORM))
04359     {
04360         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s / %s.\n",
04361                 debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
04362         return WINED3DERR_NOTAVAILABLE;
04363     }
04364 
04365     /* In FULLSCREEN mode WINED3DFMT_B8G8R8X8_UNORM can only be mixed with
04366      * backbuffer formats WINED3DFMT_B8G8R8X8_UNORM and
04367      * WINED3DFMT_B8G8R8A8_UNORM. */
04368     if (display_format == WINED3DFMT_B8G8R8X8_UNORM
04369             && !(backbuffer_format == WINED3DFMT_B8G8R8X8_UNORM || backbuffer_format == WINED3DFMT_B8G8R8A8_UNORM))
04370     {
04371         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s / %s.\n",
04372                 debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
04373         return WINED3DERR_NOTAVAILABLE;
04374     }
04375 
04376     /* WINED3DFMT_B10G10R10A2_UNORM is only allowed in fullscreen mode and it
04377      * can only be mixed with backbuffer format WINED3DFMT_B10G10R10A2_UNORM. */
04378     if (display_format == WINED3DFMT_B10G10R10A2_UNORM
04379             && (backbuffer_format != WINED3DFMT_B10G10R10A2_UNORM || windowed))
04380     {
04381         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s / %s.\n",
04382                 debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
04383         return WINED3DERR_NOTAVAILABLE;
04384     }
04385 
04386     /* Use CheckDeviceFormat to see if the backbuffer_format is usable with the given display_format */
04387     hr = wined3d_check_device_format(wined3d, adapter_idx, device_type, display_format,
04388             WINED3DUSAGE_RENDERTARGET, WINED3D_RTYPE_SURFACE, backbuffer_format, SURFACE_OPENGL);
04389     if (FAILED(hr))
04390         TRACE_(d3d_caps)("Unsupported display/backbuffer format combination %s / %s.\n",
04391                 debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
04392 
04393     return hr;
04394 }
04395 
04396 HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapter_idx,
04397         enum wined3d_device_type device_type, WINED3DCAPS *caps)
04398 {
04399     const struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx];
04400     const struct wined3d_gl_info *gl_info = &adapter->gl_info;
04401     int vs_selected_mode;
04402     int ps_selected_mode;
04403     struct shader_caps shader_caps;
04404     struct fragment_caps fragment_caps;
04405     DWORD ckey_caps, blit_caps, fx_caps, pal_caps;
04406 
04407     TRACE_(d3d_caps)("wined3d %p, adapter_idx %u, device_type %s, caps %p.\n",
04408             wined3d, adapter_idx, debug_d3ddevicetype(device_type), caps);
04409 
04410     if (adapter_idx >= wined3d->adapter_count)
04411         return WINED3DERR_INVALIDCALL;
04412 
04413     select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
04414 
04415     /* ------------------------------------------------
04416        The following fields apply to both d3d8 and d3d9
04417        ------------------------------------------------ */
04418     /* Not quite true, but use h/w supported by opengl I suppose */
04419     caps->DeviceType = (device_type == WINED3D_DEVICE_TYPE_HAL) ? WINED3D_DEVICE_TYPE_HAL : WINED3D_DEVICE_TYPE_REF;
04420     caps->AdapterOrdinal           = adapter_idx;
04421 
04422     caps->Caps                     = 0;
04423     caps->Caps2                    = WINED3DCAPS2_CANRENDERWINDOWED |
04424                                      WINED3DCAPS2_FULLSCREENGAMMA |
04425                                      WINED3DCAPS2_DYNAMICTEXTURES;
04426     if (gl_info->supported[SGIS_GENERATE_MIPMAP])
04427         caps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
04428 
04429     caps->Caps3                    = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
04430                                      WINED3DCAPS3_COPY_TO_VIDMEM                   |
04431                                      WINED3DCAPS3_COPY_TO_SYSTEMMEM;
04432 
04433     caps->PresentationIntervals    = WINED3DPRESENT_INTERVAL_IMMEDIATE  |
04434                                      WINED3DPRESENT_INTERVAL_ONE;
04435 
04436     caps->CursorCaps               = WINED3DCURSORCAPS_COLOR            |
04437                                      WINED3DCURSORCAPS_LOWRES;
04438 
04439     caps->DevCaps                  = WINED3DDEVCAPS_FLOATTLVERTEX       |
04440                                      WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
04441                                      WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
04442                                      WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
04443                                      WINED3DDEVCAPS_DRAWPRIMTLVERTEX    |
04444                                      WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
04445                                      WINED3DDEVCAPS_EXECUTEVIDEOMEMORY  |
04446                                      WINED3DDEVCAPS_PUREDEVICE          |
04447                                      WINED3DDEVCAPS_HWRASTERIZATION     |
04448                                      WINED3DDEVCAPS_TEXTUREVIDEOMEMORY  |
04449                                      WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
04450                                      WINED3DDEVCAPS_CANRENDERAFTERFLIP  |
04451                                      WINED3DDEVCAPS_DRAWPRIMITIVES2     |
04452                                      WINED3DDEVCAPS_DRAWPRIMITIVES2EX   |
04453                                      WINED3DDEVCAPS_RTPATCHES;
04454 
04455     caps->PrimitiveMiscCaps        = WINED3DPMISCCAPS_CULLNONE              |
04456                                      WINED3DPMISCCAPS_CULLCCW               |
04457                                      WINED3DPMISCCAPS_CULLCW                |
04458                                      WINED3DPMISCCAPS_COLORWRITEENABLE      |
04459                                      WINED3DPMISCCAPS_CLIPTLVERTS           |
04460                                      WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
04461                                      WINED3DPMISCCAPS_MASKZ                 |
04462                                      WINED3DPMISCCAPS_BLENDOP               |
04463                                      WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING;
04464                                     /* TODO:
04465                                         WINED3DPMISCCAPS_NULLREFERENCE
04466                                         WINED3DPMISCCAPS_FOGANDSPECULARALPHA
04467                                         WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
04468                                         WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
04469 
04470     if (gl_info->supported[EXT_BLEND_EQUATION_SEPARATE] && gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
04471         caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND;
04472     if (gl_info->supported[EXT_DRAW_BUFFERS2])
04473         caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS;
04474 
04475     caps->RasterCaps               = WINED3DPRASTERCAPS_DITHER    |
04476                                      WINED3DPRASTERCAPS_PAT       |
04477                                      WINED3DPRASTERCAPS_WFOG      |
04478                                      WINED3DPRASTERCAPS_ZFOG      |
04479                                      WINED3DPRASTERCAPS_FOGVERTEX |
04480                                      WINED3DPRASTERCAPS_FOGTABLE  |
04481                                      WINED3DPRASTERCAPS_STIPPLE   |
04482                                      WINED3DPRASTERCAPS_SUBPIXEL  |
04483                                      WINED3DPRASTERCAPS_ZTEST     |
04484                                      WINED3DPRASTERCAPS_SCISSORTEST   |
04485                                      WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
04486                                      WINED3DPRASTERCAPS_DEPTHBIAS;
04487 
04488     if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
04489     {
04490         caps->RasterCaps  |= WINED3DPRASTERCAPS_ANISOTROPY    |
04491                              WINED3DPRASTERCAPS_ZBIAS         |
04492                              WINED3DPRASTERCAPS_MIPMAPLODBIAS;
04493     }
04494     if (gl_info->supported[NV_FOG_DISTANCE])
04495     {
04496         caps->RasterCaps          |= WINED3DPRASTERCAPS_FOGRANGE;
04497     }
04498                         /* FIXME Add:
04499                            WINED3DPRASTERCAPS_COLORPERSPECTIVE
04500                            WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
04501                            WINED3DPRASTERCAPS_ANTIALIASEDGES
04502                            WINED3DPRASTERCAPS_ZBUFFERLESSHSR
04503                            WINED3DPRASTERCAPS_WBUFFER */
04504 
04505     caps->ZCmpCaps =  WINED3DPCMPCAPS_ALWAYS       |
04506                       WINED3DPCMPCAPS_EQUAL        |
04507                       WINED3DPCMPCAPS_GREATER      |
04508                       WINED3DPCMPCAPS_GREATEREQUAL |
04509                       WINED3DPCMPCAPS_LESS         |
04510                       WINED3DPCMPCAPS_LESSEQUAL    |
04511                       WINED3DPCMPCAPS_NEVER        |
04512                       WINED3DPCMPCAPS_NOTEQUAL;
04513 
04514     caps->SrcBlendCaps  =  WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
04515                            WINED3DPBLENDCAPS_BOTHSRCALPHA    |
04516                            WINED3DPBLENDCAPS_DESTALPHA       |
04517                            WINED3DPBLENDCAPS_DESTCOLOR       |
04518                            WINED3DPBLENDCAPS_INVDESTALPHA    |
04519                            WINED3DPBLENDCAPS_INVDESTCOLOR    |
04520                            WINED3DPBLENDCAPS_INVSRCALPHA     |
04521                            WINED3DPBLENDCAPS_INVSRCCOLOR     |
04522                            WINED3DPBLENDCAPS_ONE             |
04523                            WINED3DPBLENDCAPS_SRCALPHA        |
04524                            WINED3DPBLENDCAPS_SRCALPHASAT     |
04525                            WINED3DPBLENDCAPS_SRCCOLOR        |
04526                            WINED3DPBLENDCAPS_ZERO;
04527 
04528     caps->DestBlendCaps =  WINED3DPBLENDCAPS_DESTALPHA       |
04529                            WINED3DPBLENDCAPS_DESTCOLOR       |
04530                            WINED3DPBLENDCAPS_INVDESTALPHA    |
04531                            WINED3DPBLENDCAPS_INVDESTCOLOR    |
04532                            WINED3DPBLENDCAPS_INVSRCALPHA     |
04533                            WINED3DPBLENDCAPS_INVSRCCOLOR     |
04534                            WINED3DPBLENDCAPS_ONE             |
04535                            WINED3DPBLENDCAPS_SRCALPHA        |
04536                            WINED3DPBLENDCAPS_SRCCOLOR        |
04537                            WINED3DPBLENDCAPS_ZERO;
04538     /* NOTE: WINED3DPBLENDCAPS_SRCALPHASAT is not supported as dest blend factor,
04539      * according to the glBlendFunc manpage
04540      *
04541      * WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA are
04542      * legacy settings for srcblend only
04543      */
04544 
04545     if (gl_info->supported[EXT_BLEND_COLOR])
04546     {
04547         caps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
04548         caps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
04549     }
04550 
04551 
04552     caps->AlphaCmpCaps  = WINED3DPCMPCAPS_ALWAYS       |
04553                           WINED3DPCMPCAPS_EQUAL        |
04554                           WINED3DPCMPCAPS_GREATER      |
04555                           WINED3DPCMPCAPS_GREATEREQUAL |
04556                           WINED3DPCMPCAPS_LESS         |
04557                           WINED3DPCMPCAPS_LESSEQUAL    |
04558                           WINED3DPCMPCAPS_NEVER        |
04559                           WINED3DPCMPCAPS_NOTEQUAL;
04560 
04561     caps->ShadeCaps      = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
04562                            WINED3DPSHADECAPS_COLORGOURAUDRGB    |
04563                            WINED3DPSHADECAPS_ALPHAFLATBLEND     |
04564                            WINED3DPSHADECAPS_ALPHAGOURAUDBLEND  |
04565                            WINED3DPSHADECAPS_COLORFLATRGB       |
04566                            WINED3DPSHADECAPS_FOGFLAT            |
04567                            WINED3DPSHADECAPS_FOGGOURAUD         |
04568                            WINED3DPSHADECAPS_SPECULARFLATRGB;
04569 
04570     caps->TextureCaps   = WINED3DPTEXTURECAPS_ALPHA              |
04571                           WINED3DPTEXTURECAPS_ALPHAPALETTE       |
04572                           WINED3DPTEXTURECAPS_TRANSPARENCY       |
04573                           WINED3DPTEXTURECAPS_BORDER             |
04574                           WINED3DPTEXTURECAPS_MIPMAP             |
04575                           WINED3DPTEXTURECAPS_PROJECTED          |
04576                           WINED3DPTEXTURECAPS_PERSPECTIVE;
04577 
04578     if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
04579     {
04580         caps->TextureCaps  |= WINED3DPTEXTURECAPS_POW2 |
04581                               WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
04582     }
04583 
04584     if (gl_info->supported[EXT_TEXTURE3D])
04585     {
04586         caps->TextureCaps  |=  WINED3DPTEXTURECAPS_VOLUMEMAP      |
04587                                WINED3DPTEXTURECAPS_MIPVOLUMEMAP;
04588         if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
04589         {
04590             caps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
04591         }
04592     }
04593 
04594     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
04595     {
04596         caps->TextureCaps  |= WINED3DPTEXTURECAPS_CUBEMAP     |
04597                               WINED3DPTEXTURECAPS_MIPCUBEMAP;
04598         if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
04599         {
04600             caps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP_POW2;
04601         }
04602     }
04603 
04604     caps->TextureFilterCaps =  WINED3DPTFILTERCAPS_MAGFLINEAR       |
04605                                WINED3DPTFILTERCAPS_MAGFPOINT        |
04606                                WINED3DPTFILTERCAPS_MINFLINEAR       |
04607                                WINED3DPTFILTERCAPS_MINFPOINT        |
04608                                WINED3DPTFILTERCAPS_MIPFLINEAR       |
04609                                WINED3DPTFILTERCAPS_MIPFPOINT        |
04610                                WINED3DPTFILTERCAPS_LINEAR           |
04611                                WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
04612                                WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
04613                                WINED3DPTFILTERCAPS_MIPLINEAR        |
04614                                WINED3DPTFILTERCAPS_MIPNEAREST       |
04615                                WINED3DPTFILTERCAPS_NEAREST;
04616 
04617     if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
04618     {
04619         caps->TextureFilterCaps  |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
04620                                     WINED3DPTFILTERCAPS_MINFANISOTROPIC;
04621     }
04622 
04623     if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
04624     {
04625         caps->CubeTextureFilterCaps =  WINED3DPTFILTERCAPS_MAGFLINEAR       |
04626                                        WINED3DPTFILTERCAPS_MAGFPOINT        |
04627                                        WINED3DPTFILTERCAPS_MINFLINEAR       |
04628                                        WINED3DPTFILTERCAPS_MINFPOINT        |
04629                                        WINED3DPTFILTERCAPS_MIPFLINEAR       |
04630                                        WINED3DPTFILTERCAPS_MIPFPOINT        |
04631                                        WINED3DPTFILTERCAPS_LINEAR           |
04632                                        WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
04633                                        WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
04634                                        WINED3DPTFILTERCAPS_MIPLINEAR        |
04635                                        WINED3DPTFILTERCAPS_MIPNEAREST       |
04636                                        WINED3DPTFILTERCAPS_NEAREST;
04637 
04638         if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
04639         {
04640             caps->CubeTextureFilterCaps  |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
04641                                             WINED3DPTFILTERCAPS_MINFANISOTROPIC;
04642         }
04643     }
04644     else
04645     {
04646         caps->CubeTextureFilterCaps = 0;
04647     }
04648 
04649     if (gl_info->supported[EXT_TEXTURE3D])
04650     {
04651         caps->VolumeTextureFilterCaps  = WINED3DPTFILTERCAPS_MAGFLINEAR       |
04652                                          WINED3DPTFILTERCAPS_MAGFPOINT        |
04653                                          WINED3DPTFILTERCAPS_MINFLINEAR       |
04654                                          WINED3DPTFILTERCAPS_MINFPOINT        |
04655                                          WINED3DPTFILTERCAPS_MIPFLINEAR       |
04656                                          WINED3DPTFILTERCAPS_MIPFPOINT        |
04657                                          WINED3DPTFILTERCAPS_LINEAR           |
04658                                          WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
04659                                          WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
04660                                          WINED3DPTFILTERCAPS_MIPLINEAR        |
04661                                          WINED3DPTFILTERCAPS_MIPNEAREST       |
04662                                          WINED3DPTFILTERCAPS_NEAREST;
04663     }
04664     else
04665     {
04666         caps->VolumeTextureFilterCaps = 0;
04667     }
04668 
04669     caps->TextureAddressCaps  =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
04670                                  WINED3DPTADDRESSCAPS_CLAMP  |
04671                                  WINED3DPTADDRESSCAPS_WRAP;
04672 
04673     if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
04674     {
04675         caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
04676     }
04677     if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
04678     {
04679         caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
04680     }
04681     if (gl_info->supported[ATI_TEXTURE_MIRROR_ONCE])
04682     {
04683         caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
04684     }
04685 
04686     if (gl_info->supported[EXT_TEXTURE3D])
04687     {
04688         caps->VolumeTextureAddressCaps =   WINED3DPTADDRESSCAPS_INDEPENDENTUV |
04689                                            WINED3DPTADDRESSCAPS_CLAMP  |
04690                                            WINED3DPTADDRESSCAPS_WRAP;
04691         if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
04692         {
04693             caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
04694         }
04695         if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
04696         {
04697             caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
04698         }
04699         if (gl_info->supported[ATI_TEXTURE_MIRROR_ONCE])
04700         {
04701             caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
04702         }
04703     }
04704     else
04705     {
04706         caps->VolumeTextureAddressCaps = 0;
04707     }
04708 
04709     caps->LineCaps  = WINED3DLINECAPS_TEXTURE       |
04710                       WINED3DLINECAPS_ZTEST         |
04711                       WINED3DLINECAPS_BLEND         |
04712                       WINED3DLINECAPS_ALPHACMP      |
04713                       WINED3DLINECAPS_FOG;
04714     /* WINED3DLINECAPS_ANTIALIAS is not supported on Windows, and dx and gl seem to have a different
04715      * idea how generating the smoothing alpha values works; the result is different
04716      */
04717 
04718     caps->MaxTextureWidth = gl_info->limits.texture_size;
04719     caps->MaxTextureHeight = gl_info->limits.texture_size;
04720 
04721     if (gl_info->supported[EXT_TEXTURE3D])
04722         caps->MaxVolumeExtent = gl_info->limits.texture3d_size;
04723     else
04724         caps->MaxVolumeExtent = 0;
04725 
04726     caps->MaxTextureRepeat = 32768;
04727     caps->MaxTextureAspectRatio = gl_info->limits.texture_size;
04728     caps->MaxVertexW = 1.0f;
04729 
04730     caps->GuardBandLeft = 0.0f;
04731     caps->GuardBandTop = 0.0f;
04732     caps->GuardBandRight = 0.0f;
04733     caps->GuardBandBottom = 0.0f;
04734 
04735     caps->ExtentsAdjust = 0.0f;
04736 
04737     caps->StencilCaps   = WINED3DSTENCILCAPS_DECRSAT |
04738                           WINED3DSTENCILCAPS_INCRSAT |
04739                           WINED3DSTENCILCAPS_INVERT  |
04740                           WINED3DSTENCILCAPS_KEEP    |
04741                           WINED3DSTENCILCAPS_REPLACE |
04742                           WINED3DSTENCILCAPS_ZERO;
04743     if (gl_info->supported[EXT_STENCIL_WRAP])
04744     {
04745         caps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
04746                               WINED3DSTENCILCAPS_INCR;
04747     }
04748     if (gl_info->supported[EXT_STENCIL_TWO_SIDE] || gl_info->supported[ATI_SEPARATE_STENCIL])
04749     {
04750         caps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
04751     }
04752 
04753     caps->FVFCaps = WINED3DFVFCAPS_PSIZE | 0x0008; /* 8 texture coords */
04754 
04755     caps->MaxUserClipPlanes = gl_info->limits.clipplanes;
04756     caps->MaxActiveLights = gl_info->limits.lights;
04757 
04758     caps->MaxVertexBlendMatrices = gl_info->limits.blends;
04759     caps->MaxVertexBlendMatrixIndex   = 0;
04760 
04761     caps->MaxAnisotropy = gl_info->limits.anisotropy;
04762     caps->MaxPointSize = gl_info->limits.pointsize_max;
04763 
04764 
04765     /* FIXME: Add D3DVTXPCAPS_TWEENING, D3DVTXPCAPS_TEXGEN_SPHEREMAP */
04766     caps->VertexProcessingCaps  = WINED3DVTXPCAPS_DIRECTIONALLIGHTS |
04767                                   WINED3DVTXPCAPS_MATERIALSOURCE7   |
04768                                   WINED3DVTXPCAPS_POSITIONALLIGHTS  |
04769                                   WINED3DVTXPCAPS_LOCALVIEWER       |
04770                                   WINED3DVTXPCAPS_VERTEXFOG         |
04771                                   WINED3DVTXPCAPS_TEXGEN;
04772 
04773     caps->MaxPrimitiveCount   = 0xFFFFF; /* For now set 2^20-1 which is used by most >=Geforce3/Radeon8500 cards */
04774     caps->MaxVertexIndex      = 0xFFFFF;
04775     caps->MaxStreams          = MAX_STREAMS;
04776     caps->MaxStreamStride     = 1024;
04777 
04778     /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
04779     caps->DevCaps2                          = WINED3DDEVCAPS2_STREAMOFFSET |
04780                                               WINED3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET;
04781     caps->MaxNpatchTessellationLevel        = 0;
04782     caps->MasterAdapterOrdinal              = 0;
04783     caps->AdapterOrdinalInGroup             = 0;
04784     caps->NumberOfAdaptersInGroup           = 1;
04785 
04786     caps->NumSimultaneousRTs = gl_info->limits.buffers;
04787 
04788     caps->StretchRectFilterCaps               = WINED3DPTFILTERCAPS_MINFPOINT  |
04789                                                 WINED3DPTFILTERCAPS_MAGFPOINT  |
04790                                                 WINED3DPTFILTERCAPS_MINFLINEAR |
04791                                                 WINED3DPTFILTERCAPS_MAGFLINEAR;
04792     caps->VertexTextureFilterCaps             = 0;
04793 
04794     adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
04795     adapter->fragment_pipe->get_caps(&adapter->gl_info, &fragment_caps);
04796 
04797     /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
04798     caps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps;
04799 
04800     /* This takes care for disabling vertex shader or pixel shader caps while leaving the other one enabled.
04801      * Ignore shader model capabilities if disabled in config
04802      */
04803     if (vs_selected_mode == SHADER_NONE)
04804     {
04805         TRACE_(d3d_caps)("Vertex shader disabled in config, reporting version 0.0\n");
04806         caps->VertexShaderVersion          = 0;
04807         caps->MaxVertexShaderConst         = 0;
04808     }
04809     else
04810     {
04811         caps->VertexShaderVersion          = shader_caps.VertexShaderVersion;
04812         caps->MaxVertexShaderConst         = shader_caps.MaxVertexShaderConst;
04813     }
04814 
04815     if (ps_selected_mode == SHADER_NONE)
04816     {
04817         TRACE_(d3d_caps)("Pixel shader disabled in config, reporting version 0.0\n");
04818         caps->PixelShaderVersion           = 0;
04819         caps->PixelShader1xMaxValue        = 0.0f;
04820     } else {
04821         caps->PixelShaderVersion           = shader_caps.PixelShaderVersion;
04822         caps->PixelShader1xMaxValue        = shader_caps.PixelShader1xMaxValue;
04823     }
04824 
04825     caps->TextureOpCaps                    = fragment_caps.TextureOpCaps;
04826     caps->MaxTextureBlendStages            = fragment_caps.MaxTextureBlendStages;
04827     caps->MaxSimultaneousTextures          = fragment_caps.MaxSimultaneousTextures;
04828 
04829     /* The following caps are shader specific, but they are things we cannot detect, or which
04830      * are the same among all shader models. So to avoid code duplication set the shader version
04831      * specific, but otherwise constant caps here
04832      */
04833     if (caps->VertexShaderVersion >= 3)
04834     {
04835         /* Where possible set the caps based on OpenGL extensions and if they
04836          * aren't set (in case of software rendering) use the VS 3.0 from
04837          * MSDN or else if there's OpenGL spec use a hardcoded value minimum
04838          * VS3.0 value. */
04839         caps->VS20Caps.caps = WINED3DVS20CAPS_PREDICATION;
04840         /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
04841         caps->VS20Caps.dynamic_flow_control_depth = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH;
04842         caps->VS20Caps.temp_count = max(32, adapter->gl_info.limits.arb_vs_temps);
04843         /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
04844         caps->VS20Caps.static_flow_control_depth = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH;
04845 
04846         caps->MaxVShaderInstructionsExecuted    = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
04847         caps->MaxVertexShader30InstructionSlots = max(512, adapter->gl_info.limits.arb_vs_instructions);
04848     }
04849     else if (caps->VertexShaderVersion == 2)
04850     {
04851         caps->VS20Caps.caps = 0;
04852         caps->VS20Caps.dynamic_flow_control_depth = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
04853         caps->VS20Caps.temp_count = max(12, adapter->gl_info.limits.arb_vs_temps);
04854         caps->VS20Caps.static_flow_control_depth = 1;
04855 
04856         caps->MaxVShaderInstructionsExecuted    = 65535;
04857         caps->MaxVertexShader30InstructionSlots = 0;
04858     }
04859     else
04860     { /* VS 1.x */
04861         caps->VS20Caps.caps = 0;
04862         caps->VS20Caps.dynamic_flow_control_depth = 0;
04863         caps->VS20Caps.temp_count = 0;
04864         caps->VS20Caps.static_flow_control_depth = 0;
04865 
04866         caps->MaxVShaderInstructionsExecuted    = 0;
04867         caps->MaxVertexShader30InstructionSlots = 0;
04868     }
04869 
04870     if (caps->PixelShaderVersion >= 3)
04871     {
04872         /* Where possible set the caps based on OpenGL extensions and if they
04873          * aren't set (in case of software rendering) use the PS 3.0 from
04874          * MSDN or else if there's OpenGL spec use a hardcoded value minimum
04875          * PS 3.0 value. */
04876 
04877         /* Caps is more or less undocumented on MSDN but it appears to be
04878          * used for PS20Caps based on results from R9600/FX5900/Geforce6800
04879          * cards from Windows */
04880         caps->PS20Caps.caps = WINED3DPS20CAPS_ARBITRARYSWIZZLE |
04881                 WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
04882                 WINED3DPS20CAPS_PREDICATION          |
04883                 WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
04884                 WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
04885         /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
04886         caps->PS20Caps.dynamic_flow_control_depth = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH;
04887         caps->PS20Caps.temp_count = max(32, adapter->gl_info.limits.arb_ps_temps);
04888         /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
04889         caps->PS20Caps.static_flow_control_depth = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH;
04890         /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
04891         caps->PS20Caps.instruction_slot_count = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS;
04892 
04893         caps->MaxPShaderInstructionsExecuted = 65535;
04894         caps->MaxPixelShader30InstructionSlots = max(WINED3DMIN30SHADERINSTRUCTIONS,
04895                 adapter->gl_info.limits.arb_ps_instructions);
04896     }
04897     else if(caps->PixelShaderVersion == 2)
04898     {
04899         /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
04900         caps->PS20Caps.caps = 0;
04901         caps->PS20Caps.dynamic_flow_control_depth = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
04902         caps->PS20Caps.temp_count = max(12, adapter->gl_info.limits.arb_ps_temps);
04903         caps->PS20Caps.static_flow_control_depth = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minimum: 1 */
04904         /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
04905         caps->PS20Caps.instruction_slot_count = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS;
04906 
04907         caps->MaxPShaderInstructionsExecuted    = 512; /* Minimum value, a GeforceFX uses 1024 */
04908         caps->MaxPixelShader30InstructionSlots  = 0;
04909     }
04910     else /* PS 1.x */
04911     {
04912         caps->PS20Caps.caps = 0;
04913         caps->PS20Caps.dynamic_flow_control_depth = 0;
04914         caps->PS20Caps.temp_count = 0;
04915         caps->PS20Caps.static_flow_control_depth = 0;
04916         caps->PS20Caps.instruction_slot_count = 0;
04917 
04918         caps->MaxPShaderInstructionsExecuted    = 0;
04919         caps->MaxPixelShader30InstructionSlots  = 0;
04920     }
04921 
04922     if (caps->VertexShaderVersion >= 2)
04923     {
04924         /* OpenGL supports all the formats below, perhaps not always
04925          * without conversion, but it supports them.
04926          * Further GLSL doesn't seem to have an official unsigned type so
04927          * don't advertise it yet as I'm not sure how we handle it.
04928          * We might need to add some clamping in the shader engine to
04929          * support it.
04930          * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
04931         caps->DeclTypes = WINED3DDTCAPS_UBYTE4    |
04932                           WINED3DDTCAPS_UBYTE4N   |
04933                           WINED3DDTCAPS_SHORT2N   |
04934                           WINED3DDTCAPS_SHORT4N;
04935         if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
04936         {
04937             caps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 |
04938                                WINED3DDTCAPS_FLOAT16_4;
04939         }
04940     }
04941     else
04942     {
04943         caps->DeclTypes = 0;
04944     }
04945 
04946     /* Set DirectDraw helper Caps */
04947     ckey_caps =                         WINEDDCKEYCAPS_DESTBLT              |
04948                                         WINEDDCKEYCAPS_SRCBLT;
04949     fx_caps =                           WINEDDFXCAPS_BLTALPHA               |
04950                                         WINEDDFXCAPS_BLTMIRRORLEFTRIGHT     |
04951                                         WINEDDFXCAPS_BLTMIRRORUPDOWN        |
04952                                         WINEDDFXCAPS_BLTROTATION90          |
04953                                         WINEDDFXCAPS_BLTSHRINKX             |
04954                                         WINEDDFXCAPS_BLTSHRINKXN            |
04955                                         WINEDDFXCAPS_BLTSHRINKY             |
04956                                         WINEDDFXCAPS_BLTSHRINKXN            |
04957                                         WINEDDFXCAPS_BLTSTRETCHX            |
04958                                         WINEDDFXCAPS_BLTSTRETCHXN           |
04959                                         WINEDDFXCAPS_BLTSTRETCHY            |
04960                                         WINEDDFXCAPS_BLTSTRETCHYN;
04961     blit_caps =                         WINEDDCAPS_BLT                      |
04962                                         WINEDDCAPS_BLTCOLORFILL             |
04963                                         WINEDDCAPS_BLTDEPTHFILL             |
04964                                         WINEDDCAPS_BLTSTRETCH               |
04965                                         WINEDDCAPS_CANBLTSYSMEM             |
04966                                         WINEDDCAPS_CANCLIP                  |
04967                                         WINEDDCAPS_CANCLIPSTRETCHED         |
04968                                         WINEDDCAPS_COLORKEY                 |
04969                                         WINEDDCAPS_COLORKEYHWASSIST         |
04970                                         WINEDDCAPS_ALIGNBOUNDARYSRC;
04971     pal_caps =                          WINEDDPCAPS_8BIT                    |
04972                                         WINEDDPCAPS_PRIMARYSURFACE;
04973 
04974     /* Fill the ddraw caps structure */
04975     caps->ddraw_caps.caps =             WINEDDCAPS_GDI                      |
04976                                         WINEDDCAPS_PALETTE                  |
04977                                         blit_caps;
04978     caps->ddraw_caps.caps2 =            WINEDDCAPS2_CERTIFIED               |
04979                                         WINEDDCAPS2_NOPAGELOCKREQUIRED      |
04980                                         WINEDDCAPS2_PRIMARYGAMMA            |
04981                                         WINEDDCAPS2_WIDESURFACES            |
04982                                         WINEDDCAPS2_CANRENDERWINDOWED;
04983     caps->ddraw_caps.color_key_caps = ckey_caps;
04984     caps->ddraw_caps.fx_caps = fx_caps;
04985     caps->ddraw_caps.pal_caps = pal_caps;
04986     caps->ddraw_caps.svb_caps = blit_caps;
04987     caps->ddraw_caps.svb_color_key_caps = ckey_caps;
04988     caps->ddraw_caps.svb_fx_caps = fx_caps;
04989     caps->ddraw_caps.vsb_caps = blit_caps;
04990     caps->ddraw_caps.vsb_color_key_caps = ckey_caps;
04991     caps->ddraw_caps.vsb_fx_caps = fx_caps;
04992     caps->ddraw_caps.ssb_caps = blit_caps;
04993     caps->ddraw_caps.ssb_color_key_caps = ckey_caps;
04994     caps->ddraw_caps.ssb_fx_caps = fx_caps;
04995 
04996     caps->ddraw_caps.dds_caps =         WINEDDSCAPS_ALPHA                   |
04997                                         WINEDDSCAPS_BACKBUFFER              |
04998                                         WINEDDSCAPS_FLIP                    |
04999                                         WINEDDSCAPS_FRONTBUFFER             |
05000                                         WINEDDSCAPS_OFFSCREENPLAIN          |
05001                                         WINEDDSCAPS_PALETTE                 |
05002                                         WINEDDSCAPS_PRIMARYSURFACE          |
05003                                         WINEDDSCAPS_SYSTEMMEMORY            |
05004                                         WINEDDSCAPS_VIDEOMEMORY             |
05005                                         WINEDDSCAPS_VISIBLE;
05006     caps->ddraw_caps.stride_align = DDRAW_PITCH_ALIGNMENT;
05007 
05008     /* Set D3D caps if OpenGL is available. */
05009     if (adapter->opengl)
05010     {
05011         caps->ddraw_caps.dds_caps |=    WINEDDSCAPS_3DDEVICE                |
05012                                         WINEDDSCAPS_MIPMAP                  |
05013                                         WINEDDSCAPS_TEXTURE                 |
05014                                         WINEDDSCAPS_ZBUFFER;
05015         caps->ddraw_caps.caps |=        WINEDDCAPS_3D;
05016     }
05017 
05018     return WINED3D_OK;
05019 }
05020 
05021 HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, enum wined3d_device_type device_type,
05022         HWND focus_window, DWORD flags, BYTE surface_alignment, struct wined3d_device_parent *device_parent,
05023         struct wined3d_device **device)
05024 {
05025     struct wined3d_device *object;
05026     HRESULT hr;
05027 
05028     TRACE("wined3d %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x, device_parent %p, device %p.\n",
05029             wined3d, adapter_idx, device_type, focus_window, flags, device_parent, device);
05030 
05031     /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
05032      * number and create a device without a 3D adapter for 2D only operation. */
05033     if (wined3d->adapter_count && adapter_idx >= wined3d->adapter_count)
05034         return WINED3DERR_INVALIDCALL;
05035 
05036     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
05037     if (!object)
05038     {
05039         ERR("Failed to allocate device memory.\n");
05040         return E_OUTOFMEMORY;
05041     }
05042 
05043     hr = device_init(object, wined3d, adapter_idx, device_type,
05044             focus_window, flags, surface_alignment, device_parent);
05045     if (FAILED(hr))
05046     {
05047         WARN("Failed to initialize device, hr %#x.\n", hr);
05048         HeapFree(GetProcessHeap(), 0, object);
05049         return hr;
05050     }
05051 
05052     TRACE("Created device %p.\n", object);
05053     *device = object;
05054 
05055     device_parent->ops->wined3d_device_created(device_parent, *device);
05056 
05057     return WINED3D_OK;
05058 }
05059 
05060 void * CDECL wined3d_get_parent(const struct wined3d *wined3d)
05061 {
05062     TRACE("wined3d %p.\n", wined3d);
05063 
05064     return wined3d->parent;
05065 }
05066 
05067 static void WINE_GLAPI invalid_func(const void *data)
05068 {
05069     ERR("Invalid vertex attribute function called\n");
05070     DebugBreak();
05071 }
05072 
05073 static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data)
05074 {
05075     ERR("Invalid texcoord function called\n");
05076     DebugBreak();
05077 }
05078 
05079 /* Helper functions for providing vertex data to opengl. The arrays are initialized based on
05080  * the extension detection and are used in drawStridedSlow
05081  */
05082 static void WINE_GLAPI position_d3dcolor(const void *data)
05083 {
05084     DWORD pos = *((const DWORD *)data);
05085 
05086     FIXME("Add a test for fixed function position from d3dcolor type\n");
05087     glVertex4s(D3DCOLOR_B_R(pos),
05088                D3DCOLOR_B_G(pos),
05089                D3DCOLOR_B_B(pos),
05090                D3DCOLOR_B_A(pos));
05091 }
05092 
05093 static void WINE_GLAPI position_float4(const void *data)
05094 {
05095     const GLfloat *pos = data;
05096 
05097     if (pos[3] != 0.0f && pos[3] != 1.0f)
05098     {
05099         float w = 1.0f / pos[3];
05100 
05101         glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w);
05102     }
05103     else
05104     {
05105         glVertex3fv(pos);
05106     }
05107 }
05108 
05109 static void WINE_GLAPI diffuse_d3dcolor(const void *data)
05110 {
05111     DWORD diffuseColor = *((const DWORD *)data);
05112 
05113     glColor4ub(D3DCOLOR_B_R(diffuseColor),
05114                D3DCOLOR_B_G(diffuseColor),
05115                D3DCOLOR_B_B(diffuseColor),
05116                D3DCOLOR_B_A(diffuseColor));
05117 }
05118 
05119 static void WINE_GLAPI specular_d3dcolor(const void *data)
05120 {
05121     DWORD specularColor = *((const DWORD *)data);
05122     GLbyte d[] = {D3DCOLOR_B_R(specularColor),
05123             D3DCOLOR_B_G(specularColor),
05124             D3DCOLOR_B_B(specularColor)};
05125 
05126     specular_func_3ubv(d);
05127 }
05128 
05129 static void WINE_GLAPI warn_no_specular_func(const void *data)
05130 {
05131     WARN("GL_EXT_secondary_color not supported\n");
05132 }
05133 
05134 static void fillGLAttribFuncs(const struct wined3d_gl_info *gl_info)
05135 {
05136     position_funcs[WINED3D_FFP_EMIT_FLOAT1]      = invalid_func;
05137     position_funcs[WINED3D_FFP_EMIT_FLOAT2]      = invalid_func;
05138     position_funcs[WINED3D_FFP_EMIT_FLOAT3]      = (glAttribFunc)glVertex3fv;
05139     position_funcs[WINED3D_FFP_EMIT_FLOAT4]      = position_float4;
05140     position_funcs[WINED3D_FFP_EMIT_D3DCOLOR]    = position_d3dcolor;
05141     position_funcs[WINED3D_FFP_EMIT_UBYTE4]      = invalid_func;
05142     position_funcs[WINED3D_FFP_EMIT_SHORT2]      = invalid_func;
05143     position_funcs[WINED3D_FFP_EMIT_SHORT4]      = (glAttribFunc)glVertex2sv;
05144     position_funcs[WINED3D_FFP_EMIT_UBYTE4N]     = invalid_func;
05145     position_funcs[WINED3D_FFP_EMIT_SHORT2N]     = invalid_func;
05146     position_funcs[WINED3D_FFP_EMIT_SHORT4N]     = invalid_func;
05147     position_funcs[WINED3D_FFP_EMIT_USHORT2N]    = invalid_func;
05148     position_funcs[WINED3D_FFP_EMIT_USHORT4N]    = invalid_func;
05149     position_funcs[WINED3D_FFP_EMIT_UDEC3]       = invalid_func;
05150     position_funcs[WINED3D_FFP_EMIT_DEC3N]       = invalid_func;
05151     position_funcs[WINED3D_FFP_EMIT_FLOAT16_2]   = invalid_func;
05152     position_funcs[WINED3D_FFP_EMIT_FLOAT16_4]   = invalid_func;
05153 
05154     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT1]       = invalid_func;
05155     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT2]       = invalid_func;
05156     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT3]       = (glAttribFunc)glColor3fv;
05157     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT4]       = (glAttribFunc)glColor4fv;
05158     diffuse_funcs[WINED3D_FFP_EMIT_D3DCOLOR]     = diffuse_d3dcolor;
05159     diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4]       = invalid_func;
05160     diffuse_funcs[WINED3D_FFP_EMIT_SHORT2]       = invalid_func;
05161     diffuse_funcs[WINED3D_FFP_EMIT_SHORT4]       = invalid_func;
05162     diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4N]      = (glAttribFunc)glColor4ubv;
05163     diffuse_funcs[WINED3D_FFP_EMIT_SHORT2N]      = invalid_func;
05164     diffuse_funcs[WINED3D_FFP_EMIT_SHORT4N]      = (glAttribFunc)glColor4sv;
05165     diffuse_funcs[WINED3D_FFP_EMIT_USHORT2N]     = invalid_func;
05166     diffuse_funcs[WINED3D_FFP_EMIT_USHORT4N]     = (glAttribFunc)glColor4usv;
05167     diffuse_funcs[WINED3D_FFP_EMIT_UDEC3]        = invalid_func;
05168     diffuse_funcs[WINED3D_FFP_EMIT_DEC3N]        = invalid_func;
05169     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_2]    = invalid_func;
05170     diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_4]    = invalid_func;
05171 
05172     /* No 4 component entry points here */
05173     specular_funcs[WINED3D_FFP_EMIT_FLOAT1]      = invalid_func;
05174     specular_funcs[WINED3D_FFP_EMIT_FLOAT2]      = invalid_func;
05175     if (gl_info->supported[EXT_SECONDARY_COLOR])
05176     {
05177         specular_funcs[WINED3D_FFP_EMIT_FLOAT3]  = (glAttribFunc)GL_EXTCALL(glSecondaryColor3fvEXT);
05178     }
05179     else
05180     {
05181         specular_funcs[WINED3D_FFP_EMIT_FLOAT3]  = warn_no_specular_func;
05182     }
05183     specular_funcs[WINED3D_FFP_EMIT_FLOAT4]      = invalid_func;
05184     if (gl_info->supported[EXT_SECONDARY_COLOR])
05185     {
05186         specular_func_3ubv = (glAttribFunc)GL_EXTCALL(glSecondaryColor3ubvEXT);
05187         specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = specular_d3dcolor;
05188     }
05189     else
05190     {
05191         specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = warn_no_specular_func;
05192     }
05193     specular_funcs[WINED3D_FFP_EMIT_UBYTE4]      = invalid_func;
05194     specular_funcs[WINED3D_FFP_EMIT_SHORT2]      = invalid_func;
05195     specular_funcs[WINED3D_FFP_EMIT_SHORT4]      = invalid_func;
05196     specular_funcs[WINED3D_FFP_EMIT_UBYTE4N]     = invalid_func;
05197     specular_funcs[WINED3D_FFP_EMIT_SHORT2N]     = invalid_func;
05198     specular_funcs[WINED3D_FFP_EMIT_SHORT4N]     = invalid_func;
05199     specular_funcs[WINED3D_FFP_EMIT_USHORT2N]    = invalid_func;
05200     specular_funcs[WINED3D_FFP_EMIT_USHORT4N]    = invalid_func;
05201     specular_funcs[WINED3D_FFP_EMIT_UDEC3]       = invalid_func;
05202     specular_funcs[WINED3D_FFP_EMIT_DEC3N]       = invalid_func;
05203     specular_funcs[WINED3D_FFP_EMIT_FLOAT16_2]   = invalid_func;
05204     specular_funcs[WINED3D_FFP_EMIT_FLOAT16_4]   = invalid_func;
05205 
05206     /* Only 3 component entry points here. Test how others behave. Float4 normals are used
05207      * by one of our tests, trying to pass it to the pixel shader, which fails on Windows.
05208      */
05209     normal_funcs[WINED3D_FFP_EMIT_FLOAT1]         = invalid_func;
05210     normal_funcs[WINED3D_FFP_EMIT_FLOAT2]         = invalid_func;
05211     normal_funcs[WINED3D_FFP_EMIT_FLOAT3]         = (glAttribFunc)glNormal3fv;
05212     normal_funcs[WINED3D_FFP_EMIT_FLOAT4]         = (glAttribFunc)glNormal3fv; /* Just ignore the 4th value */
05213     normal_funcs[WINED3D_FFP_EMIT_D3DCOLOR]       = invalid_func;
05214     normal_funcs[WINED3D_FFP_EMIT_UBYTE4]         = invalid_func;
05215     normal_funcs[WINED3D_FFP_EMIT_SHORT2]         = invalid_func;
05216     normal_funcs[WINED3D_FFP_EMIT_SHORT4]         = invalid_func;
05217     normal_funcs[WINED3D_FFP_EMIT_UBYTE4N]        = invalid_func;
05218     normal_funcs[WINED3D_FFP_EMIT_SHORT2N]        = invalid_func;
05219     normal_funcs[WINED3D_FFP_EMIT_SHORT4N]        = invalid_func;
05220     normal_funcs[WINED3D_FFP_EMIT_USHORT2N]       = invalid_func;
05221     normal_funcs[WINED3D_FFP_EMIT_USHORT4N]       = invalid_func;
05222     normal_funcs[WINED3D_FFP_EMIT_UDEC3]          = invalid_func;
05223     normal_funcs[WINED3D_FFP_EMIT_DEC3N]          = invalid_func;
05224     normal_funcs[WINED3D_FFP_EMIT_FLOAT16_2]      = invalid_func;
05225     normal_funcs[WINED3D_FFP_EMIT_FLOAT16_4]      = invalid_func;
05226 
05227     multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT1]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord1fvARB);
05228     multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT2]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2fvARB);
05229     multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT3]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord3fvARB);
05230     multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT4]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4fvARB);
05231     multi_texcoord_funcs[WINED3D_FFP_EMIT_D3DCOLOR]  = invalid_texcoord_func;
05232     multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4]    = invalid_texcoord_func;
05233     multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2svARB);
05234     multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4]    = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4svARB);
05235     multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4N]   = invalid_texcoord_func;
05236     multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2N]   = invalid_texcoord_func;
05237     multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4N]   = invalid_texcoord_func;
05238     multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT2N]  = invalid_texcoord_func;
05239     multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT4N]  = invalid_texcoord_func;
05240     multi_texcoord_funcs[WINED3D_FFP_EMIT_UDEC3]     = invalid_texcoord_func;
05241     multi_texcoord_funcs[WINED3D_FFP_EMIT_DEC3N]     = invalid_texcoord_func;
05242     if (gl_info->supported[NV_HALF_FLOAT])
05243     {
05244         /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT */
05245         multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2hvNV);
05246         multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4hvNV);
05247     } else {
05248         multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_texcoord_func;
05249         multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_texcoord_func;
05250     }
05251 }
05252 
05253 /* Do not call while under the GL lock. */
05254 static BOOL InitAdapters(struct wined3d *wined3d)
05255 {
05256     static HMODULE mod_gl;
05257     BOOL ret;
05258     int ps_selected_mode, vs_selected_mode;
05259 
05260     /* No need to hold any lock. The calling library makes sure only one thread calls
05261      * wined3d simultaneously
05262      */
05263 
05264     TRACE("Initializing adapters\n");
05265 
05266     if(!mod_gl) {
05267 #ifdef USE_WIN32_OPENGL
05268 #define USE_GL_FUNC(pfn) pfn = (void*)GetProcAddress(mod_gl, #pfn);
05269         mod_gl = LoadLibraryA("opengl32.dll");
05270         if(!mod_gl) {
05271             ERR("Can't load opengl32.dll!\n");
05272             goto nogl_adapter;
05273         }
05274 #else
05275 #define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
05276         /* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
05277         mod_gl = GetModuleHandleA("gdi32.dll");
05278 #endif
05279     }
05280 
05281 /* Load WGL core functions from opengl32.dll */
05282 #define USE_WGL_FUNC(pfn) p##pfn = (void*)GetProcAddress(mod_gl, #pfn);
05283     WGL_FUNCS_GEN;
05284 #undef USE_WGL_FUNC
05285 
05286     if(!pwglGetProcAddress) {
05287         ERR("Unable to load wglGetProcAddress!\n");
05288         goto nogl_adapter;
05289     }
05290 
05291 /* Dynamically load all GL core functions */
05292     GL_FUNCS_GEN;
05293 #undef USE_GL_FUNC
05294 
05295     /* Load glFinish and glFlush from opengl32.dll even if we're not using WIN32 opengl
05296      * otherwise because we have to use winex11.drv's override
05297      */
05298 #ifdef USE_WIN32_OPENGL
05299     wglFinish = (void*)GetProcAddress(mod_gl, "glFinish");
05300     wglFlush = (void*)GetProcAddress(mod_gl, "glFlush");
05301 #else
05302     wglFinish = (void*)pwglGetProcAddress("wglFinish");
05303     wglFlush = (void*)pwglGetProcAddress("wglFlush");
05304 #endif
05305 
05306     glEnableWINE = glEnable;
05307     glDisableWINE = glDisable;
05308 
05309     /* For now only one default adapter */
05310     {
05311         struct wined3d_adapter *adapter = &wined3d->adapters[0];
05312         const struct wined3d_gl_info *gl_info = &adapter->gl_info;
05313         struct wined3d_fake_gl_ctx fake_gl_ctx = {0};
05314         struct wined3d_pixel_format *cfgs;
05315         int iPixelFormat;
05316         int res;
05317         DISPLAY_DEVICEW DisplayDevice;
05318         HDC hdc;
05319 
05320         TRACE("Initializing default adapter\n");
05321         adapter->ordinal = 0;
05322         adapter->monitorPoint.x = -1;
05323         adapter->monitorPoint.y = -1;
05324 
05325         if (!AllocateLocallyUniqueId(&adapter->luid))
05326         {
05327             DWORD err = GetLastError();
05328             ERR("Failed to set adapter LUID (%#x).\n", err);
05329             goto nogl_adapter;
05330         }
05331         TRACE("Allocated LUID %08x:%08x for adapter.\n",
05332                 adapter->luid.HighPart, adapter->luid.LowPart);
05333 
05334         if (!WineD3D_CreateFakeGLContext(&fake_gl_ctx))
05335         {
05336             ERR("Failed to get a gl context for default adapter\n");
05337             goto nogl_adapter;
05338         }
05339 
05340         ret = wined3d_adapter_init_gl_caps(adapter);
05341         if(!ret) {
05342             ERR("Failed to initialize gl caps for default adapter\n");
05343             WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
05344             goto nogl_adapter;
05345         }
05346         ret = initPixelFormats(&adapter->gl_info, adapter->driver_info.vendor);
05347         if(!ret) {
05348             ERR("Failed to init gl formats\n");
05349             WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
05350             goto nogl_adapter;
05351         }
05352 
05353         hdc = fake_gl_ctx.dc;
05354 
05355         adapter->TextureRam = adapter->driver_info.vidmem;
05356         adapter->UsedTextureRam = 0;
05357         TRACE("Emulating %dMB of texture ram\n", adapter->TextureRam/(1024*1024));
05358 
05359         /* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
05360         DisplayDevice.cb = sizeof(DisplayDevice);
05361         EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0);
05362         TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName));
05363         strcpyW(adapter->DeviceName, DisplayDevice.DeviceName);
05364 
05365         if (gl_info->supported[WGL_ARB_PIXEL_FORMAT])
05366         {
05367             GLint cfg_count;
05368             int attribute;
05369             int attribs[11];
05370             int values[11];
05371             int nAttribs = 0;
05372 
05373             attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
05374             GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &cfg_count));
05375             adapter->cfg_count = cfg_count;
05376 
05377             adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, adapter->cfg_count * sizeof(*adapter->cfgs));
05378             cfgs = adapter->cfgs;
05379             attribs[nAttribs++] = WGL_RED_BITS_ARB;
05380             attribs[nAttribs++] = WGL_GREEN_BITS_ARB;
05381             attribs[nAttribs++] = WGL_BLUE_BITS_ARB;
05382             attribs[nAttribs++] = WGL_ALPHA_BITS_ARB;
05383             attribs[nAttribs++] = WGL_COLOR_BITS_ARB;
05384             attribs[nAttribs++] = WGL_DEPTH_BITS_ARB;
05385             attribs[nAttribs++] = WGL_STENCIL_BITS_ARB;
05386             attribs[nAttribs++] = WGL_DRAW_TO_WINDOW_ARB;
05387             attribs[nAttribs++] = WGL_PIXEL_TYPE_ARB;
05388             attribs[nAttribs++] = WGL_DOUBLE_BUFFER_ARB;
05389             attribs[nAttribs++] = WGL_AUX_BUFFERS_ARB;
05390 
05391             for (iPixelFormat=1; iPixelFormat <= adapter->cfg_count; ++iPixelFormat)
05392             {
05393                 res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
05394 
05395                 if(!res)
05396                     continue;
05397 
05398                 /* Cache the pixel format */
05399                 cfgs->iPixelFormat = iPixelFormat;
05400                 cfgs->redSize = values[0];
05401                 cfgs->greenSize = values[1];
05402                 cfgs->blueSize = values[2];
05403                 cfgs->alphaSize = values[3];
05404                 cfgs->colorSize = values[4];
05405                 cfgs->depthSize = values[5];
05406                 cfgs->stencilSize = values[6];
05407                 cfgs->windowDrawable = values[7];
05408                 cfgs->iPixelType = values[8];
05409                 cfgs->doubleBuffer = values[9];
05410                 cfgs->auxBuffers = values[10];
05411 
05412                 cfgs->numSamples = 0;
05413                 /* Check multisample support */
05414                 if (gl_info->supported[ARB_MULTISAMPLE])
05415                 {
05416                     int attrib[2] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
05417                     int value[2];
05418                     if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 2, attrib, value))) {
05419                         /* value[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether multisampling is supported.
05420                         * value[1] = number of multi sample buffers*/
05421                         if(value[0])
05422                             cfgs->numSamples = value[1];
05423                     }
05424                 }
05425 
05426                 TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
05427                         "depth=%d, stencil=%d, samples=%d, windowDrawable=%d\n",
05428                         cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer,
05429                         cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize,
05430                         cfgs->depthSize, cfgs->stencilSize, cfgs->numSamples, cfgs->windowDrawable);
05431                 cfgs++;
05432             }
05433         }
05434         else
05435         {
05436             int nCfgs = DescribePixelFormat(hdc, 0, 0, 0);
05437             adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nCfgs * sizeof(*adapter->cfgs));
05438             adapter->cfg_count = 0; /* We won't accept all formats e.g. software accelerated ones will be skipped */
05439 
05440             cfgs = adapter->cfgs;
05441             for(iPixelFormat=1; iPixelFormat<=nCfgs; iPixelFormat++)
05442             {
05443                 PIXELFORMATDESCRIPTOR ppfd;
05444 
05445                 res = DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &ppfd);
05446                 if(!res)
05447                     continue;
05448 
05449                 /* We only want HW acceleration using an OpenGL ICD driver.
05450                  * PFD_GENERIC_FORMAT = slow opengl 1.1 gdi software rendering
05451                  * PFD_GENERIC_ACCELERATED = partial hw acceleration using a MCD driver (e.g. 3dfx minigl)
05452                  */
05453                 if(ppfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED))
05454                 {
05455                     TRACE("Skipping iPixelFormat=%d because it isn't ICD accelerated\n", iPixelFormat);
05456                     continue;
05457                 }
05458 
05459                 cfgs->iPixelFormat = iPixelFormat;
05460                 cfgs->redSize = ppfd.cRedBits;
05461                 cfgs->greenSize = ppfd.cGreenBits;
05462                 cfgs->blueSize = ppfd.cBlueBits;
05463                 cfgs->alphaSize = ppfd.cAlphaBits;
05464                 cfgs->colorSize = ppfd.cColorBits;
05465                 cfgs->depthSize = ppfd.cDepthBits;
05466                 cfgs->stencilSize = ppfd.cStencilBits;
05467                 cfgs->windowDrawable = (ppfd.dwFlags & PFD_DRAW_TO_WINDOW) ? 1 : 0;
05468                 cfgs->iPixelType = (ppfd.iPixelType == PFD_TYPE_RGBA) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB;
05469                 cfgs->doubleBuffer = (ppfd.dwFlags & PFD_DOUBLEBUFFER) ? 1 : 0;
05470                 cfgs->auxBuffers = ppfd.cAuxBuffers;
05471                 cfgs->numSamples = 0;
05472 
05473                 TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
05474                         "depth=%d, stencil=%d, windowDrawable=%d\n",
05475                         cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer,
05476                         cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize,
05477                         cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable);
05478                 cfgs++;
05479                 adapter->cfg_count++;
05480             }
05481 
05482             /* We haven't found any suitable formats. This should only happen
05483              * in case of GDI software rendering, which is pretty useless
05484              * anyway. */
05485             if (!adapter->cfg_count)
05486             {
05487                 ERR("Disabling Direct3D because no hardware accelerated pixel formats have been found!\n");
05488 
05489                 WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
05490                 HeapFree(GetProcessHeap(), 0, adapter->cfgs);
05491                 goto nogl_adapter;
05492             }
05493         }
05494 
05495         WineD3D_ReleaseFakeGLContext(&fake_gl_ctx);
05496 
05497         select_shader_mode(&adapter->gl_info, &ps_selected_mode, &vs_selected_mode);
05498         fillGLAttribFuncs(&adapter->gl_info);
05499         adapter->opengl = TRUE;
05500     }
05501     wined3d->adapter_count = 1;
05502     TRACE("%u adapters successfully initialized.\n", wined3d->adapter_count);
05503 
05504     return TRUE;
05505 
05506 nogl_adapter:
05507     /* Initialize an adapter for ddraw-only memory counting */
05508     memset(wined3d->adapters, 0, sizeof(wined3d->adapters));
05509     wined3d->adapters[0].ordinal = 0;
05510     wined3d->adapters[0].opengl = FALSE;
05511     wined3d->adapters[0].monitorPoint.x = -1;
05512     wined3d->adapters[0].monitorPoint.y = -1;
05513 
05514     wined3d->adapters[0].driver_info.name = "Display";
05515     wined3d->adapters[0].driver_info.description = "WineD3D DirectDraw Emulation";
05516     if (wined3d_settings.emulated_textureram)
05517         wined3d->adapters[0].TextureRam = wined3d_settings.emulated_textureram;
05518     else
05519         wined3d->adapters[0].TextureRam = 8 * 1024 * 1024; /* This is plenty for a DDraw-only card */
05520 
05521     initPixelFormatsNoGL(&wined3d->adapters[0].gl_info);
05522 
05523     wined3d->adapter_count = 1;
05524     return FALSE;
05525 }
05526 
05527 static void STDMETHODCALLTYPE wined3d_null_wined3d_object_destroyed(void *parent) {}
05528 
05529 const struct wined3d_parent_ops wined3d_null_parent_ops =
05530 {
05531     wined3d_null_wined3d_object_destroyed,
05532 };
05533 
05534 /* Do not call while under the GL lock. */
05535 HRESULT wined3d_init(struct wined3d *wined3d, UINT version, DWORD flags, void *parent)
05536 {
05537     wined3d->dxVersion = version;
05538     wined3d->ref = 1;
05539     wined3d->parent = parent;
05540     wined3d->flags = flags;
05541 
05542     if (!InitAdapters(wined3d))
05543     {
05544         WARN("Failed to initialize adapters.\n");
05545         if (version > 7)
05546         {
05547             MESSAGE("Direct3D%u is not available without OpenGL.\n", version);
05548             return E_FAIL;
05549         }
05550     }
05551 
05552     return WINED3D_OK;
05553 }

Generated on Fri May 25 2012 04:19:53 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.