directx.c 328 KB
Newer Older
1 2 3 4
/*
 * Copyright 2002-2004 Jason Edmeades
 * Copyright 2003-2004 Raphael Junqueira
 * Copyright 2004 Christian Costa
Oliver Stieber's avatar
Oliver Stieber committed
5
 * Copyright 2005 Oliver Stieber
6
 * Copyright 2007-2008 Stefan Dösinger for CodeWeavers
7
 * Copyright 2009-2011 Henri Verbeet for CodeWeavers
8 9 10 11 12 13 14 15 16 17 18 19 20
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 23 24
 */

#include "config.h"
25 26
#include "wine/port.h"

27
#include <stdio.h>
28

29
#include "wined3d_private.h"
30
#include "winternl.h"
31 32

WINE_DEFAULT_DEBUG_CHANNEL(d3d);
33
WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
34
WINE_DECLARE_DEBUG_CHANNEL(winediag);
35

36
#define DEFAULT_REFRESH_RATE 0
37

38 39 40 41 42 43 44 45 46
/* The driver names reflect the lowest GPU supported
 * by a certain driver, so DRIVER_AMD_R300 supports
 * R3xx, R4xx and R5xx GPUs. */
enum wined3d_display_driver
{
    DRIVER_AMD_RAGE_128PRO,
    DRIVER_AMD_R100,
    DRIVER_AMD_R300,
    DRIVER_AMD_R600,
47
    DRIVER_AMD_RX,
48 49 50 51
    DRIVER_INTEL_GMA800,
    DRIVER_INTEL_GMA900,
    DRIVER_INTEL_GMA950,
    DRIVER_INTEL_GMA3000,
52
    DRIVER_INTEL_HD4000,
53 54 55 56
    DRIVER_NVIDIA_TNT,
    DRIVER_NVIDIA_GEFORCE2MX,
    DRIVER_NVIDIA_GEFORCEFX,
    DRIVER_NVIDIA_GEFORCE6,
57
    DRIVER_NVIDIA_GEFORCE8,
58
    DRIVER_VMWARE,
59 60 61 62 63
    DRIVER_UNKNOWN
};

enum wined3d_driver_model
{
64
    DRIVER_MODEL_GENERIC,
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
    DRIVER_MODEL_WIN9X,
    DRIVER_MODEL_NT40,
    DRIVER_MODEL_NT5X,
    DRIVER_MODEL_NT6X
};

enum wined3d_gl_vendor
{
    GL_VENDOR_UNKNOWN,
    GL_VENDOR_APPLE,
    GL_VENDOR_FGLRX,
    GL_VENDOR_MESA,
    GL_VENDOR_NVIDIA,
};

80 81 82 83 84 85
enum wined3d_d3d_level
{
    WINED3D_D3D_LEVEL_5,
    WINED3D_D3D_LEVEL_6,
    WINED3D_D3D_LEVEL_7,
    WINED3D_D3D_LEVEL_8,
86 87
    WINED3D_D3D_LEVEL_9_SM2,
    WINED3D_D3D_LEVEL_9_SM3,
88
    WINED3D_D3D_LEVEL_10,
89
    WINED3D_D3D_LEVEL_11,
90
    WINED3D_D3D_LEVEL_COUNT
91 92
};

93 94 95
/* The d3d device ID */
static const GUID IID_D3DDEVICE_D3DUID = { 0xaeb2cdd4, 0x6e41, 0x43ea, { 0x94,0x1c,0x83,0x61,0xcc,0x76,0x07,0x81 } };

96
/* Extension detection */
97
struct wined3d_extension_map
98
{
99
    const char *extension_string;
100
    enum wined3d_gl_extension extension;
101 102
};

103
static const struct wined3d_extension_map gl_extension_map[] =
104
{
105
    /* APPLE */
106 107 108 109
    {"GL_APPLE_fence",                      APPLE_FENCE                   },
    {"GL_APPLE_float_pixels",               APPLE_FLOAT_PIXELS            },
    {"GL_APPLE_flush_buffer_range",         APPLE_FLUSH_BUFFER_RANGE      },
    {"GL_APPLE_ycbcr_422",                  APPLE_YCBCR_422               },
110 111

    /* ARB */
112
    {"GL_ARB_base_instance",                ARB_BASE_INSTANCE             },
113
    {"GL_ARB_blend_func_extended",          ARB_BLEND_FUNC_EXTENDED       },
114
    {"GL_ARB_clear_buffer_object",          ARB_CLEAR_BUFFER_OBJECT       },
115
    {"GL_ARB_clear_texture",                ARB_CLEAR_TEXTURE             },
116
    {"GL_ARB_clip_control",                 ARB_CLIP_CONTROL              },
117
    {"GL_ARB_color_buffer_float",           ARB_COLOR_BUFFER_FLOAT        },
118
    {"GL_ARB_compute_shader",               ARB_COMPUTE_SHADER            },
119
    {"GL_ARB_conservative_depth",           ARB_CONSERVATIVE_DEPTH        },
120
    {"GL_ARB_copy_buffer",                  ARB_COPY_BUFFER               },
121
    {"GL_ARB_copy_image",                   ARB_COPY_IMAGE                },
122
    {"GL_ARB_cull_distance",                ARB_CULL_DISTANCE             },
123
    {"GL_ARB_debug_output",                 ARB_DEBUG_OUTPUT              },
124 125
    {"GL_ARB_depth_buffer_float",           ARB_DEPTH_BUFFER_FLOAT        },
    {"GL_ARB_depth_texture",                ARB_DEPTH_TEXTURE             },
126
    {"GL_ARB_derivative_control",           ARB_DERIVATIVE_CONTROL        },
127 128
    {"GL_ARB_draw_buffers",                 ARB_DRAW_BUFFERS              },
    {"GL_ARB_draw_elements_base_vertex",    ARB_DRAW_ELEMENTS_BASE_VERTEX },
129
    {"GL_ARB_draw_indirect",                ARB_DRAW_INDIRECT             },
130
    {"GL_ARB_draw_instanced",               ARB_DRAW_INSTANCED            },
131
    {"GL_ARB_ES2_compatibility",            ARB_ES2_COMPATIBILITY         },
132
    {"GL_ARB_ES3_compatibility",            ARB_ES3_COMPATIBILITY         },
133
    {"GL_ARB_explicit_attrib_location",     ARB_EXPLICIT_ATTRIB_LOCATION  },
134
    {"GL_ARB_fragment_coord_conventions",   ARB_FRAGMENT_COORD_CONVENTIONS},
135
    {"GL_ARB_fragment_layer_viewport",      ARB_FRAGMENT_LAYER_VIEWPORT   },
136 137
    {"GL_ARB_fragment_program",             ARB_FRAGMENT_PROGRAM          },
    {"GL_ARB_fragment_shader",              ARB_FRAGMENT_SHADER           },
138
    {"GL_ARB_framebuffer_no_attachments",   ARB_FRAMEBUFFER_NO_ATTACHMENTS},
139
    {"GL_ARB_framebuffer_object",           ARB_FRAMEBUFFER_OBJECT        },
140
    {"GL_ARB_framebuffer_sRGB",             ARB_FRAMEBUFFER_SRGB          },
141
    {"GL_ARB_geometry_shader4",             ARB_GEOMETRY_SHADER4          },
142
    {"GL_ARB_gpu_shader5",                  ARB_GPU_SHADER5               },
143 144
    {"GL_ARB_half_float_pixel",             ARB_HALF_FLOAT_PIXEL          },
    {"GL_ARB_half_float_vertex",            ARB_HALF_FLOAT_VERTEX         },
145 146 147
    {"GL_ARB_instanced_arrays",             ARB_INSTANCED_ARRAYS          },
    {"GL_ARB_internalformat_query",         ARB_INTERNALFORMAT_QUERY      },
    {"GL_ARB_internalformat_query2",        ARB_INTERNALFORMAT_QUERY2     },
148 149
    {"GL_ARB_map_buffer_alignment",         ARB_MAP_BUFFER_ALIGNMENT      },
    {"GL_ARB_map_buffer_range",             ARB_MAP_BUFFER_RANGE          },
150
    {"GL_ARB_multisample",                  ARB_MULTISAMPLE               },
151 152
    {"GL_ARB_multitexture",                 ARB_MULTITEXTURE              },
    {"GL_ARB_occlusion_query",              ARB_OCCLUSION_QUERY           },
153
    {"GL_ARB_pipeline_statistics_query",    ARB_PIPELINE_STATISTICS_QUERY },
154 155 156 157
    {"GL_ARB_pixel_buffer_object",          ARB_PIXEL_BUFFER_OBJECT       },
    {"GL_ARB_point_parameters",             ARB_POINT_PARAMETERS          },
    {"GL_ARB_point_sprite",                 ARB_POINT_SPRITE              },
    {"GL_ARB_provoking_vertex",             ARB_PROVOKING_VERTEX          },
158
    {"GL_ARB_sampler_objects",              ARB_SAMPLER_OBJECTS           },
159
    {"GL_ARB_seamless_cube_map",            ARB_SEAMLESS_CUBE_MAP         },
160
    {"GL_ARB_shader_atomic_counters",       ARB_SHADER_ATOMIC_COUNTERS    },
161
    {"GL_ARB_shader_bit_encoding",          ARB_SHADER_BIT_ENCODING       },
162
    {"GL_ARB_shader_image_load_store",      ARB_SHADER_IMAGE_LOAD_STORE   },
163
    {"GL_ARB_shader_image_size",            ARB_SHADER_IMAGE_SIZE         },
164
    {"GL_ARB_shader_storage_buffer_object", ARB_SHADER_STORAGE_BUFFER_OBJECT},
165 166
    {"GL_ARB_shader_texture_lod",           ARB_SHADER_TEXTURE_LOD        },
    {"GL_ARB_shading_language_100",         ARB_SHADING_LANGUAGE_100      },
167
    {"GL_ARB_shading_language_420pack",     ARB_SHADING_LANGUAGE_420PACK  },
168
    {"GL_ARB_shading_language_packing",     ARB_SHADING_LANGUAGE_PACKING  },
169
    {"GL_ARB_shadow",                       ARB_SHADOW                    },
170
    {"GL_ARB_stencil_texturing",            ARB_STENCIL_TEXTURING         },
171
    {"GL_ARB_sync",                         ARB_SYNC                      },
172
    {"GL_ARB_tessellation_shader",          ARB_TESSELLATION_SHADER       },
173
    {"GL_ARB_texture_border_clamp",         ARB_TEXTURE_BORDER_CLAMP      },
174
    {"GL_ARB_texture_buffer_object",        ARB_TEXTURE_BUFFER_OBJECT     },
175
    {"GL_ARB_texture_buffer_range",         ARB_TEXTURE_BUFFER_RANGE      },
176
    {"GL_ARB_texture_compression",          ARB_TEXTURE_COMPRESSION       },
177
    {"GL_ARB_texture_compression_bptc",     ARB_TEXTURE_COMPRESSION_BPTC  },
178 179
    {"GL_ARB_texture_compression_rgtc",     ARB_TEXTURE_COMPRESSION_RGTC  },
    {"GL_ARB_texture_cube_map",             ARB_TEXTURE_CUBE_MAP          },
180
    {"GL_ARB_texture_cube_map_array",       ARB_TEXTURE_CUBE_MAP_ARRAY    },
181 182
    {"GL_ARB_texture_env_combine",          ARB_TEXTURE_ENV_COMBINE       },
    {"GL_ARB_texture_env_dot3",             ARB_TEXTURE_ENV_DOT3          },
183
    {"GL_ARB_texture_filter_anisotropic",   ARB_TEXTURE_FILTER_ANISOTROPIC},
184
    {"GL_ARB_texture_float",                ARB_TEXTURE_FLOAT             },
185
    {"GL_ARB_texture_gather",               ARB_TEXTURE_GATHER            },
186
    {"GL_ARB_texture_mirrored_repeat",      ARB_TEXTURE_MIRRORED_REPEAT   },
187
    {"GL_ARB_texture_mirror_clamp_to_edge", ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE},
188
    {"GL_ARB_texture_multisample",          ARB_TEXTURE_MULTISAMPLE       },
189
    {"GL_ARB_texture_non_power_of_two",     ARB_TEXTURE_NON_POWER_OF_TWO  },
190
    {"GL_ARB_texture_query_levels",         ARB_TEXTURE_QUERY_LEVELS      },
191 192
    {"GL_ARB_texture_rectangle",            ARB_TEXTURE_RECTANGLE         },
    {"GL_ARB_texture_rg",                   ARB_TEXTURE_RG                },
193
    {"GL_ARB_texture_rgb10_a2ui",           ARB_TEXTURE_RGB10_A2UI        },
194
    {"GL_ARB_texture_storage",              ARB_TEXTURE_STORAGE           },
195
    {"GL_ARB_texture_storage_multisample",  ARB_TEXTURE_STORAGE_MULTISAMPLE},
196
    {"GL_ARB_texture_swizzle",              ARB_TEXTURE_SWIZZLE           },
197
    {"GL_ARB_texture_view",                 ARB_TEXTURE_VIEW              },
198
    {"GL_ARB_timer_query",                  ARB_TIMER_QUERY               },
199
    {"GL_ARB_transform_feedback2",          ARB_TRANSFORM_FEEDBACK2       },
200
    {"GL_ARB_transform_feedback3",          ARB_TRANSFORM_FEEDBACK3       },
201
    {"GL_ARB_uniform_buffer_object",        ARB_UNIFORM_BUFFER_OBJECT     },
202 203 204 205 206
    {"GL_ARB_vertex_array_bgra",            ARB_VERTEX_ARRAY_BGRA         },
    {"GL_ARB_vertex_blend",                 ARB_VERTEX_BLEND              },
    {"GL_ARB_vertex_buffer_object",         ARB_VERTEX_BUFFER_OBJECT      },
    {"GL_ARB_vertex_program",               ARB_VERTEX_PROGRAM            },
    {"GL_ARB_vertex_shader",                ARB_VERTEX_SHADER             },
207
    {"GL_ARB_vertex_type_2_10_10_10_rev",   ARB_VERTEX_TYPE_2_10_10_10_REV},
208
    {"GL_ARB_viewport_array",               ARB_VIEWPORT_ARRAY            },
209 210

    /* ATI */
211 212 213 214 215
    {"GL_ATI_fragment_shader",              ATI_FRAGMENT_SHADER           },
    {"GL_ATI_separate_stencil",             ATI_SEPARATE_STENCIL          },
    {"GL_ATI_texture_compression_3dc",      ATI_TEXTURE_COMPRESSION_3DC   },
    {"GL_ATI_texture_env_combine3",         ATI_TEXTURE_ENV_COMBINE3      },
    {"GL_ATI_texture_mirror_once",          ATI_TEXTURE_MIRROR_ONCE       },
216 217

    /* EXT */
218 219 220 221 222 223 224 225 226 227 228 229 230 231
    {"GL_EXT_blend_color",                  EXT_BLEND_COLOR               },
    {"GL_EXT_blend_equation_separate",      EXT_BLEND_EQUATION_SEPARATE   },
    {"GL_EXT_blend_func_separate",          EXT_BLEND_FUNC_SEPARATE       },
    {"GL_EXT_blend_minmax",                 EXT_BLEND_MINMAX              },
    {"GL_EXT_blend_subtract",               EXT_BLEND_SUBTRACT            },
    {"GL_EXT_depth_bounds_test",            EXT_DEPTH_BOUNDS_TEST         },
    {"GL_EXT_draw_buffers2",                EXT_DRAW_BUFFERS2             },
    {"GL_EXT_fog_coord",                    EXT_FOG_COORD                 },
    {"GL_EXT_framebuffer_blit",             EXT_FRAMEBUFFER_BLIT          },
    {"GL_EXT_framebuffer_multisample",      EXT_FRAMEBUFFER_MULTISAMPLE   },
    {"GL_EXT_framebuffer_object",           EXT_FRAMEBUFFER_OBJECT        },
    {"GL_EXT_gpu_program_parameters",       EXT_GPU_PROGRAM_PARAMETERS    },
    {"GL_EXT_gpu_shader4",                  EXT_GPU_SHADER4               },
    {"GL_EXT_packed_depth_stencil",         EXT_PACKED_DEPTH_STENCIL      },
232
    {"GL_EXT_packed_float",                 EXT_PACKED_FLOAT              },
233 234 235 236 237 238
    {"GL_EXT_point_parameters",             EXT_POINT_PARAMETERS          },
    {"GL_EXT_provoking_vertex",             EXT_PROVOKING_VERTEX          },
    {"GL_EXT_secondary_color",              EXT_SECONDARY_COLOR           },
    {"GL_EXT_stencil_two_side",             EXT_STENCIL_TWO_SIDE          },
    {"GL_EXT_stencil_wrap",                 EXT_STENCIL_WRAP              },
    {"GL_EXT_texture3D",                    EXT_TEXTURE3D                 },
239
    {"GL_EXT_texture_array",                EXT_TEXTURE_ARRAY             },
240 241 242 243
    {"GL_EXT_texture_compression_rgtc",     EXT_TEXTURE_COMPRESSION_RGTC  },
    {"GL_EXT_texture_compression_s3tc",     EXT_TEXTURE_COMPRESSION_S3TC  },
    {"GL_EXT_texture_env_combine",          EXT_TEXTURE_ENV_COMBINE       },
    {"GL_EXT_texture_env_dot3",             EXT_TEXTURE_ENV_DOT3          },
244
    {"GL_EXT_texture_filter_anisotropic",   ARB_TEXTURE_FILTER_ANISOTROPIC},
245
    {"GL_EXT_texture_integer",              EXT_TEXTURE_INTEGER           },
246
    {"GL_EXT_texture_lod_bias",             EXT_TEXTURE_LOD_BIAS          },
247
    {"GL_EXT_texture_mirror_clamp",         EXT_TEXTURE_MIRROR_CLAMP      },
248
    {"GL_EXT_texture_shared_exponent",      EXT_TEXTURE_SHARED_EXPONENT   },
249
    {"GL_EXT_texture_snorm",                EXT_TEXTURE_SNORM             },
250 251 252
    {"GL_EXT_texture_sRGB",                 EXT_TEXTURE_SRGB              },
    {"GL_EXT_texture_sRGB_decode",          EXT_TEXTURE_SRGB_DECODE       },
    {"GL_EXT_vertex_array_bgra",            EXT_VERTEX_ARRAY_BGRA         },
253 254

    /* NV */
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
    {"GL_NV_fence",                         NV_FENCE                      },
    {"GL_NV_fog_distance",                  NV_FOG_DISTANCE               },
    {"GL_NV_fragment_program",              NV_FRAGMENT_PROGRAM           },
    {"GL_NV_fragment_program2",             NV_FRAGMENT_PROGRAM2          },
    {"GL_NV_fragment_program_option",       NV_FRAGMENT_PROGRAM_OPTION    },
    {"GL_NV_half_float",                    NV_HALF_FLOAT                 },
    {"GL_NV_light_max_exponent",            NV_LIGHT_MAX_EXPONENT         },
    {"GL_NV_point_sprite",                  NV_POINT_SPRITE               },
    {"GL_NV_register_combiners",            NV_REGISTER_COMBINERS         },
    {"GL_NV_register_combiners2",           NV_REGISTER_COMBINERS2        },
    {"GL_NV_texgen_reflection",             NV_TEXGEN_REFLECTION          },
    {"GL_NV_texture_env_combine4",          NV_TEXTURE_ENV_COMBINE4       },
    {"GL_NV_texture_shader",                NV_TEXTURE_SHADER             },
    {"GL_NV_texture_shader2",               NV_TEXTURE_SHADER2            },
    {"GL_NV_vertex_program",                NV_VERTEX_PROGRAM             },
    {"GL_NV_vertex_program1_1",             NV_VERTEX_PROGRAM1_1          },
    {"GL_NV_vertex_program2",               NV_VERTEX_PROGRAM2            },
    {"GL_NV_vertex_program2_option",        NV_VERTEX_PROGRAM2_OPTION     },
    {"GL_NV_vertex_program3",               NV_VERTEX_PROGRAM3            },
274 275
};

276 277
static const struct wined3d_extension_map wgl_extension_map[] =
{
278 279 280
    {"WGL_ARB_pixel_format",                WGL_ARB_PIXEL_FORMAT             },
    {"WGL_EXT_swap_control",                WGL_EXT_SWAP_CONTROL             },
    {"WGL_WINE_pixel_format_passthrough",   WGL_WINE_PIXEL_FORMAT_PASSTHROUGH},
281
    {"WGL_WINE_query_renderer",             WGL_WINE_QUERY_RENDERER          },
282 283
};

284 285 286 287
/**********************************************************
 * Utility functions follow
 **********************************************************/

288
const struct min_lookup minMipLookup[] =
289
{
290
    /* NONE         POINT                       LINEAR */
291
    {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* NONE */
292 293
    {{GL_NEAREST,   GL_NEAREST_MIPMAP_NEAREST,  GL_NEAREST_MIPMAP_LINEAR}}, /* POINT*/
    {{GL_LINEAR,    GL_LINEAR_MIPMAP_NEAREST,   GL_LINEAR_MIPMAP_LINEAR}},  /* LINEAR */
294
};
295

296 297
const GLenum magLookup[] =
{
298 299
    /* NONE     POINT       LINEAR */
    GL_NEAREST, GL_NEAREST, GL_LINEAR,
300 301
};

302
static void wined3d_caps_gl_ctx_destroy(const struct wined3d_caps_gl_ctx *ctx)
303
{
304 305
    const struct wined3d_gl_info *gl_info = ctx->gl_info;

306
    TRACE("Destroying caps GL context.\n");
307

308 309 310 311 312 313 314 315 316
    /* Both glDeleteProgram and glDeleteBuffers silently ignore 0 IDs but
     * this function might be called before the relevant function pointers
     * in gl_info are initialized. */
    if (ctx->test_program_id || ctx->test_vbo)
    {
        GL_EXTCALL(glDeleteProgram(ctx->test_program_id));
        GL_EXTCALL(glDeleteBuffers(1, &ctx->test_vbo));
    }

317
    if (!wglMakeCurrent(NULL, NULL))
318
        ERR("Failed to disable caps GL context.\n");
319

320
    if (!wglDeleteContext(ctx->gl_ctx))
321 322 323 324 325
    {
        DWORD err = GetLastError();
        ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx->gl_ctx, err);
    }

326
    wined3d_release_dc(ctx->wnd, ctx->dc);
327
    DestroyWindow(ctx->wnd);
328

329
    if (ctx->restore_gl_ctx && !wglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx))
330
        ERR("Failed to restore previous GL context.\n");
331 332
}

333 334
static BOOL wined3d_caps_gl_ctx_create_attribs(struct wined3d_caps_gl_ctx *caps_gl_ctx,
        struct wined3d_gl_info *gl_info)
335 336 337 338
{
    HGLRC new_ctx;

    if (!(gl_info->p_wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB")))
339
        return TRUE;
340

341
    if (!(new_ctx = context_create_wgl_attribs(gl_info, caps_gl_ctx->dc, NULL)))
342 343
    {
        gl_info->p_wglCreateContextAttribsARB = NULL;
344
        return FALSE;
345 346
    }

347
    if (!wglMakeCurrent(caps_gl_ctx->dc, new_ctx))
348 349 350 351 352
    {
        ERR("Failed to make new context current, last error %#x.\n", GetLastError());
        if (!wglDeleteContext(new_ctx))
            ERR("Failed to delete new context, last error %#x.\n", GetLastError());
        gl_info->p_wglCreateContextAttribsARB = NULL;
353
        return TRUE;
354 355
    }

356
    if (!wglDeleteContext(caps_gl_ctx->gl_ctx))
357
        ERR("Failed to delete old context, last error %#x.\n", GetLastError());
358
    caps_gl_ctx->gl_ctx = new_ctx;
359 360

    return TRUE;
361 362
}

363
static BOOL wined3d_caps_gl_ctx_create(struct wined3d_adapter *adapter, struct wined3d_caps_gl_ctx *ctx)
364
{
365 366
    PIXELFORMATDESCRIPTOR pfd;
    int iPixelFormat;
367

368
    TRACE("getting context...\n");
369

370 371
    ctx->restore_dc = wglGetCurrentDC();
    ctx->restore_gl_ctx = wglGetCurrentContext();
372

373
    /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes. */
374
    ctx->wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window",
375
            WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL);
376
    if (!ctx->wnd)
377
    {
378
        ERR("Failed to create a window.\n");
379 380
        goto fail;
    }
381

382 383
    ctx->dc = GetDC(ctx->wnd);
    if (!ctx->dc)
384
    {
385
        ERR("Failed to get a DC.\n");
386 387
        goto fail;
    }
388

389 390 391 392 393 394 395 396 397
    /* PixelFormat selection */
    ZeroMemory(&pfd, sizeof(pfd));
    pfd.nSize = sizeof(pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW; /* PFD_GENERIC_ACCELERATED */
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 32;
    pfd.iLayerType = PFD_MAIN_PLANE;

398
    if (!(iPixelFormat = ChoosePixelFormat(ctx->dc, &pfd)))
399 400
    {
        /* If this happens something is very wrong as ChoosePixelFormat barely fails. */
401
        ERR("Failed to find a suitable pixel format.\n");
402 403
        goto fail;
    }
404 405
    DescribePixelFormat(ctx->dc, iPixelFormat, sizeof(pfd), &pfd);
    SetPixelFormat(ctx->dc, iPixelFormat, &pfd);
406 407

    /* Create a GL context. */
408
    if (!(ctx->gl_ctx = wglCreateContext(ctx->dc)))
409
    {
410
        WARN("Failed to create default context for capabilities initialization.\n");
411 412
        goto fail;
    }
413

414
    /* Make it the current GL context. */
415
    if (!wglMakeCurrent(ctx->dc, ctx->gl_ctx))
416
    {
417
        ERR("Failed to make caps GL context current.\n");
418
        goto fail;
419
    }
420

421
    ctx->gl_info = &adapter->gl_info;
422
    return TRUE;
423 424

fail:
425
    if (ctx->gl_ctx) wglDeleteContext(ctx->gl_ctx);
426 427 428 429 430
    ctx->gl_ctx = NULL;
    if (ctx->dc) ReleaseDC(ctx->wnd, ctx->dc);
    ctx->dc = NULL;
    if (ctx->wnd) DestroyWindow(ctx->wnd);
    ctx->wnd = NULL;
431
    if (ctx->restore_gl_ctx && !wglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx))
432
        ERR("Failed to restore previous GL context.\n");
433

434
    return FALSE;
435 436
}

437
/* Adjust the amount of used texture memory */
438
UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount)
439
{
440 441 442 443 444
    adapter->vram_bytes_used += amount;
    TRACE("Adjusted used adapter memory by 0x%s to 0x%s.\n",
            wine_dbgstr_longlong(amount),
            wine_dbgstr_longlong(adapter->vram_bytes_used));
    return adapter->vram_bytes_used;
445
}
446

447 448
static void wined3d_adapter_cleanup(struct wined3d_adapter *adapter)
{
449 450
    heap_free(adapter->gl_info.formats);
    heap_free(adapter->cfgs);
451 452
}

453
ULONG CDECL wined3d_incref(struct wined3d *wined3d)
454
{
455
    ULONG refcount = InterlockedIncrement(&wined3d->ref);
456

457
    TRACE("%p increasing refcount to %u.\n", wined3d, refcount);
458

459
    return refcount;
460 461
}

462 463 464 465 466
ULONG CDECL wined3d_decref(struct wined3d *wined3d)
{
    ULONG refcount = InterlockedDecrement(&wined3d->ref);

    TRACE("%p decreasing refcount to %u.\n", wined3d, refcount);
467

468
    if (!refcount)
469
    {
470 471
        unsigned int i;

472
        for (i = 0; i < wined3d->adapter_count; ++i)
473
        {
474
            wined3d_adapter_cleanup(&wined3d->adapters[i]);
475
        }
476
        heap_free(wined3d);
477
    }
478

479
    return refcount;
480 481
}

482 483
/* Context activation is done by the caller. */
static BOOL test_arb_vs_offset_limit(const struct wined3d_gl_info *gl_info)
484
{
485 486
    GLuint prog;
    BOOL ret = FALSE;
487
    static const char testcode[] =
488 489 490
        "!!ARBvp1.0\n"
        "PARAM C[66] = { program.env[0..65] };\n"
        "ADDRESS A0;"
491 492
        "PARAM zero = {0.0, 0.0, 0.0, 0.0};\n"
        "ARL A0.x, zero.x;\n"
493 494 495
        "MOV result.position, C[A0.x + 65];\n"
        "END\n";

496
    while (gl_info->gl_ops.gl.p_glGetError());
497 498 499 500 501 502 503
    GL_EXTCALL(glGenProgramsARB(1, &prog));
    if(!prog) {
        ERR("Failed to create an ARB offset limit test program\n");
    }
    GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
    GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
                                  strlen(testcode), testcode));
504
    if (gl_info->gl_ops.gl.p_glGetError())
505
    {
506
        TRACE("OpenGL implementation does not allow indirect addressing offsets > 63\n");
507
        TRACE("error: %s\n", debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
508 509 510 511 512
        ret = TRUE;
    } else TRACE("OpenGL implementation allows offsets > 63\n");

    GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
    GL_EXTCALL(glDeleteProgramsARB(1, &prog));
513
    checkGLcall("ARB vp offset limit test cleanup");
514 515 516 517

    return ret;
}

518 519 520
static BOOL match_amd_r300_to_500(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx,
        const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
        enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
521
{
522 523 524 525
    if (card_vendor != HW_VENDOR_AMD) return FALSE;
    if (device == CARD_AMD_RADEON_9500) return TRUE;
    if (device == CARD_AMD_RADEON_X700) return TRUE;
    if (device == CARD_AMD_RADEON_X1600) return TRUE;
526 527
    return FALSE;
}
528

529 530 531
static BOOL match_geforce5(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx,
        const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
        enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
532
{
533
    if (card_vendor == HW_VENDOR_NVIDIA)
534
    {
535 536 537
        if (device == CARD_NVIDIA_GEFORCEFX_5200 ||
            device == CARD_NVIDIA_GEFORCEFX_5600 ||
            device == CARD_NVIDIA_GEFORCEFX_5800)
538 539 540
        {
            return TRUE;
        }
541
    }
542 543
    return FALSE;
}
544

545 546 547
static BOOL match_apple(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx,
        const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
        enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
548 549 550 551 552 553 554 555 556 557 558
{
    /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
     * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
     * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
     *
     * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
     * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
     * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
     * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
     * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
     * the chance that other implementations support them is rather small since Win32 QuickTime uses
559 560 561 562
     * DirectDraw, not OpenGL.
     *
     * This test has been moved into wined3d_guess_gl_vendor()
     */
563
    return gl_vendor == GL_VENDOR_APPLE;
564
}
565

566
/* Context activation is done by the caller. */
567
static void test_pbo_functionality(struct wined3d_gl_info *gl_info)
568 569 570 571 572 573 574 575 576 577 578 579 580
{
    /* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
     * but glTexSubImage from a PBO fails miserably, with the first line repeated over
     * all the texture. This function detects this bug by its symptom and disables PBOs
     * if the test fails.
     *
     * The test uploads a 4x4 texture via the PBO in the "native" format GL_BGRA,
     * GL_UNSIGNED_INT_8_8_8_8_REV. This format triggers the bug, and it is what we use
     * for D3DFMT_A8R8G8B8. Then the texture is read back without any PBO and the data
     * read back is compared to the original. If they are equal PBOs are assumed to work,
     * otherwise the PBO extension is disabled. */
    GLuint texture, pbo;
    static const unsigned int pattern[] =
581
    {
582 583 584 585 586
        0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000,
        0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff,
        0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
        0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
    };
587
    unsigned int check[ARRAY_SIZE(pattern)];
588

589 590
    /* No PBO -> No point in testing them. */
    if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) return;
591

592 593 594
    while (gl_info->gl_ops.gl.p_glGetError());
    gl_info->gl_ops.gl.p_glGenTextures(1, &texture);
    gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, texture);
595

596 597
    gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
    gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
598
    checkGLcall("Specifying the PBO test texture");
599

600 601 602
    GL_EXTCALL(glGenBuffers(1, &pbo));
    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo));
    GL_EXTCALL(glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(pattern), pattern, GL_STREAM_DRAW));
603
    checkGLcall("Specifying the PBO test pbo");
604

605
    gl_info->gl_ops.gl.p_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
606
    checkGLcall("Loading the PBO test texture");
607

608
    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
609

610
    gl_info->gl_ops.gl.p_glFinish(); /* just to be sure */
611

612
    memset(check, 0, sizeof(check));
613
    gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check);
614
    checkGLcall("Reading back the PBO test texture");
615

616
    gl_info->gl_ops.gl.p_glDeleteTextures(1, &texture);
617
    GL_EXTCALL(glDeleteBuffers(1, &pbo));
618
    checkGLcall("PBO test cleanup");
619

620 621
    if (memcmp(check, pattern, sizeof(check)))
    {
622
        WARN_(d3d_perf)("PBO test failed, read back data doesn't match original.\n"
623
                "Disabling PBOs. This may result in slower performance.\n");
624 625 626 627
        gl_info->supported[ARB_PIXEL_BUFFER_OBJECT] = FALSE;
    }
    else
    {
628
        TRACE("PBO test successful.\n");
629 630
    }
}
631

632 633 634
static BOOL match_apple_intel(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx,
        const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
        enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
635
{
636
    return (card_vendor == HW_VENDOR_INTEL) && (gl_vendor == GL_VENDOR_APPLE);
637
}
638

639 640 641
static BOOL match_apple_nonr500ati(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx,
        const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
        enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
642
{
643
    if (gl_vendor != GL_VENDOR_APPLE) return FALSE;
644 645
    if (card_vendor != HW_VENDOR_AMD) return FALSE;
    if (device == CARD_AMD_RADEON_X1600) return FALSE;
646 647
    return TRUE;
}
648

649 650 651
static BOOL match_dx10_capable(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx,
        const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
        enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
652 653 654 655
{
    /* DX9 cards support 40 single float varyings in hardware, most drivers report 32. ATI misreports
     * 44 varyings. So assume that if we have more than 44 varyings we have a dx10 card.
     * This detection is for the gl_ClipPos varying quirk. If a d3d9 card really supports more than 44
656
     * varyings and we subtract one in dx9 shaders it's not going to hurt us because the dx9 limit is
657 658 659
     * hardcoded
     *
     * dx10 cards usually have 64 varyings */
660
    return gl_info->limits.glsl_varyings > 44;
661
}
662

663 664 665
static BOOL match_not_dx10_capable(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx,
        const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
        enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
666
{
667
    return !match_dx10_capable(gl_info, ctx, gl_renderer, gl_vendor, card_vendor, device);
668 669
}

670
/* A GL context is provided by the caller */
671 672 673
static BOOL match_allows_spec_alpha(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx,
        const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
        enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
674 675 676 677
{
    GLenum error;
    DWORD data[16];

678 679
    if (!gl_info->supported[EXT_SECONDARY_COLOR])
        return FALSE;
680

681
    while (gl_info->gl_ops.gl.p_glGetError());
682
    GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE, 4, data);
683
    error = gl_info->gl_ops.gl.p_glGetError();
684

685
    if (error == GL_NO_ERROR)
686 687 688 689 690 691 692 693 694 695 696 697
    {
        TRACE("GL Implementation accepts 4 component specular color pointers\n");
        return TRUE;
    }
    else
    {
        TRACE("GL implementation does not accept 4 component specular colors, error %s\n",
              debug_glerror(error));
        return FALSE;
    }
}

698
/* A GL context is provided by the caller */
699 700 701
static BOOL match_broken_nv_clip(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx,
        const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
        enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
702 703 704 705
{
    GLuint prog;
    BOOL ret = FALSE;
    GLint pos;
706
    static const char testcode[] =
707 708 709 710 711 712
        "!!ARBvp1.0\n"
        "OPTION NV_vertex_program2;\n"
        "MOV result.clip[0], 0.0;\n"
        "MOV result.position, 0.0;\n"
        "END\n";

713
    if (!gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]) return FALSE;
714

715
    while (gl_info->gl_ops.gl.p_glGetError());
716 717 718 719

    GL_EXTCALL(glGenProgramsARB(1, &prog));
    if(!prog)
    {
720
        ERR("Failed to create the NVvp clip test program\n");
721 722 723 724 725
        return FALSE;
    }
    GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog));
    GL_EXTCALL(glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
                                  strlen(testcode), testcode));
726
    gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
727 728 729
    if(pos != -1)
    {
        WARN("GL_NV_vertex_program2_option result.clip[] test failed\n");
730
        TRACE("error: %s\n", debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
731
        ret = TRUE;
732
        while (gl_info->gl_ops.gl.p_glGetError());
733 734 735 736 737 738 739 740 741 742
    }
    else TRACE("GL_NV_vertex_program2_option result.clip[] test passed\n");

    GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
    GL_EXTCALL(glDeleteProgramsARB(1, &prog));
    checkGLcall("GL_NV_vertex_program2_option result.clip[] test cleanup");

    return ret;
}

743
/* Context activation is done by the caller. */
744 745 746
static BOOL match_fbo_tex_update(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx,
        const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
        enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
747 748 749 750 751 752 753 754 755
{
    char data[4 * 4 * 4];
    GLuint tex, fbo;
    GLenum status;

    if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) return FALSE;

    memset(data, 0xcc, sizeof(data));

756 757 758 759 760
    gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
    gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
    gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
761 762 763 764 765 766 767 768 769 770 771 772
    checkGLcall("glTexImage2D");

    gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
    gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
    checkGLcall("glFramebufferTexture2D");

    status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status);
    checkGLcall("glCheckFramebufferStatus");

    memset(data, 0x11, sizeof(data));
773
    gl_info->gl_ops.gl.p_glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
774 775
    checkGLcall("glTexSubImage2D");

776 777
    gl_info->gl_ops.gl.p_glClearColor(0.996f, 0.729f, 0.745f, 0.792f);
    gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
778 779
    checkGLcall("glClear");

780
    gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
781 782 783 784
    checkGLcall("glGetTexImage");

    gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
    gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
785
    gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, 0);
786 787 788
    checkGLcall("glBindTexture");

    gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
789
    gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
790 791 792 793 794
    checkGLcall("glDeleteTextures");

    return *(DWORD *)data == 0x11111111;
}

795
/* Context activation is done by the caller. */
796 797 798
static BOOL match_broken_rgba16(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx,
        const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
        enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
799 800 801 802 803 804
{
    /* GL_RGBA16 uses GL_RGBA8 internally on Geforce 7 and older cards.
     * This leads to graphical bugs in Half Life 2 and Unreal engine games. */
    GLuint tex;
    GLint size;

805 806 807
    gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
    gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
    gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16, 4, 4, 0, GL_RGBA, GL_UNSIGNED_SHORT, NULL);
808 809
    checkGLcall("glTexImage2D");

810
    gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &size);
811 812 813
    checkGLcall("glGetTexLevelParameteriv");
    TRACE("Real color depth is %d\n", size);

814
    gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, 0);
815
    checkGLcall("glBindTexture");
816
    gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
817 818 819 820 821
    checkGLcall("glDeleteTextures");

    return size < 16;
}

822 823 824
static BOOL match_fglrx(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx,
        const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
        enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
825 826 827 828
{
    return gl_vendor == GL_VENDOR_FGLRX;
}

829 830 831
static BOOL match_r200(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx,
        const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
        enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
832 833 834 835 836 837
{
    if (card_vendor != HW_VENDOR_AMD) return FALSE;
    if (device == CARD_AMD_RADEON_8500) return TRUE;
    return FALSE;
}

838 839 840
static BOOL match_broken_arb_fog(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx,
        const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
        enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
841 842 843 844 845 846 847
{
    DWORD data[4];
    GLuint tex, fbo;
    GLenum status;
    float color[4] = {0.0f, 1.0f, 0.0f, 0.0f};
    GLuint prog;
    GLint err_pos;
848
    static const char program_code[] =
849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933
        "!!ARBfp1.0\n"
        "OPTION ARB_fog_linear;\n"
        "MOV result.color, {1.0, 0.0, 0.0, 0.0};\n"
        "END\n";

    if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
        return FALSE;
    if (!gl_info->supported[ARB_FRAGMENT_PROGRAM])
        return FALSE;

    gl_info->gl_ops.gl.p_glGenTextures(1, &tex);
    gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, tex);
    gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    gl_info->gl_ops.gl.p_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    gl_info->gl_ops.gl.p_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, 4, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
    checkGLcall("glTexImage2D");

    gl_info->fbo_ops.glGenFramebuffers(1, &fbo);
    gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    gl_info->fbo_ops.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
    checkGLcall("glFramebufferTexture2D");

    status = gl_info->fbo_ops.glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if (status != GL_FRAMEBUFFER_COMPLETE) ERR("FBO status %#x\n", status);
    checkGLcall("glCheckFramebufferStatus");

    gl_info->gl_ops.gl.p_glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
    gl_info->gl_ops.gl.p_glClear(GL_COLOR_BUFFER_BIT);
    checkGLcall("glClear");
    gl_info->gl_ops.gl.p_glViewport(0, 0, 4, 1);
    checkGLcall("glViewport");

    gl_info->gl_ops.gl.p_glEnable(GL_FOG);
    gl_info->gl_ops.gl.p_glFogf(GL_FOG_START, 0.5f);
    gl_info->gl_ops.gl.p_glFogf(GL_FOG_END, 0.5f);
    gl_info->gl_ops.gl.p_glFogi(GL_FOG_MODE, GL_LINEAR);
    gl_info->gl_ops.gl.p_glHint(GL_FOG_HINT, GL_NICEST);
    gl_info->gl_ops.gl.p_glFogfv(GL_FOG_COLOR, color);
    checkGLcall("fog setup");

    GL_EXTCALL(glGenProgramsARB(1, &prog));
    GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog));
    GL_EXTCALL(glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
            strlen(program_code), program_code));
    gl_info->gl_ops.gl.p_glEnable(GL_FRAGMENT_PROGRAM_ARB);
    checkGLcall("Test fragment program setup");

    gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &err_pos);
    if (err_pos != -1)
    {
        const char *error_str;
        error_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB);
        FIXME("Fog test program error at position %d: %s\n\n", err_pos, debugstr_a(error_str));
    }

    gl_info->gl_ops.gl.p_glBegin(GL_TRIANGLE_STRIP);
    gl_info->gl_ops.gl.p_glVertex3f(-1.0f, -1.0f,  0.0f);
    gl_info->gl_ops.gl.p_glVertex3f( 1.0f, -1.0f,  1.0f);
    gl_info->gl_ops.gl.p_glVertex3f(-1.0f,  1.0f,  0.0f);
    gl_info->gl_ops.gl.p_glVertex3f( 1.0f,  1.0f,  1.0f);
    gl_info->gl_ops.gl.p_glEnd();
    checkGLcall("ARBfp fog test draw");

    gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
    checkGLcall("glGetTexImage");
    data[0] &= 0x00ffffff;
    data[1] &= 0x00ffffff;
    data[2] &= 0x00ffffff;
    data[3] &= 0x00ffffff;

    gl_info->fbo_ops.glBindFramebuffer(GL_FRAMEBUFFER, 0);
    gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, 0);

    gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
    gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
    gl_info->gl_ops.gl.p_glDisable(GL_FOG);
    GL_EXTCALL(glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, 0));
    gl_info->gl_ops.gl.p_glDisable(GL_FRAGMENT_PROGRAM_ARB);
    GL_EXTCALL(glDeleteProgramsARB(1, &prog));
    checkGLcall("ARBfp fog test teardown");

    TRACE("Fog test data: %08x %08x %08x %08x\n", data[0], data[1], data[2], data[3]);
    return data[0] != 0x00ff0000 || data[3] != 0x0000ff00;
}

934 935 936 937 938 939 940 941 942 943 944
static BOOL match_broken_viewport_subpixel_bits(const struct wined3d_gl_info *gl_info,
        struct wined3d_caps_gl_ctx *ctx, const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
        enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
{
    if (!gl_info->supported[ARB_VIEWPORT_ARRAY])
        return FALSE;
    if (wined3d_settings.offscreen_rendering_mode != ORM_FBO)
        return FALSE;
    return !wined3d_caps_gl_ctx_test_viewport_subpixel_bits(ctx);
}

945
static void quirk_apple_glsl_constants(struct wined3d_gl_info *gl_info)
946 947 948 949
{
    /* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms.
     * Beyond that the general uniform isn't optimal, so reserve a number of uniforms. 12 vec4's should
     * allow 48 different offsets or other helper immediate values. */
950
    TRACE("Reserving 12 GLSL constants for compiler private use.\n");
951 952 953
    gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12);
}

954
static void quirk_amd_dx9(struct wined3d_gl_info *gl_info)
955 956 957 958
{
    /* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
     * these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
     * If real NP2 textures are used, the driver falls back to software. We could just remove the
959
     * extension and use GL_ARB_texture_rectangle instead, but texture_rectangle is inconvenient
960 961 962 963 964 965 966
     * due to the non-normalized texture coordinates. Thus set an internal extension flag,
     * GL_WINE_normalized_texrect, which signals the code that it can use non power of two textures
     * as per GL_ARB_texture_non_power_of_two, but has to stick to the texture_rectangle limits.
     *
     * fglrx doesn't advertise GL_ARB_texture_non_power_of_two, but it advertises opengl 2.0 which
     * has this extension promoted to core. The extension loading code sets this extension supported
     * due to that, so this code works on fglrx as well. */
967 968 969 970
    if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
    {
        TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing.\n");
        gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
971
        gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] = TRUE;
972
    }
973 974
}

975
static void quirk_no_np2(struct wined3d_gl_info *gl_info)
976 977 978 979 980 981 982 983 984 985
{
    /*  The nVidia GeForceFX series reports OpenGL 2.0 capabilities with the latest drivers versions, but
     *  doesn't explicitly advertise the ARB_tex_npot extension in the GL extension string.
     *  This usually means that ARB_tex_npot is supported in hardware as long as the application is staying
     *  within the limits enforced by the ARB_texture_rectangle extension. This however is not true for the
     *  FX series, which instantly falls back to a slower software path as soon as ARB_tex_npot is used.
     *  We therefore completely remove ARB_tex_npot from the list of supported extensions.
     *
     *  Note that wine_normalized_texrect can't be used in this case because internally it uses ARB_tex_npot,
     *  triggering the software fallback. There is not much we can do here apart from disabling the
986
     *  software-emulated extension and re-enable ARB_tex_rect (which was previously disabled
987
     *  in wined3d_adapter_init_gl_caps).
988 989 990 991 992 993 994 995
     *  This fixup removes performance problems on both the FX 5900 and FX 5700 (e.g. for framebuffer
     *  post-processing effects in the game "Max Payne 2").
     *  The behaviour can be verified through a simple test app attached in bugreport #14724. */
    TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing.\n");
    gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
    gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
}

996
static void quirk_texcoord_w(struct wined3d_gl_info *gl_info)
997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
{
    /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
     * with fixed function fragment processing. Ideally this flag should be detected with a test shader
     * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
     * do not like vertex shaders in feedback mode and return an error, even though it should be valid
     * according to the spec.
     *
     * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
     * makes the shader slower and eats instruction slots which should be available to the d3d app.
     *
     * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
     * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
     * this workaround is activated on cards that do not need it, it won't break things, just affect
     * performance negatively. */
    TRACE("Enabling vertex texture coord fixes in vertex shaders.\n");
    gl_info->quirks |= WINED3D_QUIRK_SET_TEXCOORD_W;
}

1015
static void quirk_clip_varying(struct wined3d_gl_info *gl_info)
1016 1017 1018 1019
{
    gl_info->quirks |= WINED3D_QUIRK_GLSL_CLIP_VARYING;
}

1020
static void quirk_allows_specular_alpha(struct wined3d_gl_info *gl_info)
1021 1022 1023 1024
{
    gl_info->quirks |= WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA;
}

1025 1026 1027 1028 1029
static void quirk_disable_nvvp_clip(struct wined3d_gl_info *gl_info)
{
    gl_info->quirks |= WINED3D_QUIRK_NV_CLIP_BROKEN;
}

1030 1031 1032 1033 1034
static void quirk_fbo_tex_update(struct wined3d_gl_info *gl_info)
{
    gl_info->quirks |= WINED3D_QUIRK_FBO_TEX_UPDATE;
}

1035 1036 1037 1038 1039
static void quirk_broken_rgba16(struct wined3d_gl_info *gl_info)
{
    gl_info->quirks |= WINED3D_QUIRK_BROKEN_RGBA16;
}

1040 1041 1042 1043 1044
static void quirk_infolog_spam(struct wined3d_gl_info *gl_info)
{
    gl_info->quirks |= WINED3D_QUIRK_INFO_LOG_SPAM;
}

1045
static void quirk_limited_tex_filtering(struct wined3d_gl_info *gl_info)
1046
{
1047 1048 1049 1050 1051 1052
    /* Nvidia GeForce 6xxx and 7xxx support accelerated VTF only on a few
       selected texture formats. They are apparently the only DX9 class GPUs
       supporting VTF.
       Also, DX9-era GPUs are somewhat limited with float textures
       filtering and blending. */
    gl_info->quirks |= WINED3D_QUIRK_LIMITED_TEX_FILTERING;
1053 1054
}

1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067
static void quirk_r200_constants(struct wined3d_gl_info *gl_info)
{
    /* The Mesa r200 driver (and there is no other driver for this GPU Wine would run on)
     * loads some fog parameters (start, end, exponent, but not the color) into the
     * program.
     *
     * Apparently the fog hardware is only able to handle linear fog with a range of 0.0;1.0,
     * and it is the responsibility of the vertex pipeline to handle non-linear fog and
     * linear fog with start and end other than 0.0 and 1.0. */
    TRACE("Reserving 1 ARB constant for compiler private use.\n");
    gl_info->reserved_arb_constants = max(gl_info->reserved_arb_constants, 1);
}

1068 1069 1070 1071 1072
static void quirk_broken_arb_fog(struct wined3d_gl_info *gl_info)
{
    gl_info->quirks |= WINED3D_QUIRK_BROKEN_ARB_FOG;
}

1073 1074 1075 1076 1077 1078 1079 1080 1081
static void quirk_broken_viewport_subpixel_bits(struct wined3d_gl_info *gl_info)
{
    if (gl_info->supported[ARB_CLIP_CONTROL])
    {
        TRACE("Disabling ARB_clip_control.\n");
        gl_info->supported[ARB_CLIP_CONTROL] = FALSE;
    }
}

1082 1083
struct driver_quirk
{
1084 1085 1086
    BOOL (*match)(const struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx,
            const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
            enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device);
1087
    void (*apply)(struct wined3d_gl_info *gl_info);
1088 1089 1090
    const char *description;
};

1091
static const struct driver_quirk quirk_table[] =
1092 1093
{
    {
1094 1095
        match_amd_r300_to_500,
        quirk_amd_dx9,
1096
        "AMD normalized texrect quirk"
1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121
    },
    {
        match_apple,
        quirk_apple_glsl_constants,
        "Apple GLSL uniform override"
    },
    {
        match_geforce5,
        quirk_no_np2,
        "Geforce 5 NP2 disable"
    },
    {
        match_apple_intel,
        quirk_texcoord_w,
        "Init texcoord .w for Apple Intel GPU driver"
    },
    {
        match_apple_nonr500ati,
        quirk_texcoord_w,
        "Init texcoord .w for Apple ATI >= r600 GPU driver"
    },
    {
        match_dx10_capable,
        quirk_clip_varying,
        "Reserved varying for gl_ClipPos"
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136
    },
    {
        /* GL_EXT_secondary_color does not allow 4 component secondary colors, but most
         * GL implementations accept it. The Mac GL is the only implementation known to
         * reject it.
         *
         * If we can pass 4 component specular colors, do it, because (a) we don't have
         * to screw around with the data, and (b) the D3D fixed function vertex pipeline
         * passes specular alpha to the pixel shader if any is used. Otherwise the
         * specular alpha is used to pass the fog coordinate, which we pass to opengl
         * via GL_EXT_fog_coord.
         */
        match_allows_spec_alpha,
        quirk_allows_specular_alpha,
        "Allow specular alpha quirk"
1137
    },
1138 1139 1140 1141 1142
    {
        match_broken_nv_clip,
        quirk_disable_nvvp_clip,
        "Apple NV_vertex_program clip bug quirk"
    },
1143 1144 1145 1146 1147
    {
        match_fbo_tex_update,
        quirk_fbo_tex_update,
        "FBO rebind for attachment updates"
    },
1148 1149 1150 1151 1152
    {
        match_broken_rgba16,
        quirk_broken_rgba16,
        "True RGBA16 is not available"
    },
1153 1154 1155 1156 1157
    {
        match_fglrx,
        quirk_infolog_spam,
        "Not printing GLSL infolog"
    },
1158
    {
1159 1160 1161
        match_not_dx10_capable,
        quirk_limited_tex_filtering,
        "Texture filtering, blending and VTF support is limited"
1162
    },
1163 1164 1165 1166 1167
    {
        match_r200,
        quirk_r200_constants,
        "r200 vertex shader constants"
    },
1168 1169 1170 1171 1172
    {
        match_broken_arb_fog,
        quirk_broken_arb_fog,
        "ARBfp fogstart == fogend workaround"
    },
1173 1174 1175 1176 1177
    {
        match_broken_viewport_subpixel_bits,
        quirk_broken_viewport_subpixel_bits,
        "Nvidia viewport subpixel bits bug"
    },
1178 1179 1180 1181 1182 1183
};

/* Certain applications (Steam) complain if we report an outdated driver version. In general,
 * reporting a driver version is moot because we are not the Windows driver, and we have different
 * bugs, features, etc.
 *
1184 1185 1186 1187 1188 1189 1190 1191 1192
 * The driver version has the form "x.y.z.w".
 *
 * "x" is the Windows version the driver is meant for:
 * 4 -> 95/98/NT4
 * 5 -> 2000
 * 6 -> 2000/XP
 * 7 -> Vista
 * 8 -> Win 7
 *
1193 1194
 * "y" is the maximum Direct3D version the driver supports.
 * y  -> d3d version mapping:
1195 1196 1197 1198 1199
 * 11 -> d3d6
 * 12 -> d3d7
 * 13 -> d3d8
 * 14 -> d3d9
 * 15 -> d3d10
1200 1201
 * 16 -> d3d10.1
 * 17 -> d3d11
1202
 *
1203
 * "z" is the subversion number.
1204
 *
1205
 * "w" is the vendor specific driver build number.
1206
 */
1207

1208
struct driver_version_information
1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220
{
    enum wined3d_display_driver driver;
    enum wined3d_driver_model driver_model;
    const char *driver_name;            /* name of Windows driver */
    WORD version;                       /* version word ('y'), contained in low word of DriverVersion.HighPart */
    WORD subversion;                    /* subversion word ('z'), contained in high word of DriverVersion.LowPart */
    WORD build;                         /* build number ('w'), contained in low word of DriverVersion.LowPart */
};

/* The driver version table contains driver information for different devices on several OS versions. */
static const struct driver_version_information driver_version_table[] =
{
1221
    /* AMD
1222
     * - Radeon HD2x00 (R600) and up supported by current drivers.
1223 1224 1225
     * - Radeon 9500 (R300) - X1*00 (R5xx) supported up to Catalyst 9.3 (Linux) and 10.2 (XP/Vista/Win7)
     * - Radeon 7xxx (R100) - 9250 (RV250) supported up to Catalyst 6.11 (XP)
     * - Rage 128 supported up to XP, latest official build 6.13.3279 dated October 2001 */
1226 1227 1228
    {DRIVER_AMD_RAGE_128PRO,    DRIVER_MODEL_NT5X,  "ati2dvaa.dll", 13, 3279,  0},
    {DRIVER_AMD_R100,           DRIVER_MODEL_NT5X,  "ati2dvag.dll", 14, 10, 6614},
    {DRIVER_AMD_R300,           DRIVER_MODEL_NT5X,  "ati2dvag.dll", 14, 10, 6764},
1229
    {DRIVER_AMD_R600,           DRIVER_MODEL_NT5X,  "ati2dvag.dll", 17, 10, 1280},
1230
    {DRIVER_AMD_R300,           DRIVER_MODEL_NT6X,  "atiumdag.dll", 14, 10, 741 },
1231
    {DRIVER_AMD_R600,           DRIVER_MODEL_NT6X,  "atiumdag.dll", 17, 10, 1280},
1232
    {DRIVER_AMD_RX,             DRIVER_MODEL_NT6X,  "aticfx32.dll", 17, 10, 1474},
1233

1234 1235 1236 1237 1238 1239 1240 1241 1242 1243
    /* Intel
     * The drivers are unified but not all versions support all GPUs. At some point the 2k/xp
     * drivers used ialmrnt5.dll for GMA800/GMA900 but at some point the file was renamed to
     * igxprd32.dll but the GMA800 driver was never updated. */
    {DRIVER_INTEL_GMA800,       DRIVER_MODEL_NT5X,  "ialmrnt5.dll", 14, 10, 3889},
    {DRIVER_INTEL_GMA900,       DRIVER_MODEL_NT5X,  "igxprd32.dll", 14, 10, 4764},
    {DRIVER_INTEL_GMA950,       DRIVER_MODEL_NT5X,  "igxprd32.dll", 14, 10, 4926},
    {DRIVER_INTEL_GMA3000,      DRIVER_MODEL_NT5X,  "igxprd32.dll", 14, 10, 5218},
    {DRIVER_INTEL_GMA950,       DRIVER_MODEL_NT6X,  "igdumd32.dll", 14, 10, 1504},
    {DRIVER_INTEL_GMA3000,      DRIVER_MODEL_NT6X,  "igdumd32.dll", 15, 10, 1666},
1244
    {DRIVER_INTEL_HD4000,       DRIVER_MODEL_NT6X,  "igdumdim32.dll", 19, 15, 4352},
1245

1246
    /* Nvidia
1247 1248
     * - Geforce8 and newer is supported by the current 340.52 driver on XP-Win8
     * - Geforce6 and 7 support is up to 307.83 on XP-Win8
1249 1250 1251 1252 1253 1254 1255
     * - GeforceFX support is up to 173.x on <= XP
     * - Geforce2MX/3/4 up to 96.x on <= XP
     * - TNT/Geforce1/2 up to 71.x on <= XP
     * All version numbers used below are from the Linux nvidia drivers. */
    {DRIVER_NVIDIA_TNT,         DRIVER_MODEL_NT5X,  "nv4_disp.dll", 14, 10, 7186},
    {DRIVER_NVIDIA_GEFORCE2MX,  DRIVER_MODEL_NT5X,  "nv4_disp.dll", 14, 10, 9371},
    {DRIVER_NVIDIA_GEFORCEFX,   DRIVER_MODEL_NT5X,  "nv4_disp.dll", 14, 11, 7516},
1256 1257 1258 1259
    {DRIVER_NVIDIA_GEFORCE6,    DRIVER_MODEL_NT5X,  "nv4_disp.dll", 18, 13,  783},
    {DRIVER_NVIDIA_GEFORCE8,    DRIVER_MODEL_NT5X,  "nv4_disp.dll", 18, 13, 4052},
    {DRIVER_NVIDIA_GEFORCE6,    DRIVER_MODEL_NT6X,  "nvd3dum.dll",  18, 13,  783},
    {DRIVER_NVIDIA_GEFORCE8,    DRIVER_MODEL_NT6X,  "nvd3dum.dll",  18, 13, 4052},
1260 1261 1262

    /* VMware */
    {DRIVER_VMWARE,             DRIVER_MODEL_NT5X,  "vm3dum.dll",   14, 1,  1134},
1263 1264 1265
};

struct gpu_description
1266
{
1267
    WORD vendor;                    /* reported PCI card vendor ID  */
1268 1269
    WORD card;                      /* reported PCI card device ID  */
    const char *description;        /* Description of the card e.g. NVIDIA RIVA TNT */
1270
    enum wined3d_display_driver driver;
1271
    unsigned int vidmem;
1272 1273
};

1274 1275
/* The amount of video memory stored in the gpu description table is the minimum amount of video memory
 * found on a board containing a specific GPU. */
1276
static const struct gpu_description gpu_description_table[] =
1277
{
1278
    /* Nvidia cards */
1279
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_RIVA_128,           "NVIDIA RIVA 128",                  DRIVER_NVIDIA_TNT,       4   },
1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_RIVA_TNT,           "NVIDIA RIVA TNT",                  DRIVER_NVIDIA_TNT,       16  },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_RIVA_TNT2,          "NVIDIA RIVA TNT2/TNT2 Pro",        DRIVER_NVIDIA_TNT,       32  },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE,            "NVIDIA GeForce 256",               DRIVER_NVIDIA_TNT,       32  },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE2,           "NVIDIA GeForce2 GTS/GeForce2 Pro", DRIVER_NVIDIA_TNT,       32  },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE2_MX,        "NVIDIA GeForce2 MX/MX 400",        DRIVER_NVIDIA_GEFORCE2MX,32  },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE3,           "NVIDIA GeForce3",                  DRIVER_NVIDIA_GEFORCE2MX,64  },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE4_MX,        "NVIDIA GeForce4 MX 460",           DRIVER_NVIDIA_GEFORCE2MX,64  },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE4_TI4200,    "NVIDIA GeForce4 Ti 4200",          DRIVER_NVIDIA_GEFORCE2MX,64, },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5200,     "NVIDIA GeForce FX 5200",           DRIVER_NVIDIA_GEFORCEFX, 64  },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5600,     "NVIDIA GeForce FX 5600",           DRIVER_NVIDIA_GEFORCEFX, 128 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCEFX_5800,     "NVIDIA GeForce FX 5800",           DRIVER_NVIDIA_GEFORCEFX, 256 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6200,       "NVIDIA GeForce 6200",              DRIVER_NVIDIA_GEFORCE6,  64  },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6600GT,     "NVIDIA GeForce 6600 GT",           DRIVER_NVIDIA_GEFORCE6,  128 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_6800,       "NVIDIA GeForce 6800",              DRIVER_NVIDIA_GEFORCE6,  128 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7300,       "NVIDIA GeForce Go 7300",           DRIVER_NVIDIA_GEFORCE6,  256 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7400,       "NVIDIA GeForce Go 7400",           DRIVER_NVIDIA_GEFORCE6,  256 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7600,       "NVIDIA GeForce 7600 GT",           DRIVER_NVIDIA_GEFORCE6,  256 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_7800GT,     "NVIDIA GeForce 7800 GT",           DRIVER_NVIDIA_GEFORCE6,  256 },
1298
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8200,       "NVIDIA GeForce 8200",              DRIVER_NVIDIA_GEFORCE8,  512 },
1299 1300
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8300GS,     "NVIDIA GeForce 8300 GS",           DRIVER_NVIDIA_GEFORCE8,  128 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8400GS,     "NVIDIA GeForce 8400 GS",           DRIVER_NVIDIA_GEFORCE8,  128 },
1301
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8500GT,     "NVIDIA GeForce 8500 GT",           DRIVER_NVIDIA_GEFORCE8,  256 },
1302 1303 1304 1305 1306 1307 1308 1309 1310
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600GT,     "NVIDIA GeForce 8600 GT",           DRIVER_NVIDIA_GEFORCE8,  256 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8600MGT,    "NVIDIA GeForce 8600M GT",          DRIVER_NVIDIA_GEFORCE8,  512 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTS,    "NVIDIA GeForce 8800 GTS",          DRIVER_NVIDIA_GEFORCE8,  320 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8800GTX,    "NVIDIA GeForce 8800 GTX",          DRIVER_NVIDIA_GEFORCE8,  768 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9200,       "NVIDIA GeForce 9200",              DRIVER_NVIDIA_GEFORCE8,  256 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9300,       "NVIDIA GeForce 9300",              DRIVER_NVIDIA_GEFORCE8,  256 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9400M,      "NVIDIA GeForce 9400M",             DRIVER_NVIDIA_GEFORCE8,  256 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9400GT,     "NVIDIA GeForce 9400 GT",           DRIVER_NVIDIA_GEFORCE8,  256 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9500GT,     "NVIDIA GeForce 9500 GT",           DRIVER_NVIDIA_GEFORCE8,  256 },
1311
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9600GT,     "NVIDIA GeForce 9600 GT",           DRIVER_NVIDIA_GEFORCE8,  512 },
1312
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9700MGT,    "NVIDIA GeForce 9700M GT",          DRIVER_NVIDIA_GEFORCE8,  512 },
1313 1314 1315 1316
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9800GT,     "NVIDIA GeForce 9800 GT",           DRIVER_NVIDIA_GEFORCE8,  512 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_210,        "NVIDIA GeForce 210",               DRIVER_NVIDIA_GEFORCE8,  512 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT220,      "NVIDIA GeForce GT 220",            DRIVER_NVIDIA_GEFORCE8,  512 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT240,      "NVIDIA GeForce GT 240",            DRIVER_NVIDIA_GEFORCE8,  512 },
1317
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTS250,     "NVIDIA GeForce GTS 250",           DRIVER_NVIDIA_GEFORCE8,  1024},
1318 1319 1320 1321 1322 1323 1324 1325 1326
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX260,     "NVIDIA GeForce GTX 260",           DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX275,     "NVIDIA GeForce GTX 275",           DRIVER_NVIDIA_GEFORCE8,  896 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX280,     "NVIDIA GeForce GTX 280",           DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_315M,       "NVIDIA GeForce 315M",              DRIVER_NVIDIA_GEFORCE8,  512 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_320M,       "NVIDIA GeForce 320M",              DRIVER_NVIDIA_GEFORCE8,  256},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT320M,     "NVIDIA GeForce GT 320M",           DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT325M,     "NVIDIA GeForce GT 325M",           DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT330,      "NVIDIA GeForce GT 330",            DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTS350M,    "NVIDIA GeForce GTS 350M",          DRIVER_NVIDIA_GEFORCE8,  1024},
1327
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_410M,       "NVIDIA GeForce 410M",              DRIVER_NVIDIA_GEFORCE8,  512},
1328
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT420,      "NVIDIA GeForce GT 420",            DRIVER_NVIDIA_GEFORCE8,  2048},
1329
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT425M,     "NVIDIA GeForce GT 425M",           DRIVER_NVIDIA_GEFORCE8,  1024},
1330 1331 1332 1333 1334 1335 1336 1337 1338
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT430,      "NVIDIA GeForce GT 430",            DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT440,      "NVIDIA GeForce GT 440",            DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTS450,     "NVIDIA GeForce GTS 450",           DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX460,     "NVIDIA GeForce GTX 460",           DRIVER_NVIDIA_GEFORCE8,  768 },
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX460M,    "NVIDIA GeForce GTX 460M",          DRIVER_NVIDIA_GEFORCE8,  1536},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX465,     "NVIDIA GeForce GTX 465",           DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX470,     "NVIDIA GeForce GTX 470",           DRIVER_NVIDIA_GEFORCE8,  1280},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX480,     "NVIDIA GeForce GTX 480",           DRIVER_NVIDIA_GEFORCE8,  1536},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT520,      "NVIDIA GeForce GT 520",            DRIVER_NVIDIA_GEFORCE8,  1024},
1339
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT525M,     "NVIDIA GeForce GT 525M",           DRIVER_NVIDIA_GEFORCE8,  1024},
1340 1341 1342 1343
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT540M,     "NVIDIA GeForce GT 540M",           DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX550,     "NVIDIA GeForce GTX 550 Ti",        DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT555M,     "NVIDIA GeForce GT 555M",           DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX560TI,   "NVIDIA GeForce GTX 560 Ti",        DRIVER_NVIDIA_GEFORCE8,  1024},
1344
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX560M,    "NVIDIA GeForce GTX 560M",          DRIVER_NVIDIA_GEFORCE8,  3072},
1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX560,     "NVIDIA GeForce GTX 560",           DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX570,     "NVIDIA GeForce GTX 570",           DRIVER_NVIDIA_GEFORCE8,  1280},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX580,     "NVIDIA GeForce GTX 580",           DRIVER_NVIDIA_GEFORCE8,  1536},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT610,      "NVIDIA GeForce GT 610",            DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT630,      "NVIDIA GeForce GT 630",            DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT630M,     "NVIDIA GeForce GT 630M",           DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT640M,     "NVIDIA GeForce GT 640M",           DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT650M,     "NVIDIA GeForce GT 650M",           DRIVER_NVIDIA_GEFORCE8,  2048},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX650,     "NVIDIA GeForce GTX 650",           DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX650TI,   "NVIDIA GeForce GTX 650 Ti",        DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX660,     "NVIDIA GeForce GTX 660",           DRIVER_NVIDIA_GEFORCE8,  2048},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX660M,    "NVIDIA GeForce GTX 660M",          DRIVER_NVIDIA_GEFORCE8,  2048},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX660TI,   "NVIDIA GeForce GTX 660 Ti",        DRIVER_NVIDIA_GEFORCE8,  2048},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX670,     "NVIDIA GeForce GTX 670",           DRIVER_NVIDIA_GEFORCE8,  2048},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX670MX,   "NVIDIA GeForce GTX 670MX",         DRIVER_NVIDIA_GEFORCE8,  3072},
1360
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX675MX,   "NVIDIA GeForce GTX 675MX",         DRIVER_NVIDIA_GEFORCE8,  4096},
1361
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX680,     "NVIDIA GeForce GTX 680",           DRIVER_NVIDIA_GEFORCE8,  2048},
1362
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX690,     "NVIDIA GeForce GTX 690",           DRIVER_NVIDIA_GEFORCE8,  2048},
1363
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT730,      "NVIDIA GeForce GT 730",            DRIVER_NVIDIA_GEFORCE8,  2048},
1364
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT730M,     "NVIDIA GeForce GT 730M",           DRIVER_NVIDIA_GEFORCE8,  1024},
1365
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT740M,     "NVIDIA GeForce GT 740M",           DRIVER_NVIDIA_GEFORCE8,  2048},
1366
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT750M,     "NVIDIA GeForce GT 750M",           DRIVER_NVIDIA_GEFORCE8,  1024},
1367 1368
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX750,     "NVIDIA GeForce GTX 750",           DRIVER_NVIDIA_GEFORCE8,  1024},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX750TI,   "NVIDIA GeForce GTX 750 Ti",        DRIVER_NVIDIA_GEFORCE8,  2048},
1369 1370
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX760,     "NVIDIA GeForce GTX 760",           DRIVER_NVIDIA_GEFORCE8,  2048},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX760TI,   "NVIDIA GeForce GTX 760 Ti",        DRIVER_NVIDIA_GEFORCE8,  2048},
1371 1372 1373 1374 1375
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX765M,    "NVIDIA GeForce GTX 765M",          DRIVER_NVIDIA_GEFORCE8,  2048},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX770M,    "NVIDIA GeForce GTX 770M",          DRIVER_NVIDIA_GEFORCE8,  3072},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX770,     "NVIDIA GeForce GTX 770",           DRIVER_NVIDIA_GEFORCE8,  2048},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX780,     "NVIDIA GeForce GTX 780",           DRIVER_NVIDIA_GEFORCE8,  3072},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX780TI,   "NVIDIA GeForce GTX 780 Ti",        DRIVER_NVIDIA_GEFORCE8,  3072},
1376 1377 1378 1379
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTXTITAN,   "NVIDIA GeForce GTX TITAN",         DRIVER_NVIDIA_GEFORCE8,  6144},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTXTITANB,  "NVIDIA GeForce GTX TITAN Black",   DRIVER_NVIDIA_GEFORCE8,  6144},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTXTITANX,  "NVIDIA GeForce GTX TITAN X",       DRIVER_NVIDIA_GEFORCE8,  12288},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTXTITANZ,  "NVIDIA GeForce GTX TITAN Z",       DRIVER_NVIDIA_GEFORCE8,  12288},
1380
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_820M,       "NVIDIA GeForce 820M",              DRIVER_NVIDIA_GEFORCE8,  2048},
1381
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_830M,       "NVIDIA GeForce 830M",              DRIVER_NVIDIA_GEFORCE8,  2048},
1382
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_840M,       "NVIDIA GeForce 840M",              DRIVER_NVIDIA_GEFORCE8,  2048},
1383
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_845M,       "NVIDIA GeForce 845M",              DRIVER_NVIDIA_GEFORCE8,  2048},
1384
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX850M,    "NVIDIA GeForce GTX 850M",          DRIVER_NVIDIA_GEFORCE8,  2048},
1385
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX860M,    "NVIDIA GeForce GTX 860M",          DRIVER_NVIDIA_GEFORCE8,  2048},
1386
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX870M,    "NVIDIA GeForce GTX 870M",          DRIVER_NVIDIA_GEFORCE8,  3072},
1387
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX880M,    "NVIDIA GeForce GTX 880M",          DRIVER_NVIDIA_GEFORCE8,  4096},
1388
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_940M,       "NVIDIA GeForce 940M",              DRIVER_NVIDIA_GEFORCE8,  4096},
1389 1390 1391 1392
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX950,     "NVIDIA GeForce GTX 950",           DRIVER_NVIDIA_GEFORCE8,  2048},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX950M,    "NVIDIA GeForce GTX 950M",          DRIVER_NVIDIA_GEFORCE8,  4096},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX960,     "NVIDIA GeForce GTX 960",           DRIVER_NVIDIA_GEFORCE8,  4096},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX960M,    "NVIDIA GeForce GTX 960M",          DRIVER_NVIDIA_GEFORCE8,  2048},
1393
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX970,     "NVIDIA GeForce GTX 970",           DRIVER_NVIDIA_GEFORCE8,  4096},
1394
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX970M,    "NVIDIA GeForce GTX 970M",          DRIVER_NVIDIA_GEFORCE8,  3072},
1395
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX980,     "NVIDIA GeForce GTX 980",           DRIVER_NVIDIA_GEFORCE8,  4096},
1396
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX980TI,   "NVIDIA GeForce GTX 980 Ti",        DRIVER_NVIDIA_GEFORCE8,  6144},
1397
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX1050,    "NVIDIA GeForce GTX 1050",          DRIVER_NVIDIA_GEFORCE8,  2048},
1398
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX1050TI,  "NVIDIA GeForce GTX 1050 Ti",       DRIVER_NVIDIA_GEFORCE8,  4096},
1399 1400 1401
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX1060,    "NVIDIA GeForce GTX 1060",          DRIVER_NVIDIA_GEFORCE8,  6144},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX1070,    "NVIDIA GeForce GTX 1070",          DRIVER_NVIDIA_GEFORCE8,  8192},
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX1080,    "NVIDIA GeForce GTX 1080",          DRIVER_NVIDIA_GEFORCE8,  8192},
1402
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX1080TI,  "NVIDIA GeForce GTX 1080 Ti",       DRIVER_NVIDIA_GEFORCE8,  11264},
1403
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_TITANX_PASCAL,      "NVIDIA TITAN X (Pascal)",          DRIVER_NVIDIA_GEFORCE8,  12288},
1404

1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416
    /* AMD cards */
    {HW_VENDOR_AMD,        CARD_AMD_RAGE_128PRO,           "ATI Rage Fury",                    DRIVER_AMD_RAGE_128PRO,  16  },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_7200,           "ATI RADEON 7200 SERIES",           DRIVER_AMD_R100,         32  },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_8500,           "ATI RADEON 8500 SERIES",           DRIVER_AMD_R100,         64  },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_9500,           "ATI Radeon 9500",                  DRIVER_AMD_R300,         64  },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_XPRESS_200M,    "ATI RADEON XPRESS 200M Series",    DRIVER_AMD_R300,         64  },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_X700,           "ATI Radeon X700 SE",               DRIVER_AMD_R300,         128 },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_X1600,          "ATI Radeon X1600 Series",          DRIVER_AMD_R300,         128 },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD2350,         "ATI Mobility Radeon HD 2350",      DRIVER_AMD_R600,         256 },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD2600,         "ATI Mobility Radeon HD 2600",      DRIVER_AMD_R600,         256 },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD2900,         "ATI Radeon HD 2900 XT",            DRIVER_AMD_R600,         512 },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD3200,         "ATI Radeon HD 3200 Graphics",      DRIVER_AMD_R600,         128 },
1417
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD3850,         "ATI Radeon HD 3850 AGP",           DRIVER_AMD_R600,         512 },
1418
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD4200M,        "ATI Mobility Radeon HD 4200",      DRIVER_AMD_R600,         256 },
1419 1420 1421 1422 1423 1424 1425 1426 1427
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD4350,         "ATI Radeon HD 4350",               DRIVER_AMD_R600,         256 },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD4600,         "ATI Radeon HD 4600 Series",        DRIVER_AMD_R600,         512 },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD4700,         "ATI Radeon HD 4700 Series",        DRIVER_AMD_R600,         512 },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD4800,         "ATI Radeon HD 4800 Series",        DRIVER_AMD_R600,         512 },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD5400,         "ATI Radeon HD 5400 Series",        DRIVER_AMD_R600,         512 },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD5600,         "ATI Radeon HD 5600 Series",        DRIVER_AMD_R600,         512 },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD5700,         "ATI Radeon HD 5700 Series",        DRIVER_AMD_R600,         512 },
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD5800,         "ATI Radeon HD 5800 Series",        DRIVER_AMD_R600,         1024},
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD5900,         "ATI Radeon HD 5900 Series",        DRIVER_AMD_R600,         1024},
1428 1429
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6300,         "AMD Radeon HD 6300 series Graphics", DRIVER_AMD_R600,       1024},
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6400,         "AMD Radeon HD 6400 Series",        DRIVER_AMD_R600,         1024},
1430
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6410D,        "AMD Radeon HD 6410D",              DRIVER_AMD_R600,         1024},
1431
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6480G,        "AMD Radeon HD 6480G",              DRIVER_AMD_R600,         512 },
1432
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6550D,        "AMD Radeon HD 6550D",              DRIVER_AMD_R600,         1024},
1433
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6600,         "AMD Radeon HD 6600 Series",        DRIVER_AMD_R600,         1024},
1434
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6600M,        "AMD Radeon HD 6600M Series",       DRIVER_AMD_R600,         512 },
1435
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6700,         "AMD Radeon HD 6700 Series",        DRIVER_AMD_R600,         1024},
1436 1437
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6800,         "AMD Radeon HD 6800 Series",        DRIVER_AMD_R600,         1024},
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6900,         "AMD Radeon HD 6900 Series",        DRIVER_AMD_R600,         2048},
1438
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD7660D,        "AMD Radeon HD 7660D",              DRIVER_AMD_R600,         2048},
1439 1440
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD7700,         "AMD Radeon HD 7700 Series",        DRIVER_AMD_R600,         1024},
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD7800,         "AMD Radeon HD 7800 Series",        DRIVER_AMD_R600,         2048},
1441
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD7900,         "AMD Radeon HD 7900 Series",        DRIVER_AMD_R600,         2048},
1442 1443 1444 1445 1446
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD8600M,        "AMD Radeon HD 8600M Series",       DRIVER_AMD_R600,         1024},
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD8670,         "AMD Radeon HD 8670",               DRIVER_AMD_R600,         2048},
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD8770,         "AMD Radeon HD 8770",               DRIVER_AMD_R600,         2048},
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_R3,             "AMD Radeon HD 8400 / R3 Series",   DRIVER_AMD_R600,         2048},
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_R7,             "AMD Radeon(TM) R7 Graphics",       DRIVER_AMD_R600,         2048},
1447 1448
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_R9_285,         "AMD Radeon R9 285",                DRIVER_AMD_RX,           2048},
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_R9_290,         "AMD Radeon R9 290",                DRIVER_AMD_RX,           4096},
1449
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_R9_FURY,        "AMD Radeon (TM) R9 Fury Series",   DRIVER_AMD_RX,           4096},
1450 1451
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_RX_460,         "Radeon(TM) RX 460 Graphics",       DRIVER_AMD_RX,           4096},
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_RX_480,         "Radeon (TM) RX 480 Graphics",      DRIVER_AMD_RX,           4096},
1452 1453 1454 1455

    /* VMware */
    {HW_VENDOR_VMWARE,     CARD_VMWARE_SVGA3D,             "VMware SVGA 3D (Microsoft Corporation - WDDM)",             DRIVER_VMWARE,        1024},

1456
    /* Intel cards */
1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482
    {HW_VENDOR_INTEL,      CARD_INTEL_830M,                "Intel(R) 82830M Graphics Controller",                       DRIVER_INTEL_GMA800,  32 },
    {HW_VENDOR_INTEL,      CARD_INTEL_855GM,               "Intel(R) 82852/82855 GM/GME Graphics Controller",           DRIVER_INTEL_GMA800,  32 },
    {HW_VENDOR_INTEL,      CARD_INTEL_845G,                "Intel(R) 845G",                                             DRIVER_INTEL_GMA800,  32 },
    {HW_VENDOR_INTEL,      CARD_INTEL_865G,                "Intel(R) 82865G Graphics Controller",                       DRIVER_INTEL_GMA800,  32 },
    {HW_VENDOR_INTEL,      CARD_INTEL_915G,                "Intel(R) 82915G/GV/910GL Express Chipset Family",           DRIVER_INTEL_GMA900,  64 },
    {HW_VENDOR_INTEL,      CARD_INTEL_E7221G,              "Intel(R) E7221G",                                           DRIVER_INTEL_GMA900,  64 },
    {HW_VENDOR_INTEL,      CARD_INTEL_915GM,               "Mobile Intel(R) 915GM/GMS,910GML Express Chipset Family",   DRIVER_INTEL_GMA900,  64 },
    {HW_VENDOR_INTEL,      CARD_INTEL_945G,                "Intel(R) 945G",                                             DRIVER_INTEL_GMA950,  64 },
    {HW_VENDOR_INTEL,      CARD_INTEL_945GM,               "Mobile Intel(R) 945GM Express Chipset Family",              DRIVER_INTEL_GMA950,  64 },
    {HW_VENDOR_INTEL,      CARD_INTEL_945GME,              "Intel(R) 945GME",                                           DRIVER_INTEL_GMA950,  64 },
    {HW_VENDOR_INTEL,      CARD_INTEL_Q35,                 "Intel(R) Q35",                                              DRIVER_INTEL_GMA950,  64 },
    {HW_VENDOR_INTEL,      CARD_INTEL_G33,                 "Intel(R) G33",                                              DRIVER_INTEL_GMA950,  64 },
    {HW_VENDOR_INTEL,      CARD_INTEL_Q33,                 "Intel(R) Q33",                                              DRIVER_INTEL_GMA950,  64 },
    {HW_VENDOR_INTEL,      CARD_INTEL_PNVG,                "Intel(R) IGD",                                              DRIVER_INTEL_GMA950,  64 },
    {HW_VENDOR_INTEL,      CARD_INTEL_PNVM,                "Intel(R) IGD",                                              DRIVER_INTEL_GMA950,  64 },
    {HW_VENDOR_INTEL,      CARD_INTEL_965Q,                "Intel(R) 965Q",                                             DRIVER_INTEL_GMA3000, 128},
    {HW_VENDOR_INTEL,      CARD_INTEL_965G,                "Intel(R) 965G",                                             DRIVER_INTEL_GMA3000, 128},
    {HW_VENDOR_INTEL,      CARD_INTEL_946GZ,               "Intel(R) 946GZ",                                            DRIVER_INTEL_GMA3000, 128},
    {HW_VENDOR_INTEL,      CARD_INTEL_965GM,               "Mobile Intel(R) 965 Express Chipset Family",                DRIVER_INTEL_GMA3000, 128},
    {HW_VENDOR_INTEL,      CARD_INTEL_965GME,              "Intel(R) 965GME",                                           DRIVER_INTEL_GMA3000, 128},
    {HW_VENDOR_INTEL,      CARD_INTEL_GM45,                "Mobile Intel(R) GM45 Express Chipset Family",               DRIVER_INTEL_GMA3000, 512},
    {HW_VENDOR_INTEL,      CARD_INTEL_IGD,                 "Intel(R) Integrated Graphics Device",                       DRIVER_INTEL_GMA3000, 512},
    {HW_VENDOR_INTEL,      CARD_INTEL_G45,                 "Intel(R) G45/G43",                                          DRIVER_INTEL_GMA3000, 512},
    {HW_VENDOR_INTEL,      CARD_INTEL_Q45,                 "Intel(R) Q45/Q43",                                          DRIVER_INTEL_GMA3000, 512},
    {HW_VENDOR_INTEL,      CARD_INTEL_G41,                 "Intel(R) G41",                                              DRIVER_INTEL_GMA3000, 512},
    {HW_VENDOR_INTEL,      CARD_INTEL_B43,                 "Intel(R) B43",                                              DRIVER_INTEL_GMA3000, 512},
1483 1484 1485 1486 1487 1488 1489 1490
    {HW_VENDOR_INTEL,      CARD_INTEL_ILKD,                "Intel(R) HD Graphics",                                      DRIVER_INTEL_GMA3000, 1536},
    {HW_VENDOR_INTEL,      CARD_INTEL_ILKM,                "Intel(R) HD Graphics",                                      DRIVER_INTEL_GMA3000, 1536},
    {HW_VENDOR_INTEL,      CARD_INTEL_SNBD,                "Intel(R) HD Graphics 3000",                                 DRIVER_INTEL_GMA3000, 1536},
    {HW_VENDOR_INTEL,      CARD_INTEL_SNBM,                "Intel(R) HD Graphics 3000",                                 DRIVER_INTEL_GMA3000, 1536},
    {HW_VENDOR_INTEL,      CARD_INTEL_SNBS,                "Intel(R) HD Graphics Family",                               DRIVER_INTEL_GMA3000, 1536},
    {HW_VENDOR_INTEL,      CARD_INTEL_IVBD,                "Intel(R) HD Graphics 4000",                                 DRIVER_INTEL_HD4000,  1536},
    {HW_VENDOR_INTEL,      CARD_INTEL_IVBM,                "Intel(R) HD Graphics 4000",                                 DRIVER_INTEL_HD4000,  1536},
    {HW_VENDOR_INTEL,      CARD_INTEL_IVBS,                "Intel(R) HD Graphics Family",                               DRIVER_INTEL_HD4000,  1536},
1491
    {HW_VENDOR_INTEL,      CARD_INTEL_HWD,                 "Intel(R) HD Graphics 4600",                                 DRIVER_INTEL_HD4000,  1536},
1492
    {HW_VENDOR_INTEL,      CARD_INTEL_HWM,                 "Intel(R) HD Graphics 4600",                                 DRIVER_INTEL_HD4000,  1536},
1493
    {HW_VENDOR_INTEL,      CARD_INTEL_HD5000,              "Intel(R) HD Graphics 5000",                                 DRIVER_INTEL_HD4000,  1536},
1494 1495 1496 1497 1498 1499 1500 1501 1502
    {HW_VENDOR_INTEL,      CARD_INTEL_I5100_1,             "Intel(R) Iris(TM) Graphics 5100",                           DRIVER_INTEL_HD4000,  1536},
    {HW_VENDOR_INTEL,      CARD_INTEL_I5100_2,             "Intel(R) Iris(TM) Graphics 5100",                           DRIVER_INTEL_HD4000,  1536},
    {HW_VENDOR_INTEL,      CARD_INTEL_I5100_3,             "Intel(R) Iris(TM) Graphics 5100",                           DRIVER_INTEL_HD4000,  1536},
    {HW_VENDOR_INTEL,      CARD_INTEL_I5100_4,             "Intel(R) Iris(TM) Graphics 5100",                           DRIVER_INTEL_HD4000,  1536},
    {HW_VENDOR_INTEL,      CARD_INTEL_IP5200_1,            "Intel(R) Iris(TM) Pro Graphics 5200",                       DRIVER_INTEL_HD4000,  1536},
    {HW_VENDOR_INTEL,      CARD_INTEL_IP5200_2,            "Intel(R) Iris(TM) Pro Graphics 5200",                       DRIVER_INTEL_HD4000,  1536},
    {HW_VENDOR_INTEL,      CARD_INTEL_IP5200_3,            "Intel(R) Iris(TM) Pro Graphics 5200",                       DRIVER_INTEL_HD4000,  1536},
    {HW_VENDOR_INTEL,      CARD_INTEL_IP5200_4,            "Intel(R) Iris(TM) Pro Graphics 5200",                       DRIVER_INTEL_HD4000,  1536},
    {HW_VENDOR_INTEL,      CARD_INTEL_IP5200_5,            "Intel(R) Iris(TM) Pro Graphics 5200",                       DRIVER_INTEL_HD4000,  1536},
1503 1504 1505 1506 1507
    {HW_VENDOR_INTEL,      CARD_INTEL_HD5300,              "Intel(R) HD Graphics 5300",                                 DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_HD5500,              "Intel(R) HD Graphics 5500",                                 DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_HD5600,              "Intel(R) HD Graphics 5600",                                 DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_HD6000,              "Intel(R) HD Graphics 6000",                                 DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_I6100,               "Intel(R) Iris(TM) Graphics 6100",                           DRIVER_INTEL_HD4000,  2048},
1508
    {HW_VENDOR_INTEL,      CARD_INTEL_IP6200,              "Intel(R) Iris(TM) Pro Graphics 6200",                       DRIVER_INTEL_HD4000,  2048},
1509
    {HW_VENDOR_INTEL,      CARD_INTEL_IPP6300,             "Intel(R) Iris(TM) Pro Graphics P6300",                      DRIVER_INTEL_HD4000,  2048},
1510 1511 1512 1513 1514 1515
    {HW_VENDOR_INTEL,      CARD_INTEL_HD510_1,             "Intel(R) HD Graphics 510",                                  DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_HD510_2,             "Intel(R) HD Graphics 510",                                  DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_HD510_3,             "Intel(R) HD Graphics 510",                                  DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_HD515,               "Intel(R) HD Graphics 515",                                  DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_HD520_1,             "Intel(R) HD Graphics 520",                                  DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_HD520_2,             "Intel(R) HD Graphics 520",                                  DRIVER_INTEL_HD4000,  2048},
1516 1517
    {HW_VENDOR_INTEL,      CARD_INTEL_HD530_1,             "Intel(R) HD Graphics 530",                                  DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_HD530_2,             "Intel(R) HD Graphics 530",                                  DRIVER_INTEL_HD4000,  2048},
1518 1519 1520 1521 1522 1523 1524 1525 1526
    {HW_VENDOR_INTEL,      CARD_INTEL_HDP530,              "Intel(R) HD Graphics P530",                                 DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_I540,                "Intel(R) Iris(TM) Graphics 540",                            DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_I550,                "Intel(R) Iris(TM) Graphics 550",                            DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_I555,                "Intel(R) Iris(TM) Graphics 555",                            DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_IP555,               "Intel(R) Iris(TM) Graphics P555",                           DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_IP580_1,             "Intel(R) Iris(TM) Pro Graphics 580",                        DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_IP580_2,             "Intel(R) Iris(TM) Pro Graphics 580",                        DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_IPP580_1,            "Intel(R) Iris(TM) Pro Graphics P580",                       DRIVER_INTEL_HD4000,  2048},
    {HW_VENDOR_INTEL,      CARD_INTEL_IPP580_2,            "Intel(R) Iris(TM) Pro Graphics P580",                       DRIVER_INTEL_HD4000,  2048},
1527 1528
};

1529 1530 1531 1532 1533 1534
static const struct driver_version_information *get_driver_version_info(enum wined3d_display_driver driver,
        enum wined3d_driver_model driver_model)
{
    unsigned int i;

    TRACE("Looking up version info for driver=%d driver_model=%d\n", driver, driver_model);
1535
    for (i = 0; i < ARRAY_SIZE(driver_version_table); ++i)
1536 1537 1538
    {
        const struct driver_version_information *entry = &driver_version_table[i];

1539 1540
        if (entry->driver == driver && (driver_model == DRIVER_MODEL_GENERIC
                || entry->driver_model == driver_model))
1541
        {
1542 1543
            TRACE("Found driver \"%s\", version %u, subversion %u, build %u.\n",
                    entry->driver_name, entry->version, entry->subversion, entry->build);
1544 1545 1546 1547 1548 1549
            return entry;
        }
    }
    return NULL;
}

1550 1551 1552 1553 1554
static const struct gpu_description *get_gpu_description(enum wined3d_pci_vendor vendor,
        enum wined3d_pci_device device)
{
    unsigned int i;

1555
    for (i = 0; i < ARRAY_SIZE(gpu_description_table); ++i)
1556 1557 1558 1559 1560 1561 1562 1563
    {
        if (vendor == gpu_description_table[i].vendor && device == gpu_description_table[i].card)
            return &gpu_description_table[i];
    }

    return NULL;
}

1564
static const struct gpu_description *query_gpu_description(const struct wined3d_gl_info *gl_info, UINT64 *vram_bytes)
1565
{
1566 1567 1568 1569
    enum wined3d_pci_vendor vendor = PCI_VENDOR_NONE;
    enum wined3d_pci_device device = PCI_DEVICE_NONE;
    const struct gpu_description *gpu_description;
    static unsigned int once;
1570

1571
    if (gl_info->supported[WGL_WINE_QUERY_RENDERER])
1572
    {
1573
        GLuint value;
1574

1575 1576 1577 1578 1579 1580 1581 1582 1583
        if (GL_EXTCALL(wglQueryCurrentRendererIntegerWINE(WGL_RENDERER_VENDOR_ID_WINE, &value)))
            vendor = value;
        if (GL_EXTCALL(wglQueryCurrentRendererIntegerWINE(WGL_RENDERER_DEVICE_ID_WINE, &value)))
            device = value;
        if (GL_EXTCALL(wglQueryCurrentRendererIntegerWINE(WGL_RENDERER_VIDEO_MEMORY_WINE, &value)))
            *vram_bytes = (UINT64)value * 1024 * 1024;
        TRACE("Card reports vendor PCI ID 0x%04x, device PCI ID 0x%04x, 0x%s bytes of video memory.\n",
                vendor, device, wine_dbgstr_longlong(*vram_bytes));
    }
1584

1585 1586 1587 1588 1589
    if (wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
    {
        vendor = wined3d_settings.pci_vendor_id;
        TRACE("Overriding vendor PCI ID with 0x%04x.\n", vendor);
    }
1590

1591 1592 1593
    if (wined3d_settings.pci_device_id != PCI_DEVICE_NONE)
    {
        device = wined3d_settings.pci_device_id;
1594
        TRACE("Overriding device PCI ID with 0x%04x.\n", device);
1595
    }
1596

1597 1598 1599 1600 1601
    if (wined3d_settings.emulated_textureram)
    {
        *vram_bytes = wined3d_settings.emulated_textureram;
        TRACE("Overriding amount of video memory with 0x%s bytes.\n",
                wine_dbgstr_longlong(*vram_bytes));
1602 1603
    }

1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619
    if (!(gpu_description = get_gpu_description(vendor, device))
            && (wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE
            || wined3d_settings.pci_device_id != PCI_DEVICE_NONE) && !once++)
        ERR_(winediag)("Invalid GPU override %04x:%04x specified, ignoring.\n", vendor, device);

    return gpu_description;
}

static void init_driver_info(struct wined3d_driver_info *driver_info,
        const struct gpu_description *gpu_desc, UINT64 vram_bytes)
{
    OSVERSIONINFOW os_version;
    WORD driver_os_version;
    enum wined3d_display_driver driver;
    enum wined3d_driver_model driver_model;
    const struct driver_version_information *version_info;
1620

1621 1622 1623 1624 1625 1626
    memset(&os_version, 0, sizeof(os_version));
    os_version.dwOSVersionInfoSize = sizeof(os_version);
    if (!GetVersionExW(&os_version))
    {
        ERR("Failed to get OS version, reporting 2000/XP.\n");
        driver_os_version = 6;
1627
        driver_model = DRIVER_MODEL_NT5X;
1628 1629 1630 1631 1632 1633 1634
    }
    else
    {
        TRACE("OS version %u.%u.\n", os_version.dwMajorVersion, os_version.dwMinorVersion);
        switch (os_version.dwMajorVersion)
        {
            case 4:
1635 1636 1637
                /* If needed we could distinguish between 9x and NT4, but this code won't make
                 * sense for NT4 since it had no way to obtain this info through DirectDraw 3.0.
                 */
1638
                driver_os_version = 4;
1639
                driver_model = DRIVER_MODEL_WIN9X;
1640 1641 1642 1643
                break;

            case 5:
                driver_os_version = 6;
1644
                driver_model = DRIVER_MODEL_NT5X;
1645 1646 1647 1648 1649 1650
                break;

            case 6:
                if (os_version.dwMinorVersion == 0)
                {
                    driver_os_version = 7;
1651
                    driver_model = DRIVER_MODEL_NT6X;
1652
                }
1653 1654 1655 1656 1657
                else if (os_version.dwMinorVersion == 1)
                {
                    driver_os_version = 8;
                    driver_model = DRIVER_MODEL_NT6X;
                }
1658 1659
                else
                {
1660
                    if (os_version.dwMinorVersion > 2)
1661
                    {
1662
                        FIXME("Unhandled OS version %u.%u, reporting Win 8.\n",
1663 1664
                                os_version.dwMajorVersion, os_version.dwMinorVersion);
                    }
1665
                    driver_os_version = 9;
1666
                    driver_model = DRIVER_MODEL_NT6X;
1667 1668 1669
                }
                break;

1670 1671 1672 1673 1674
            case 10:
                driver_os_version = 10;
                driver_model = DRIVER_MODEL_NT6X;
                break;

1675 1676 1677 1678
            default:
                FIXME("Unhandled OS version %u.%u, reporting 2000/XP.\n",
                        os_version.dwMajorVersion, os_version.dwMinorVersion);
                driver_os_version = 6;
1679
                driver_model = DRIVER_MODEL_NT5X;
1680 1681 1682 1683
                break;
        }
    }

1684 1685 1686 1687 1688
    driver_info->vendor = gpu_desc->vendor;
    driver_info->device = gpu_desc->card;
    driver_info->description = gpu_desc->description;
    driver_info->vram_bytes = vram_bytes ? vram_bytes : (UINT64)gpu_desc->vidmem * 1024 * 1024;
    driver = gpu_desc->driver;
1689

1690 1691 1692 1693 1694
    /**
     * Diablo 2 crashes when the amount of video memory is greater than 0x7fffffff.
     * In order to avoid this application bug we limit the amount of video memory
     * to LONG_MAX for older Windows versions.
     */
1695
    if (driver_model < DRIVER_MODEL_NT6X && driver_info->vram_bytes > LONG_MAX)
1696 1697 1698 1699 1700
    {
        TRACE("Limiting amount of video memory to %#lx bytes for OS version older than Vista.\n", LONG_MAX);
        driver_info->vram_bytes = LONG_MAX;
    }

1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713
    /* Try to obtain driver version information for the current Windows version. This fails in
     * some cases:
     * - the gpu is not available on the currently selected OS version:
     *   - Geforce GTX480 on Win98. When running applications in compatibility mode on Windows,
     *     version information for the current Windows version is returned instead of faked info.
     *     We do the same and assume the default Windows version to emulate is WinXP.
     *
     *   - Videocard is a Riva TNT but winver is set to win7 (there are no drivers for this beast)
     *     For now return the XP driver info. Perhaps later on we should return VESA.
     *
     * - the gpu is not in our database (can happen when the user overrides the vendor_id / device_id)
     *   This could be an indication that our database is not up to date, so this should be fixed.
     */
1714
    if ((version_info = get_driver_version_info(driver, driver_model))
1715
            || (version_info = get_driver_version_info(driver, DRIVER_MODEL_GENERIC)))
1716 1717 1718 1719 1720 1721 1722
    {
        driver_info->name = version_info->driver_name;
        driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, version_info->version);
        driver_info->version_low = MAKEDWORD_VERSION(version_info->subversion, version_info->build);
    }
    else
    {
1723
        ERR("No driver version info found for device %04x:%04x, driver model %#x.\n",
1724
                driver_info->vendor, driver_info->device, driver_model);
1725 1726 1727
        driver_info->name = "Display";
        driver_info->version_high = MAKEDWORD_VERSION(driver_os_version, 15);
        driver_info->version_low = MAKEDWORD_VERSION(8, 6); /* Nvidia RIVA TNT, arbitrary */
1728 1729
    }

1730
    TRACE("Reporting (fake) driver version 0x%08x-0x%08x.\n",
1731 1732 1733
            driver_info->version_high, driver_info->version_low);
}

1734
/* Context activation is done by the caller. */
1735 1736 1737
static void fixup_extensions(struct wined3d_gl_info *gl_info, struct wined3d_caps_gl_ctx *ctx,
        const char *gl_renderer, enum wined3d_gl_vendor gl_vendor,
        enum wined3d_pci_vendor card_vendor, enum wined3d_pci_device device)
1738 1739 1740
{
    unsigned int i;

1741
    for (i = 0; i < ARRAY_SIZE(quirk_table); ++i)
1742
    {
1743
        if (!quirk_table[i].match(gl_info, ctx, gl_renderer, gl_vendor, card_vendor, device)) continue;
1744
        TRACE("Applying driver quirk \"%s\".\n", quirk_table[i].description);
1745 1746 1747 1748 1749 1750 1751
        quirk_table[i].apply(gl_info);
    }

    /* Find out if PBOs work as they are supposed to. */
    test_pbo_functionality(gl_info);
}

1752 1753 1754 1755 1756 1757
static DWORD wined3d_parse_gl_version(const char *gl_version)
{
    const char *ptr = gl_version;
    int major, minor;

    major = atoi(ptr);
1758 1759
    if (major <= 0)
        ERR("Invalid OpenGL major version %d.\n", major);
1760 1761

    while (isdigit(*ptr)) ++ptr;
1762 1763
    if (*ptr++ != '.')
        ERR("Invalid OpenGL version string %s.\n", debugstr_a(gl_version));
1764 1765 1766

    minor = atoi(ptr);

1767
    TRACE("Found OpenGL version %d.%d.\n", major, minor);
1768 1769 1770 1771

    return MAKEDWORD_VERSION(major, minor);
}

1772
static enum wined3d_gl_vendor wined3d_guess_gl_vendor(const struct wined3d_gl_info *gl_info,
1773
        const char *gl_vendor_string, const char *gl_renderer, const char *gl_version)
1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785
{
    /* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
     * the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
     * detect the Apple OpenGL implementation to apply some extension fixups afterwards.
     *
     * Detecting this isn't really easy. The vendor string doesn't mention Apple. Compile-time checks
     * aren't sufficient either because a Linux binary may display on a macos X server via remote X11.
     * So try to detect the GL implementation by looking at certain Apple extensions. Some extensions
     * like client storage might be supported on other implementations too, but GL_APPLE_flush_render
     * is specific to the Mac OS X window management, and GL_APPLE_ycbcr_422 is QuickTime specific. So
     * the chance that other implementations support them is rather small since Win32 QuickTime uses
     * DirectDraw, not OpenGL. */
1786
    if (gl_info->supported[APPLE_FENCE] && gl_info->supported[APPLE_YCBCR_422])
1787 1788 1789 1790 1791 1792
        return GL_VENDOR_APPLE;

    if (strstr(gl_vendor_string, "NVIDIA"))
        return GL_VENDOR_NVIDIA;

    if (strstr(gl_vendor_string, "ATI"))
1793
        return GL_VENDOR_FGLRX;
1794 1795

    if (strstr(gl_vendor_string, "Mesa")
1796
            || strstr(gl_vendor_string, "X.Org")
1797
            || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
1798 1799 1800
            || strstr(gl_vendor_string, "DRI R300 Project")
            || strstr(gl_vendor_string, "Tungsten Graphics, Inc")
            || strstr(gl_vendor_string, "VMware, Inc.")
1801
            || strstr(gl_vendor_string, "Intel")
1802
            || strstr(gl_renderer, "Mesa")
1803
            || strstr(gl_renderer, "Gallium")
1804 1805
            || strstr(gl_renderer, "Intel")
            || strstr(gl_version, "Mesa"))
1806 1807
        return GL_VENDOR_MESA;

1808
    FIXME("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_UNKNOWN.\n",
1809
            debugstr_a(gl_vendor_string));
1810

1811
    return GL_VENDOR_UNKNOWN;
1812 1813
}

1814
static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_string, const char *gl_renderer)
1815
{
1816
    if (strstr(gl_vendor_string, "NVIDIA")
1817
            || strstr(gl_vendor_string, "Nouveau")
1818
            || strstr(gl_vendor_string, "nouveau"))
1819
        return HW_VENDOR_NVIDIA;
1820

1821
    if (strstr(gl_vendor_string, "ATI")
1822
            || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
1823
            || strstr(gl_vendor_string, "X.Org R300 Project")
1824
            || strstr(gl_renderer, "AMD")
1825 1826
            || strstr(gl_renderer, "FirePro")
            || strstr(gl_renderer, "Radeon")
1827 1828 1829 1830 1831
            || strstr(gl_renderer, "R100")
            || strstr(gl_renderer, "R200")
            || strstr(gl_renderer, "R300")
            || strstr(gl_renderer, "R600")
            || strstr(gl_renderer, "R700"))
1832
        return HW_VENDOR_AMD;
1833

1834
    if (strstr(gl_vendor_string, "Intel(R)")
1835 1836
            /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */
            || strstr(gl_renderer, "Intel")
1837
            || strstr(gl_renderer, "i915")
1838 1839
            || strstr(gl_vendor_string, "Intel Inc."))
        return HW_VENDOR_INTEL;
1840

1841 1842 1843
    if (strstr(gl_renderer, "SVGA3D"))
        return HW_VENDOR_VMWARE;

1844
    if (strstr(gl_vendor_string, "Mesa")
1845
            || strstr(gl_vendor_string, "Brian Paul")
1846 1847
            || strstr(gl_vendor_string, "Tungsten Graphics, Inc")
            || strstr(gl_vendor_string, "VMware, Inc."))
1848
        return HW_VENDOR_SOFTWARE;
1849

1850
    FIXME("Received unrecognized GL_VENDOR %s. Returning HW_VENDOR_NVIDIA.\n", debugstr_a(gl_vendor_string));
1851

1852
    return HW_VENDOR_NVIDIA;
1853 1854
}

1855
static enum wined3d_d3d_level d3d_level_from_caps(const struct shader_caps *shader_caps, const struct fragment_caps *fragment_caps, DWORD glsl_version)
1856
{
1857
    if (shader_caps->vs_version >= 5)
1858
        return WINED3D_D3D_LEVEL_11;
1859
    if (shader_caps->vs_version == 4)
1860
        return WINED3D_D3D_LEVEL_10;
1861
    if (shader_caps->vs_version == 3)
1862
    {
1863 1864 1865 1866
        /* wined3d with default settings at the moment doesn't expose SM4+ on
         * Mesa drivers. */
        if (glsl_version >= MAKEDWORD_VERSION(4, 30))
            return WINED3D_D3D_LEVEL_11;
1867
        if (glsl_version >= MAKEDWORD_VERSION(1, 30))
1868 1869 1870
            return WINED3D_D3D_LEVEL_10;
        return WINED3D_D3D_LEVEL_9_SM3;
    }
1871
    if (shader_caps->vs_version == 2)
1872
        return WINED3D_D3D_LEVEL_9_SM2;
1873
    if (shader_caps->vs_version == 1)
1874 1875
        return WINED3D_D3D_LEVEL_8;

1876
    if (fragment_caps->TextureOpCaps & WINED3DTEXOPCAPS_DOTPRODUCT3)
1877
        return WINED3D_D3D_LEVEL_7;
1878
    if (fragment_caps->MaxSimultaneousTextures > 1)
1879 1880 1881
        return WINED3D_D3D_LEVEL_6;

    return WINED3D_D3D_LEVEL_5;
1882
}
1883

1884
static const struct wined3d_renderer_table
1885
{
1886 1887
    const char *renderer;
    enum wined3d_pci_device id;
1888
}
1889 1890 1891
cards_nvidia_binary[] =
{
    /* Direct 3D 11 */
1892
    {"TITAN X (Pascal)",            CARD_NVIDIA_TITANX_PASCAL},     /* GeForce 1000 - highend */
1893
    {"GTX 1080 Ti",                 CARD_NVIDIA_GEFORCE_GTX1080TI}, /* GeForce 1000 - highend */
1894 1895 1896
    {"GTX 1080",                    CARD_NVIDIA_GEFORCE_GTX1080},   /* GeForce 1000 - highend */
    {"GTX 1070",                    CARD_NVIDIA_GEFORCE_GTX1070},   /* GeForce 1000 - highend */
    {"GTX 1060",                    CARD_NVIDIA_GEFORCE_GTX1060},   /* GeForce 1000 - midend high */
1897
    {"GTX 1050 Ti",                 CARD_NVIDIA_GEFORCE_GTX1050TI}, /* GeForce 1000 - midend */
1898
    {"GTX 1050",                    CARD_NVIDIA_GEFORCE_GTX1050},   /* GeForce 1000 - midend */
1899
    {"GTX 980 Ti",                  CARD_NVIDIA_GEFORCE_GTX980TI},  /* GeForce 900 - highend */
1900
    {"GTX 980",                     CARD_NVIDIA_GEFORCE_GTX980},    /* GeForce 900 - highend */
1901
    {"GTX 970M",                    CARD_NVIDIA_GEFORCE_GTX970M},   /* GeForce 900 - highend mobile*/
1902
    {"GTX 970",                     CARD_NVIDIA_GEFORCE_GTX970},    /* GeForce 900 - highend */
1903
    {"GTX TITAN X",                 CARD_NVIDIA_GEFORCE_GTXTITANX}, /* Geforce 900 - highend */
1904 1905 1906 1907
    {"GTX 960M",                    CARD_NVIDIA_GEFORCE_GTX960M},   /* GeForce 900 - midend high mobile */
    {"GTX 960",                     CARD_NVIDIA_GEFORCE_GTX960},    /* GeForce 900 - midend high */
    {"GTX 950M",                    CARD_NVIDIA_GEFORCE_GTX950M},   /* GeForce 900 - midend mobile */
    {"GTX 950",                     CARD_NVIDIA_GEFORCE_GTX950},    /* GeForce 900 - midend */
1908
    {"GeForce 940M",                CARD_NVIDIA_GEFORCE_940M},      /* GeForce 900 - midend mobile */
1909
    {"GTX 880M",                    CARD_NVIDIA_GEFORCE_GTX880M},   /* GeForce 800 - mobile */
1910
    {"GTX 870M",                    CARD_NVIDIA_GEFORCE_GTX870M},   /* GeForce 800 - mobile */
1911
    {"GTX 860M",                    CARD_NVIDIA_GEFORCE_GTX860M},   /* GeForce 800 - mobile */
1912
    {"GTX 850M",                    CARD_NVIDIA_GEFORCE_GTX850M},   /* GeForce 800 - mobile */
1913
    {"GeForce 845M",                CARD_NVIDIA_GEFORCE_845M},      /* GeForce 800 - mobile */
1914
    {"GeForce 840M",                CARD_NVIDIA_GEFORCE_840M},      /* GeForce 800 - mobile */
1915
    {"GeForce 830M",                CARD_NVIDIA_GEFORCE_830M},      /* GeForce 800 - mobile */
1916
    {"GeForce 820M",                CARD_NVIDIA_GEFORCE_820M},      /* GeForce 800 - mobile */
1917
    {"GTX 780 Ti",                  CARD_NVIDIA_GEFORCE_GTX780TI},  /* Geforce 700 - highend */
1918 1919 1920
    {"GTX TITAN Black",             CARD_NVIDIA_GEFORCE_GTXTITANB}, /* Geforce 700 - highend */
    {"GTX TITAN Z",                 CARD_NVIDIA_GEFORCE_GTXTITANZ}, /* Geforce 700 - highend */
    {"GTX TITAN",                   CARD_NVIDIA_GEFORCE_GTXTITAN},  /* Geforce 700 - highend */
1921 1922 1923 1924
    {"GTX 780",                     CARD_NVIDIA_GEFORCE_GTX780},    /* Geforce 700 - highend */
    {"GTX 770M",                    CARD_NVIDIA_GEFORCE_GTX770M},   /* Geforce 700 - midend high mobile */
    {"GTX 770",                     CARD_NVIDIA_GEFORCE_GTX770},    /* Geforce 700 - highend */
    {"GTX 765M",                    CARD_NVIDIA_GEFORCE_GTX765M},   /* Geforce 700 - midend high mobile */
1925
    {"GTX 760 Ti",                  CARD_NVIDIA_GEFORCE_GTX760TI},  /* Geforce 700 - midend high */
1926 1927 1928
    {"GTX 760",                     CARD_NVIDIA_GEFORCE_GTX760},    /* Geforce 700 - midend high  */
    {"GTX 750 Ti",                  CARD_NVIDIA_GEFORCE_GTX750TI},  /* Geforce 700 - midend */
    {"GTX 750",                     CARD_NVIDIA_GEFORCE_GTX750},    /* Geforce 700 - midend */
1929
    {"GT 750M",                     CARD_NVIDIA_GEFORCE_GT750M},    /* Geforce 700 - midend mobile */
1930
    {"GT 740M",                     CARD_NVIDIA_GEFORCE_GT740M},    /* Geforce 700 - midend mobile */
1931
    {"GT 730M",                     CARD_NVIDIA_GEFORCE_GT730M},    /* Geforce 700 - midend mobile */
1932
    {"GT 730",                      CARD_NVIDIA_GEFORCE_GT730},     /* Geforce 700 - lowend */
1933
    {"GTX 690",                     CARD_NVIDIA_GEFORCE_GTX690},    /* Geforce 600 - highend */
1934
    {"GTX 680",                     CARD_NVIDIA_GEFORCE_GTX680},    /* Geforce 600 - highend */
1935
    {"GTX 675MX",                   CARD_NVIDIA_GEFORCE_GTX675MX},  /* Geforce 600 - highend */
1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950
    {"GTX 670MX",                   CARD_NVIDIA_GEFORCE_GTX670MX},  /* Geforce 600 - highend */
    {"GTX 670",                     CARD_NVIDIA_GEFORCE_GTX670},    /* Geforce 600 - midend high */
    {"GTX 660 Ti",                  CARD_NVIDIA_GEFORCE_GTX660TI},  /* Geforce 600 - midend high */
    {"GTX 660M",                    CARD_NVIDIA_GEFORCE_GTX660M},   /* Geforce 600 - midend high mobile */
    {"GTX 660",                     CARD_NVIDIA_GEFORCE_GTX660},    /* Geforce 600 - midend high */
    {"GTX 650 Ti",                  CARD_NVIDIA_GEFORCE_GTX650TI},  /* Geforce 600 - lowend */
    {"GTX 650",                     CARD_NVIDIA_GEFORCE_GTX650},    /* Geforce 600 - lowend */
    {"GT 650M",                     CARD_NVIDIA_GEFORCE_GT650M},    /* Geforce 600 - midend mobile */
    {"GT 640M",                     CARD_NVIDIA_GEFORCE_GT640M},    /* Geforce 600 - midend mobile */
    {"GT 630M",                     CARD_NVIDIA_GEFORCE_GT630M},    /* Geforce 600 - midend mobile */
    {"GT 630",                      CARD_NVIDIA_GEFORCE_GT630},     /* Geforce 600 - lowend */
    {"GT 610",                      CARD_NVIDIA_GEFORCE_GT610},     /* Geforce 600 - lowend */
    {"GTX 580",                     CARD_NVIDIA_GEFORCE_GTX580},    /* Geforce 500 - highend */
    {"GTX 570",                     CARD_NVIDIA_GEFORCE_GTX570},    /* Geforce 500 - midend high */
    {"GTX 560 Ti",                  CARD_NVIDIA_GEFORCE_GTX560TI},  /* Geforce 500 - midend */
1951
    {"GTX 560M",                    CARD_NVIDIA_GEFORCE_GTX560M},   /* Geforce 500 - midend mobile */
1952 1953 1954 1955
    {"GTX 560",                     CARD_NVIDIA_GEFORCE_GTX560},    /* Geforce 500 - midend */
    {"GT 555M",                     CARD_NVIDIA_GEFORCE_GT555M},    /* Geforce 500 - midend mobile */
    {"GTX 550 Ti",                  CARD_NVIDIA_GEFORCE_GTX550},    /* Geforce 500 - midend */
    {"GT 540M",                     CARD_NVIDIA_GEFORCE_GT540M},    /* Geforce 500 - midend mobile */
1956
    {"GT 525M",                     CARD_NVIDIA_GEFORCE_GT525M},    /* Geforce 500 - lowend mobile */
1957 1958 1959 1960 1961 1962 1963 1964 1965 1966
    {"GT 520",                      CARD_NVIDIA_GEFORCE_GT520},     /* Geforce 500 - lowend */
    {"GTX 480",                     CARD_NVIDIA_GEFORCE_GTX480},    /* Geforce 400 - highend */
    {"GTX 470",                     CARD_NVIDIA_GEFORCE_GTX470},    /* Geforce 400 - midend high */
    /* Direct 3D 10 */
    {"GTX 465",                     CARD_NVIDIA_GEFORCE_GTX465},    /* Geforce 400 - midend */
    {"GTX 460M",                    CARD_NVIDIA_GEFORCE_GTX460M},   /* Geforce 400 - highend mobile */
    {"GTX 460",                     CARD_NVIDIA_GEFORCE_GTX460},    /* Geforce 400 - midend */
    {"GTS 450",                     CARD_NVIDIA_GEFORCE_GTS450},    /* Geforce 400 - midend low */
    {"GT 440",                      CARD_NVIDIA_GEFORCE_GT440},     /* Geforce 400 - lowend */
    {"GT 430",                      CARD_NVIDIA_GEFORCE_GT430},     /* Geforce 400 - lowend */
1967
    {"GT 425M",                     CARD_NVIDIA_GEFORCE_GT425M},    /* Geforce 400 - lowend mobile */
1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982
    {"GT 420",                      CARD_NVIDIA_GEFORCE_GT420},     /* Geforce 400 - lowend */
    {"410M",                        CARD_NVIDIA_GEFORCE_410M},      /* Geforce 400 - lowend mobile */
    {"GT 330",                      CARD_NVIDIA_GEFORCE_GT330},     /* Geforce 300 - highend */
    {"GTS 360M",                    CARD_NVIDIA_GEFORCE_GTS350M},   /* Geforce 300 - highend mobile */
    {"GTS 350M",                    CARD_NVIDIA_GEFORCE_GTS350M},   /* Geforce 300 - highend mobile */
    {"GT 330M",                     CARD_NVIDIA_GEFORCE_GT325M},    /* Geforce 300 - midend mobile */
    {"GT 325M",                     CARD_NVIDIA_GEFORCE_GT325M},    /* Geforce 300 - midend mobile */
    {"GT 320M",                     CARD_NVIDIA_GEFORCE_GT320M},    /* Geforce 300 - midend mobile */
    {"320M",                        CARD_NVIDIA_GEFORCE_320M},      /* Geforce 300 - midend mobile */
    {"315M",                        CARD_NVIDIA_GEFORCE_315M},      /* Geforce 300 - midend mobile */
    {"GTX 295",                     CARD_NVIDIA_GEFORCE_GTX280},    /* Geforce 200 - highend */
    {"GTX 285",                     CARD_NVIDIA_GEFORCE_GTX280},    /* Geforce 200 - highend */
    {"GTX 280",                     CARD_NVIDIA_GEFORCE_GTX280},    /* Geforce 200 - highend */
    {"GTX 275",                     CARD_NVIDIA_GEFORCE_GTX275},    /* Geforce 200 - midend high */
    {"GTX 260",                     CARD_NVIDIA_GEFORCE_GTX260},    /* Geforce 200 - midend */
1983
    {"GTS 250",                     CARD_NVIDIA_GEFORCE_GTS250},    /* Geforce 200 - midend */
1984 1985 1986 1987 1988 1989 1990 1991
    {"GT 240",                      CARD_NVIDIA_GEFORCE_GT240},     /* Geforce 200 - midend */
    {"GT 220",                      CARD_NVIDIA_GEFORCE_GT220},     /* Geforce 200 - lowend */
    {"GeForce 310",                 CARD_NVIDIA_GEFORCE_210},       /* Geforce 200 - lowend */
    {"GeForce 305",                 CARD_NVIDIA_GEFORCE_210},       /* Geforce 200 - lowend */
    {"GeForce 210",                 CARD_NVIDIA_GEFORCE_210},       /* Geforce 200 - lowend */
    {"G 210",                       CARD_NVIDIA_GEFORCE_210},       /* Geforce 200 - lowend */
    {"GTS 150",                     CARD_NVIDIA_GEFORCE_9800GT},    /* Geforce 9 - highend / Geforce 200 - midend */
    {"9800",                        CARD_NVIDIA_GEFORCE_9800GT},    /* Geforce 9 - highend / Geforce 200 - midend */
1992
    {"9700M GT",                    CARD_NVIDIA_GEFORCE_9700MGT},   /* Geforce 9 - midend */
1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009
    {"GT 140",                      CARD_NVIDIA_GEFORCE_9600GT},    /* Geforce 9 - midend */
    {"9600",                        CARD_NVIDIA_GEFORCE_9600GT},    /* Geforce 9 - midend */
    {"GT 130",                      CARD_NVIDIA_GEFORCE_9500GT},    /* Geforce 9 - midend low / Geforce 200 - low */
    {"GT 120",                      CARD_NVIDIA_GEFORCE_9500GT},    /* Geforce 9 - midend low / Geforce 200 - low */
    {"9500",                        CARD_NVIDIA_GEFORCE_9500GT},    /* Geforce 9 - midend low / Geforce 200 - low */
    {"9400M",                       CARD_NVIDIA_GEFORCE_9400M},     /* Geforce 9 - lowend */
    {"9400",                        CARD_NVIDIA_GEFORCE_9400GT},    /* Geforce 9 - lowend */
    {"9300",                        CARD_NVIDIA_GEFORCE_9300},      /* Geforce 9 - lowend low */
    {"9200",                        CARD_NVIDIA_GEFORCE_9200},      /* Geforce 9 - lowend low */
    {"9100",                        CARD_NVIDIA_GEFORCE_9200},      /* Geforce 9 - lowend low */
    {"G 100",                       CARD_NVIDIA_GEFORCE_9200},      /* Geforce 9 - lowend low */
    {"8800 GTX",                    CARD_NVIDIA_GEFORCE_8800GTX},   /* Geforce 8 - highend high */
    {"8800",                        CARD_NVIDIA_GEFORCE_8800GTS},   /* Geforce 8 - highend */
    {"8600M",                       CARD_NVIDIA_GEFORCE_8600MGT},   /* Geforce 8 - midend mobile */
    {"8600 M",                      CARD_NVIDIA_GEFORCE_8600MGT},   /* Geforce 8 - midend mobile */
    {"8700",                        CARD_NVIDIA_GEFORCE_8600GT},    /* Geforce 8 - midend */
    {"8600",                        CARD_NVIDIA_GEFORCE_8600GT},    /* Geforce 8 - midend */
2010
    {"8500",                        CARD_NVIDIA_GEFORCE_8500GT},    /* Geforce 8 - mid-lowend */
2011 2012
    {"8400",                        CARD_NVIDIA_GEFORCE_8400GS},    /* Geforce 8 - mid-lowend */
    {"8300",                        CARD_NVIDIA_GEFORCE_8300GS},    /* Geforce 8 - lowend */
2013 2014
    {"8200",                        CARD_NVIDIA_GEFORCE_8200},      /* Geforce 8 - lowend */
    {"8100",                        CARD_NVIDIA_GEFORCE_8200},      /* Geforce 8 - lowend */
2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060
    /* Direct 3D 9 SM3 */
    {"Quadro FX 5",                 CARD_NVIDIA_GEFORCE_7800GT},    /* Geforce 7 - highend */
    {"Quadro FX 4",                 CARD_NVIDIA_GEFORCE_7800GT},    /* Geforce 7 - highend */
    {"7950",                        CARD_NVIDIA_GEFORCE_7800GT},    /* Geforce 7 - highend */
    {"7900",                        CARD_NVIDIA_GEFORCE_7800GT},    /* Geforce 7 - highend */
    {"7800",                        CARD_NVIDIA_GEFORCE_7800GT},    /* Geforce 7 - highend */
    {"7700",                        CARD_NVIDIA_GEFORCE_7600},      /* Geforce 7 - midend */
    {"7600",                        CARD_NVIDIA_GEFORCE_7600},      /* Geforce 7 - midend */
    {"7400",                        CARD_NVIDIA_GEFORCE_7400},      /* Geforce 7 - lower medium */
    {"7300",                        CARD_NVIDIA_GEFORCE_7300},      /* Geforce 7 - lowend */
    {"6800",                        CARD_NVIDIA_GEFORCE_6800},      /* Geforce 6 - highend */
    {"6700",                        CARD_NVIDIA_GEFORCE_6600GT},    /* Geforce 6 - midend */
    {"6610",                        CARD_NVIDIA_GEFORCE_6600GT},    /* Geforce 6 - midend */
    {"6600",                        CARD_NVIDIA_GEFORCE_6600GT},    /* Geforce 6 - midend */
    /* Direct 3D 9 SM2 */
    {"Quadro FX",                   CARD_NVIDIA_GEFORCEFX_5800},    /* GeforceFX - highend */
    {"5950",                        CARD_NVIDIA_GEFORCEFX_5800},    /* GeforceFX - highend */
    {"5900",                        CARD_NVIDIA_GEFORCEFX_5800},    /* GeforceFX - highend */
    {"5800",                        CARD_NVIDIA_GEFORCEFX_5800},    /* GeforceFX - highend */
    {"5750",                        CARD_NVIDIA_GEFORCEFX_5600},    /* GeforceFX - midend */
    {"5700",                        CARD_NVIDIA_GEFORCEFX_5600},    /* GeforceFX - midend */
    {"5650",                        CARD_NVIDIA_GEFORCEFX_5600},    /* GeforceFX - midend */
    {"5600",                        CARD_NVIDIA_GEFORCEFX_5600},    /* GeforceFX - midend */
    {"5500",                        CARD_NVIDIA_GEFORCEFX_5200},    /* GeforceFX - lowend */
    {"5300",                        CARD_NVIDIA_GEFORCEFX_5200},    /* GeforceFX - lowend */
    {"5250",                        CARD_NVIDIA_GEFORCEFX_5200},    /* GeforceFX - lowend */
    {"5200",                        CARD_NVIDIA_GEFORCEFX_5200},    /* GeforceFX - lowend */
    {"5100",                        CARD_NVIDIA_GEFORCEFX_5200},    /* GeforceFX - lowend */
    /* Direct 3D 8 */
    {"Quadro4",                     CARD_NVIDIA_GEFORCE4_TI4200},
    {"GeForce4 Ti",                 CARD_NVIDIA_GEFORCE4_TI4200},   /* Geforce4 Ti4200/Ti4400/Ti4600/Ti4800 */
    /* Direct 3D 7 */
    {"GeForce4 MX",                 CARD_NVIDIA_GEFORCE4_MX},       /* MX420/MX440/MX460/MX4000 */
    {"Quadro2 MXR",                 CARD_NVIDIA_GEFORCE2_MX},
    {"GeForce2 MX",                 CARD_NVIDIA_GEFORCE2_MX},       /* Geforce2 standard/MX100/MX200/MX400 */
    {"Quadro2",                     CARD_NVIDIA_GEFORCE2},
    {"GeForce2",                    CARD_NVIDIA_GEFORCE2},          /* Geforce2 GTS/Pro/Ti/Ultra */
    /* Direct 3D 6 */
    {"TNT2",                        CARD_NVIDIA_RIVA_TNT2},         /* Riva TNT2 standard/M64/Pro/Ultra */
},
/* See http://developer.amd.com/resources/hardware-drivers/ati-catalyst-pc-vendor-id-1002-li/
 *
 * Beware: renderer string do not match exact card model,
 * eg HD 4800 is returned for multiple cards, even for RV790 based ones. */
cards_amd_binary[] =
{
2061
    {"RX 480",                      CARD_AMD_RADEON_RX_480},
2062
    {"RX 460",                      CARD_AMD_RADEON_RX_460},
2063
    {"R9 Fury Series",              CARD_AMD_RADEON_R9_FURY},
2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081
    /* Southern Islands */
    {"HD 7900",                     CARD_AMD_RADEON_HD7900},
    {"HD 7800",                     CARD_AMD_RADEON_HD7800},
    {"HD 7700",                     CARD_AMD_RADEON_HD7700},
    /* Northern Islands */
    {"HD 6970",                     CARD_AMD_RADEON_HD6900},
    {"HD 6900",                     CARD_AMD_RADEON_HD6900},
    {"HD 6800",                     CARD_AMD_RADEON_HD6800},
    {"HD 6770M",                    CARD_AMD_RADEON_HD6600M},
    {"HD 6750M",                    CARD_AMD_RADEON_HD6600M},
    {"HD 6700",                     CARD_AMD_RADEON_HD6700},
    {"HD 6670",                     CARD_AMD_RADEON_HD6600},
    {"HD 6630M",                    CARD_AMD_RADEON_HD6600M},
    {"HD 6600M",                    CARD_AMD_RADEON_HD6600M},
    {"HD 6600",                     CARD_AMD_RADEON_HD6600},
    {"HD 6570",                     CARD_AMD_RADEON_HD6600},
    {"HD 6500M",                    CARD_AMD_RADEON_HD6600M},
    {"HD 6500",                     CARD_AMD_RADEON_HD6600},
2082
    {"HD 6480G",                    CARD_AMD_RADEON_HD6480G},
2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152
    {"HD 6400",                     CARD_AMD_RADEON_HD6400},
    {"HD 6300",                     CARD_AMD_RADEON_HD6300},
    {"HD 6200",                     CARD_AMD_RADEON_HD6300},
    /* Evergreen */
    {"HD 5870",                     CARD_AMD_RADEON_HD5800},    /* Radeon EG CYPRESS PRO */
    {"HD 5850",                     CARD_AMD_RADEON_HD5800},    /* Radeon EG CYPRESS XT */
    {"HD 5800",                     CARD_AMD_RADEON_HD5800},    /* Radeon EG CYPRESS HD58xx generic renderer string */
    {"HD 5770",                     CARD_AMD_RADEON_HD5700},    /* Radeon EG JUNIPER XT */
    {"HD 5750",                     CARD_AMD_RADEON_HD5700},    /* Radeon EG JUNIPER LE */
    {"HD 5700",                     CARD_AMD_RADEON_HD5700},    /* Radeon EG JUNIPER HD57xx generic renderer string */
    {"HD 5670",                     CARD_AMD_RADEON_HD5600},    /* Radeon EG REDWOOD XT */
    {"HD 5570",                     CARD_AMD_RADEON_HD5600},    /* Radeon EG REDWOOD PRO mapped to HD5600 series */
    {"HD 5550",                     CARD_AMD_RADEON_HD5600},    /* Radeon EG REDWOOD LE mapped to HD5600 series */
    {"HD 5450",                     CARD_AMD_RADEON_HD5400},    /* Radeon EG CEDAR PRO */
    {"HD 5000",                     CARD_AMD_RADEON_HD5600},    /* Defaulting to HD 5600 */
    /* R700 */
    {"HD 4890",                     CARD_AMD_RADEON_HD4800},    /* Radeon RV790 */
    {"HD 4870",                     CARD_AMD_RADEON_HD4800},    /* Radeon RV770 */
    {"HD 4850",                     CARD_AMD_RADEON_HD4800},    /* Radeon RV770 */
    {"HD 4830",                     CARD_AMD_RADEON_HD4800},    /* Radeon RV770 */
    {"HD 4800",                     CARD_AMD_RADEON_HD4800},    /* Radeon RV7xx HD48xx generic renderer string */
    {"HD 4770",                     CARD_AMD_RADEON_HD4700},    /* Radeon RV740 */
    {"HD 4700",                     CARD_AMD_RADEON_HD4700},    /* Radeon RV7xx HD47xx generic renderer string */
    {"HD 4670",                     CARD_AMD_RADEON_HD4600},    /* Radeon RV730 */
    {"HD 4650",                     CARD_AMD_RADEON_HD4600},    /* Radeon RV730 */
    {"HD 4600",                     CARD_AMD_RADEON_HD4600},    /* Radeon RV730 */
    {"HD 4550",                     CARD_AMD_RADEON_HD4350},    /* Radeon RV710 */
    {"HD 4350",                     CARD_AMD_RADEON_HD4350},    /* Radeon RV710 */
    /* R600/R700 integrated */
    {"HD 4200M",                    CARD_AMD_RADEON_HD4200M},
    {"HD 3300",                     CARD_AMD_RADEON_HD3200},
    {"HD 3200",                     CARD_AMD_RADEON_HD3200},
    {"HD 3100",                     CARD_AMD_RADEON_HD3200},
    /* R600 */
    {"HD 3870",                     CARD_AMD_RADEON_HD2900},    /* HD2900/HD3800 - highend */
    {"HD 3850",                     CARD_AMD_RADEON_HD2900},    /* HD2900/HD3800 - highend */
    {"HD 2900",                     CARD_AMD_RADEON_HD2900},    /* HD2900/HD3800 - highend */
    {"HD 3830",                     CARD_AMD_RADEON_HD2600},    /* China-only midend */
    {"HD 3690",                     CARD_AMD_RADEON_HD2600},    /* HD2600/HD3600 - midend */
    {"HD 3650",                     CARD_AMD_RADEON_HD2600},    /* HD2600/HD3600 - midend */
    {"HD 2600",                     CARD_AMD_RADEON_HD2600},    /* HD2600/HD3600 - midend */
    {"HD 3470",                     CARD_AMD_RADEON_HD2350},    /* HD2350/HD2400/HD3400 - lowend */
    {"HD 3450",                     CARD_AMD_RADEON_HD2350},    /* HD2350/HD2400/HD3400 - lowend */
    {"HD 3430",                     CARD_AMD_RADEON_HD2350},    /* HD2350/HD2400/HD3400 - lowend */
    {"HD 3400",                     CARD_AMD_RADEON_HD2350},    /* HD2350/HD2400/HD3400 - lowend */
    {"HD 2400",                     CARD_AMD_RADEON_HD2350},    /* HD2350/HD2400/HD3400 - lowend */
    {"HD 2350",                     CARD_AMD_RADEON_HD2350},    /* HD2350/HD2400/HD3400 - lowend */
    /* Radeon R5xx */
    {"X1950",                       CARD_AMD_RADEON_X1600},
    {"X1900",                       CARD_AMD_RADEON_X1600},
    {"X1800",                       CARD_AMD_RADEON_X1600},
    {"X1650",                       CARD_AMD_RADEON_X1600},
    {"X1600",                       CARD_AMD_RADEON_X1600},
    /* Radeon R4xx + X1300/X1400/X1450/X1550/X2300/X2500/HD2300 (lowend R5xx)
     * Note X2300/X2500/HD2300 are R5xx GPUs with a 2xxx naming but they are still DX9-only */
    {"HD 2300",                     CARD_AMD_RADEON_X700},
    {"X2500",                       CARD_AMD_RADEON_X700},
    {"X2300",                       CARD_AMD_RADEON_X700},
    {"X1550",                       CARD_AMD_RADEON_X700},
    {"X1450",                       CARD_AMD_RADEON_X700},
    {"X1400",                       CARD_AMD_RADEON_X700},
    {"X1300",                       CARD_AMD_RADEON_X700},
    {"X850",                        CARD_AMD_RADEON_X700},
    {"X800",                        CARD_AMD_RADEON_X700},
    {"X700",                        CARD_AMD_RADEON_X700},
    /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400 MHz */
    {"Radeon Xpress",               CARD_AMD_RADEON_XPRESS_200M},
},
cards_intel[] =
{
2153
    /* Skylake */
2154 2155
    {"Iris Pro Graphics P580",      CARD_INTEL_IPP580_1},
    {"Skylake",                     CARD_INTEL_HD520_1},
2156
    /* Broadwell */
2157
    {"Iris Pro P6300",              CARD_INTEL_IPP6300},
2158
    {"Iris Pro 6200",               CARD_INTEL_IP6200},
2159 2160
    {"Iris 6100",                   CARD_INTEL_I6100},
    {"Iris(TM) Graphics 6100",      CARD_INTEL_I6100},  /* MacOS */
2161
    /* Haswell */
2162 2163
    {"Iris Pro 5200",               CARD_INTEL_IP5200_1},
    {"Iris 5100",                   CARD_INTEL_I5100_1},
2164
    {"HD Graphics 5000",            CARD_INTEL_HD5000}, /* MacOS */
2165
    {"Haswell Mobile",              CARD_INTEL_HWM},
2166
    {"Iris OpenGL Engine",          CARD_INTEL_HWM},    /* MacOS */
2167 2168 2169 2170
    /* Ivybridge */
    {"Ivybridge Server",            CARD_INTEL_IVBS},
    {"Ivybridge Mobile",            CARD_INTEL_IVBM},
    {"Ivybridge Desktop",           CARD_INTEL_IVBD},
2171
    {"HD Graphics 4000",            CARD_INTEL_IVBD},   /* MacOS */
2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214
    /* Sandybridge */
    {"Sandybridge Server",          CARD_INTEL_SNBS},
    {"Sandybridge Mobile",          CARD_INTEL_SNBM},
    {"Sandybridge Desktop",         CARD_INTEL_SNBD},
    /* Ironlake */
    {"Ironlake Mobile",             CARD_INTEL_ILKM},
    {"Ironlake Desktop",            CARD_INTEL_ILKD},
    /* G4x */
    {"B43",                         CARD_INTEL_B43},
    {"G41",                         CARD_INTEL_G41},
    {"G45",                         CARD_INTEL_G45},
    {"Q45",                         CARD_INTEL_Q45},
    {"Integrated Graphics Device",  CARD_INTEL_IGD},
    {"GM45",                        CARD_INTEL_GM45},
    /* i965 */
    {"965GME",                      CARD_INTEL_965GME},
    {"965GM",                       CARD_INTEL_965GM},
    {"X3100",                       CARD_INTEL_965GM},  /* MacOS */
    {"946GZ",                       CARD_INTEL_946GZ},
    {"965G",                        CARD_INTEL_965G},
    {"965Q",                        CARD_INTEL_965Q},
    /* i945 */
    {"Pineview M",                  CARD_INTEL_PNVM},
    {"Pineview G",                  CARD_INTEL_PNVG},
    {"IGD",                         CARD_INTEL_PNVG},
    {"Q33",                         CARD_INTEL_Q33},
    {"G33",                         CARD_INTEL_G33},
    {"Q35",                         CARD_INTEL_Q35},
    {"945GME",                      CARD_INTEL_945GME},
    {"945GM",                       CARD_INTEL_945GM},
    {"GMA 950",                     CARD_INTEL_945GM},  /* MacOS */
    {"945G",                        CARD_INTEL_945G},
    /* i915 */
    {"915GM",                       CARD_INTEL_915GM},
    {"E7221G",                      CARD_INTEL_E7221G},
    {"915G",                        CARD_INTEL_915G},
    /* i8xx */
    {"865G",                        CARD_INTEL_865G},
    {"845G",                        CARD_INTEL_845G},
    {"855GM",                       CARD_INTEL_855GM},
    {"830M",                        CARD_INTEL_830M},
},
/* 20101109 - These are never returned by current Gallium radeon
2215
 * drivers: R700, RV790, R680, RV535, RV516, R410, RS485, RV360, RV351. */
2216 2217
cards_amd_mesa[] =
{
2218 2219 2220
    /* Polaris 10/11 */
    {"POLARIS10",                   CARD_AMD_RADEON_RX_480},
    {"POLARIS11",                   CARD_AMD_RADEON_RX_460},
2221
    /* Volcanic Islands */
2222
    {"FIJI",                        CARD_AMD_RADEON_R9_FURY},
2223
    {"TONGA",                       CARD_AMD_RADEON_R9_285},
2224
    /* Sea Islands */
2225
    {"HAWAII",                      CARD_AMD_RADEON_R9_290},
2226 2227 2228
    {"KAVERI",                      CARD_AMD_RADEON_R7    },
    {"KABINI",                      CARD_AMD_RADEON_R3    },
    {"BONAIRE",                     CARD_AMD_RADEON_HD8770},
2229
    /* Southern Islands */
2230 2231
    {"OLAND",                       CARD_AMD_RADEON_HD8670},
    {"HAINAN",                      CARD_AMD_RADEON_HD8600M},
2232 2233 2234 2235
    {"TAHITI",                      CARD_AMD_RADEON_HD7900},
    {"PITCAIRN",                    CARD_AMD_RADEON_HD7800},
    {"CAPE VERDE",                  CARD_AMD_RADEON_HD7700},
    /* Northern Islands */
2236
    {"ARUBA",                       CARD_AMD_RADEON_HD7660D},
2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262
    {"CAYMAN",                      CARD_AMD_RADEON_HD6900},
    {"BARTS",                       CARD_AMD_RADEON_HD6800},
    {"TURKS",                       CARD_AMD_RADEON_HD6600},
    {"SUMO2",                       CARD_AMD_RADEON_HD6410D},   /* SUMO2 first, because we do a strstr(). */
    {"SUMO",                        CARD_AMD_RADEON_HD6550D},
    {"CAICOS",                      CARD_AMD_RADEON_HD6400},
    {"PALM",                        CARD_AMD_RADEON_HD6300},
    /* Evergreen */
    {"HEMLOCK",                     CARD_AMD_RADEON_HD5900},
    {"CYPRESS",                     CARD_AMD_RADEON_HD5800},
    {"JUNIPER",                     CARD_AMD_RADEON_HD5700},
    {"REDWOOD",                     CARD_AMD_RADEON_HD5600},
    {"CEDAR",                       CARD_AMD_RADEON_HD5400},
    /* R700 */
    {"R700",                        CARD_AMD_RADEON_HD4800},
    {"RV790",                       CARD_AMD_RADEON_HD4800},
    {"RV770",                       CARD_AMD_RADEON_HD4800},
    {"RV740",                       CARD_AMD_RADEON_HD4700},
    {"RV730",                       CARD_AMD_RADEON_HD4600},
    {"RV710",                       CARD_AMD_RADEON_HD4350},
    /* R600/R700 integrated */
    {"RS880",                       CARD_AMD_RADEON_HD4200M},
    {"RS780",                       CARD_AMD_RADEON_HD3200},
    /* R600 */
    {"R680",                        CARD_AMD_RADEON_HD2900},
    {"R600",                        CARD_AMD_RADEON_HD2900},
2263
    {"RV670",                       CARD_AMD_RADEON_HD3850},
2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292
    {"RV635",                       CARD_AMD_RADEON_HD2600},
    {"RV630",                       CARD_AMD_RADEON_HD2600},
    {"RV620",                       CARD_AMD_RADEON_HD2350},
    {"RV610",                       CARD_AMD_RADEON_HD2350},
    /* R500 */
    {"R580",                        CARD_AMD_RADEON_X1600},
    {"R520",                        CARD_AMD_RADEON_X1600},
    {"RV570",                       CARD_AMD_RADEON_X1600},
    {"RV560",                       CARD_AMD_RADEON_X1600},
    {"RV535",                       CARD_AMD_RADEON_X1600},
    {"RV530",                       CARD_AMD_RADEON_X1600},
    {"RV516",                       CARD_AMD_RADEON_X700},
    {"RV515",                       CARD_AMD_RADEON_X700},
    /* R400 */
    {"R481",                        CARD_AMD_RADEON_X700},
    {"R480",                        CARD_AMD_RADEON_X700},
    {"R430",                        CARD_AMD_RADEON_X700},
    {"R423",                        CARD_AMD_RADEON_X700},
    {"R420",                        CARD_AMD_RADEON_X700},
    {"R410",                        CARD_AMD_RADEON_X700},
    {"RV410",                       CARD_AMD_RADEON_X700},
    /* Radeon Xpress - onboard, DX9b, Shader 2.0, 300-400 MHz */
    {"RS740",                       CARD_AMD_RADEON_XPRESS_200M},
    {"RS690",                       CARD_AMD_RADEON_XPRESS_200M},
    {"RS600",                       CARD_AMD_RADEON_XPRESS_200M},
    {"RS485",                       CARD_AMD_RADEON_XPRESS_200M},
    {"RS482",                       CARD_AMD_RADEON_XPRESS_200M},
    {"RS480",                       CARD_AMD_RADEON_XPRESS_200M},
    {"RS400",                       CARD_AMD_RADEON_XPRESS_200M},
2293
    {"RC410",                       CARD_AMD_RADEON_XPRESS_200M},
2294 2295 2296 2297
    /* R300 */
    {"R360",                        CARD_AMD_RADEON_9500},
    {"R350",                        CARD_AMD_RADEON_9500},
    {"R300",                        CARD_AMD_RADEON_9500},
2298
    {"RV380",                       CARD_AMD_RADEON_9500},
2299 2300 2301 2302 2303 2304 2305 2306
    {"RV370",                       CARD_AMD_RADEON_9500},
    {"RV360",                       CARD_AMD_RADEON_9500},
    {"RV351",                       CARD_AMD_RADEON_9500},
    {"RV350",                       CARD_AMD_RADEON_9500},
},
cards_nvidia_mesa[] =
{
    /* Maxwell */
2307
    {"NV124",                       CARD_NVIDIA_GEFORCE_GTX970},
2308
    {"NV120",                       CARD_NVIDIA_GEFORCE_GTX980TI},
2309
    {"NV118",                       CARD_NVIDIA_GEFORCE_840M},
2310 2311
    {"NV117",                       CARD_NVIDIA_GEFORCE_GTX750},
    /* Kepler */
2312
    {"NV108",                       CARD_NVIDIA_GEFORCE_GT740M},
2313 2314 2315
    {"NVF1",                        CARD_NVIDIA_GEFORCE_GTX780TI},
    {"NVF0",                        CARD_NVIDIA_GEFORCE_GTX780},
    {"NVE6",                        CARD_NVIDIA_GEFORCE_GTX770M},
2316
    {"NVE4",                        CARD_NVIDIA_GEFORCE_GTX680},    /* 690 / 675MX / 760TI */
2317 2318
    /* Fermi */
    {"NVD9",                        CARD_NVIDIA_GEFORCE_GT520},
2319
    {"NVD7",                        CARD_NVIDIA_GEFORCE_820M},
2320 2321 2322 2323 2324 2325 2326 2327 2328 2329
    {"NVCF",                        CARD_NVIDIA_GEFORCE_GTX550},
    {"NVCE",                        CARD_NVIDIA_GEFORCE_GTX560},
    {"NVC8",                        CARD_NVIDIA_GEFORCE_GTX570},
    {"NVC4",                        CARD_NVIDIA_GEFORCE_GTX460},
    {"NVC3",                        CARD_NVIDIA_GEFORCE_GT440},
    {"NVC1",                        CARD_NVIDIA_GEFORCE_GT420},
    {"NVC0",                        CARD_NVIDIA_GEFORCE_GTX480},
    /* Tesla */
    {"NVAF",                        CARD_NVIDIA_GEFORCE_GT320M},
    {"NVAC",                        CARD_NVIDIA_GEFORCE_8200},
2330
    {"NVAA",                        CARD_NVIDIA_GEFORCE_8200},      /* 8100 */
2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384
    {"NVA8",                        CARD_NVIDIA_GEFORCE_210},
    {"NVA5",                        CARD_NVIDIA_GEFORCE_GT220},
    {"NVA3",                        CARD_NVIDIA_GEFORCE_GT240},
    {"NVA0",                        CARD_NVIDIA_GEFORCE_GTX280},
    {"NV98",                        CARD_NVIDIA_GEFORCE_9200},
    {"NV96",                        CARD_NVIDIA_GEFORCE_9400GT},
    {"NV94",                        CARD_NVIDIA_GEFORCE_9600GT},
    {"NV92",                        CARD_NVIDIA_GEFORCE_9800GT},
    {"NV86",                        CARD_NVIDIA_GEFORCE_8500GT},
    {"NV84",                        CARD_NVIDIA_GEFORCE_8600GT},
    {"NV50",                        CARD_NVIDIA_GEFORCE_8800GTX},
    /* Curie */
    {"NV68",                        CARD_NVIDIA_GEFORCE_6200},      /* 7050 */
    {"NV67",                        CARD_NVIDIA_GEFORCE_6200},      /* 7000M */
    {"NV63",                        CARD_NVIDIA_GEFORCE_6200},      /* 7100 */
    {"NV4E",                        CARD_NVIDIA_GEFORCE_6200},      /* 6100 Go / 6150 Go */
    {"NV4C",                        CARD_NVIDIA_GEFORCE_6200},      /* 6150SE */
    {"NV4B",                        CARD_NVIDIA_GEFORCE_7600},
    {"NV4A",                        CARD_NVIDIA_GEFORCE_6200},
    {"NV49",                        CARD_NVIDIA_GEFORCE_7800GT},    /* 7900 */
    {"NV47",                        CARD_NVIDIA_GEFORCE_7800GT},
    {"NV46",                        CARD_NVIDIA_GEFORCE_7400},
    {"NV45",                        CARD_NVIDIA_GEFORCE_6800},
    {"NV44",                        CARD_NVIDIA_GEFORCE_6200},
    {"NV43",                        CARD_NVIDIA_GEFORCE_6600GT},
    {"NV42",                        CARD_NVIDIA_GEFORCE_6800},
    {"NV41",                        CARD_NVIDIA_GEFORCE_6800},
    {"NV40",                        CARD_NVIDIA_GEFORCE_6800},
    /* Rankine */
    {"NV38",                        CARD_NVIDIA_GEFORCEFX_5800},    /* FX 5950 Ultra */
    {"NV36",                        CARD_NVIDIA_GEFORCEFX_5800},    /* FX 5700/5750 */
    {"NV35",                        CARD_NVIDIA_GEFORCEFX_5800},    /* FX 5900 */
    {"NV34",                        CARD_NVIDIA_GEFORCEFX_5200},
    {"NV31",                        CARD_NVIDIA_GEFORCEFX_5600},
    {"NV30",                        CARD_NVIDIA_GEFORCEFX_5800},
    /* Kelvin */
    {"nv28",                        CARD_NVIDIA_GEFORCE4_TI4200},
    {"nv25",                        CARD_NVIDIA_GEFORCE4_TI4200},
    {"nv20",                        CARD_NVIDIA_GEFORCE3},
    /* Celsius */
    {"nv1F",                        CARD_NVIDIA_GEFORCE4_MX},       /* GF4 MX IGP */
    {"nv1A",                        CARD_NVIDIA_GEFORCE2},          /* GF2 IGP */
    {"nv18",                        CARD_NVIDIA_GEFORCE4_MX},
    {"nv17",                        CARD_NVIDIA_GEFORCE4_MX},
    {"nv16",                        CARD_NVIDIA_GEFORCE2},
    {"nv15",                        CARD_NVIDIA_GEFORCE2},
    {"nv11",                        CARD_NVIDIA_GEFORCE2_MX},
    {"nv10",                        CARD_NVIDIA_GEFORCE},
    /* Fahrenheit */
    {"nv05",                        CARD_NVIDIA_RIVA_TNT2},
    {"nv04",                        CARD_NVIDIA_RIVA_TNT},
    {"nv03",                        CARD_NVIDIA_RIVA_128},
},
cards_vmware[] =
2385
{
2386 2387
    {"SVGA3D",                      CARD_VMWARE_SVGA3D},
};
2388

2389 2390 2391 2392
static const struct gl_vendor_selection
{
    enum wined3d_gl_vendor gl_vendor;
    const char *description;        /* Description of the card selector i.e. Apple OS/X Intel */
2393 2394
    const struct wined3d_renderer_table *cards; /* To be used as cards[], pointer to the first member in an array */
    size_t cards_size;              /* Number of entries in the array above */
2395
}
2396 2397
amd_gl_vendor_table[] =
{
2398 2399 2400
    {GL_VENDOR_APPLE,   "Apple OSX AMD/ATI binary driver",  cards_amd_binary,       ARRAY_SIZE(cards_amd_binary)},
    {GL_VENDOR_FGLRX,   "AMD/ATI binary driver",            cards_amd_binary,       ARRAY_SIZE(cards_amd_binary)},
    {GL_VENDOR_MESA,    "Mesa AMD/ATI driver",              cards_amd_mesa,         ARRAY_SIZE(cards_amd_mesa)},
2401
},
2402 2403
nvidia_gl_vendor_table[] =
{
2404 2405 2406
    {GL_VENDOR_APPLE,   "Apple OSX NVidia binary driver",   cards_nvidia_binary,    ARRAY_SIZE(cards_nvidia_binary)},
    {GL_VENDOR_MESA,    "Mesa Nouveau driver",              cards_nvidia_mesa,      ARRAY_SIZE(cards_nvidia_mesa)},
    {GL_VENDOR_NVIDIA,  "Nvidia binary driver",             cards_nvidia_binary,    ARRAY_SIZE(cards_nvidia_binary)},
2407
},
2408
vmware_gl_vendor_table[] =
2409
{
2410
    {GL_VENDOR_MESA,    "VMware driver",                    cards_vmware,           ARRAY_SIZE(cards_vmware)},
2411 2412 2413
},
intel_gl_vendor_table[] =
{
2414 2415
    {GL_VENDOR_APPLE,   "Apple OSX Intel binary driver",    cards_intel,            ARRAY_SIZE(cards_intel)},
    {GL_VENDOR_MESA,    "Mesa Intel driver",                cards_intel,            ARRAY_SIZE(cards_intel)},
2416
};
2417

2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442
static const enum wined3d_pci_device
card_fallback_nvidia[] =
{
    CARD_NVIDIA_RIVA_128,           /* D3D5 */
    CARD_NVIDIA_RIVA_TNT,           /* D3D6 */
    CARD_NVIDIA_GEFORCE,            /* D3D7 */
    CARD_NVIDIA_GEFORCE3,           /* D3D8 */
    CARD_NVIDIA_GEFORCEFX_5800,     /* D3D9_SM2 */
    CARD_NVIDIA_GEFORCE_6800,       /* D3D9_SM3 */
    CARD_NVIDIA_GEFORCE_8800GTX,    /* D3D10 */
    CARD_NVIDIA_GEFORCE_GTX470,     /* D3D11 */
},
card_fallback_amd[] =
{
    CARD_AMD_RAGE_128PRO,           /* D3D5 */
    CARD_AMD_RAGE_128PRO,           /* D3D6 */
    CARD_AMD_RADEON_7200,           /* D3D7 */
    CARD_AMD_RADEON_8500,           /* D3D8 */
    CARD_AMD_RADEON_9500,           /* D3D9_SM2 */
    CARD_AMD_RADEON_X1600,          /* D3D9_SM3 */
    CARD_AMD_RADEON_HD2900,         /* D3D10 */
    CARD_AMD_RADEON_HD5600,         /* D3D11 */
},
card_fallback_intel[] =
{
2443 2444 2445
    CARD_INTEL_845G,                /* D3D5 */
    CARD_INTEL_845G,                /* D3D6 */
    CARD_INTEL_845G,                /* D3D7 */
2446 2447
    CARD_INTEL_915G,                /* D3D8 */
    CARD_INTEL_915G,                /* D3D9_SM2 */
2448
    CARD_INTEL_945G,                /* D3D9_SM3 */
2449 2450 2451 2452 2453 2454
    CARD_INTEL_G45,                 /* D3D10 */
    CARD_INTEL_IVBD,                /* D3D11 */
};
C_ASSERT(ARRAY_SIZE(card_fallback_nvidia)  == WINED3D_D3D_LEVEL_COUNT);
C_ASSERT(ARRAY_SIZE(card_fallback_amd)     == WINED3D_D3D_LEVEL_COUNT);
C_ASSERT(ARRAY_SIZE(card_fallback_intel)   == WINED3D_D3D_LEVEL_COUNT);
2455 2456

static enum wined3d_pci_device select_card_handler(const struct gl_vendor_selection *table,
2457
        unsigned int table_size, enum wined3d_gl_vendor gl_vendor, const char *gl_renderer)
2458
{
2459
    unsigned int i, j;
2460 2461 2462 2463 2464 2465 2466

    for (i = 0; i < table_size; ++i)
    {
        if (table[i].gl_vendor != gl_vendor)
            continue;

        TRACE("Applying card selector \"%s\".\n", table[i].description);
2467 2468 2469 2470 2471 2472 2473

        for (j = 0; j < table[i].cards_size; ++j)
        {
            if (strstr(gl_renderer, table[i].cards[j].renderer))
                return table[i].cards[j].id;
        }
        return PCI_DEVICE_NONE;
2474
    }
2475
    FIXME("Couldn't find a suitable card selector for GL vendor %04x (using GL_RENDERER %s)\n",
2476 2477 2478 2479 2480 2481
            gl_vendor, debugstr_a(gl_renderer));

    return PCI_DEVICE_NONE;
}

static const struct
2482 2483 2484
{
    enum wined3d_pci_vendor card_vendor;
    const char *description;        /* Description of the card selector i.e. Apple OS/X Intel */
2485 2486
    const struct gl_vendor_selection *gl_vendor_selection;
    unsigned int gl_vendor_count;
2487
    const enum wined3d_pci_device *card_fallback; /* An array with D3D_LEVEL_COUNT elements */
2488 2489 2490
}
card_vendor_table[] =
{
2491
    {HW_VENDOR_AMD,         "AMD",      amd_gl_vendor_table,
2492
            ARRAY_SIZE(amd_gl_vendor_table),
2493
            card_fallback_amd},
2494
    {HW_VENDOR_NVIDIA,      "Nvidia",   nvidia_gl_vendor_table,
2495
            ARRAY_SIZE(nvidia_gl_vendor_table),
2496
            card_fallback_nvidia},
2497
    {HW_VENDOR_VMWARE,      "VMware",   vmware_gl_vendor_table,
2498
            ARRAY_SIZE(vmware_gl_vendor_table),
2499
            card_fallback_amd},
2500
    {HW_VENDOR_INTEL,       "Intel",    intel_gl_vendor_table,
2501
            ARRAY_SIZE(intel_gl_vendor_table),
2502
            card_fallback_intel},
2503 2504 2505
};


2506 2507
static enum wined3d_pci_device wined3d_guess_card(const struct shader_caps *shader_caps, const struct fragment_caps *fragment_caps,
        DWORD glsl_version, const char *gl_renderer, enum wined3d_gl_vendor *gl_vendor, enum wined3d_pci_vendor *card_vendor)
2508
{
2509
    /* A Direct3D device object contains the PCI id (vendor + device) of the
2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543
     * videocard which is used for rendering. Various applications use this
     * information to get a rough estimation of the features of the card and
     * some might use it for enabling 3d effects only on certain types of
     * videocards. In some cases games might even use it to work around bugs
     * which happen on certain videocards/driver combinations. The problem is
     * that OpenGL only exposes a rendering string containing the name of the
     * videocard and not the PCI id.
     *
     * Various games depend on the PCI id, so somehow we need to provide one.
     * A simple option is to parse the renderer string and translate this to
     * the right PCI id. This is a lot of work because there are more than 200
     * GPUs just for Nvidia. Various cards share the same renderer string, so
     * the amount of code might be 'small' but there are quite a number of
     * exceptions which would make this a pain to maintain. Another way would
     * be to query the PCI id from the operating system (assuming this is the
     * videocard which is used for rendering which is not always the case).
     * This would work but it is not very portable. Second it would not work
     * well in, let's say, a remote X situation in which the amount of 3d
     * features which can be used is limited.
     *
     * As said most games only use the PCI id to get an indication of the
     * capabilities of the card. It doesn't really matter if the given id is
     * the correct one if we return the id of a card with similar 3d features.
     *
     * The code below checks the OpenGL capabilities of a videocard and matches
     * that to a certain level of Direct3D functionality. Once a card passes
     * the Direct3D9 check, we know that the card (in case of Nvidia) is at
     * least a GeforceFX. To give a better estimate we do a basic check on the
     * renderer string but if that won't pass we return a default card. This
     * way is better than maintaining a full card database as even without a
     * full database we can return a card with similar features. Second the
     * size of the database can be made quite small because when you know what
     * type of 3d functionality a card has, you know to which GPU family the
     * GPU must belong. Because of this you only have to check a small part of
2544
     * the renderer string to distinguish between different models from that
2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558
     * family.
     *
     * The code also selects a default amount of video memory which we will
     * use for an estimation of the amount of free texture memory. In case of
     * real D3D the amount of texture memory includes video memory and system
     * memory (to be specific AGP memory or in case of PCIE TurboCache /
     * HyperMemory). We don't know how much system memory can be addressed by
     * the system but we can make a reasonable estimation about the amount of
     * video memory. If the value is slightly wrong it doesn't matter as we
     * didn't include AGP-like memory which makes the amount of addressable
     * memory higher and second OpenGL isn't that critical it moves to system
     * memory behind our backs if really needed. Note that the amount of video
     * memory can be overruled using a registry setting. */

2559
    unsigned int i;
2560
    enum wined3d_d3d_level d3d_level = d3d_level_from_caps(shader_caps, fragment_caps, glsl_version);
2561
    enum wined3d_pci_device device;
2562

2563
    for (i = 0; i < ARRAY_SIZE(card_vendor_table); ++i)
2564
    {
2565
        if (card_vendor_table[i].card_vendor != *card_vendor)
2566
            continue;
2567 2568 2569

        TRACE("Applying card selector \"%s\".\n", card_vendor_table[i].description);
        device = select_card_handler(card_vendor_table[i].gl_vendor_selection,
2570
                card_vendor_table[i].gl_vendor_count, *gl_vendor, gl_renderer);
2571 2572 2573 2574
        if (device != PCI_DEVICE_NONE)
            return device;

        TRACE("Unrecognized renderer %s, falling back to default.\n", debugstr_a(gl_renderer));
2575
        return card_vendor_table[i].card_fallback[d3d_level];
2576
    }
2577

2578 2579
    FIXME("No card selector available for card vendor %04x (using GL_RENDERER %s).\n",
            *card_vendor, debugstr_a(gl_renderer));
2580

2581
    /* Default to generic Nvidia hardware based on the supported OpenGL extensions. */
2582
    *card_vendor = HW_VENDOR_NVIDIA;
2583
    return card_fallback_nvidia[d3d_level];
2584 2585
}

2586 2587 2588
static const struct wined3d_vertex_pipe_ops *select_vertex_implementation(const struct wined3d_gl_info *gl_info,
        const struct wined3d_shader_backend_ops *shader_backend_ops)
{
2589
    if (shader_backend_ops == &glsl_shader_backend && gl_info->supported[ARB_VERTEX_SHADER])
2590 2591 2592 2593
        return &glsl_vertex_pipe;
    return &ffp_vertex_pipe;
}

2594 2595
static const struct fragment_pipeline *select_fragment_implementation(const struct wined3d_gl_info *gl_info,
        const struct wined3d_shader_backend_ops *shader_backend_ops)
2596
{
2597
    if (shader_backend_ops == &glsl_shader_backend && gl_info->supported[ARB_FRAGMENT_SHADER])
2598
        return &glsl_fragment_pipe;
2599
    if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
2600
        return &arbfp_fragment_pipeline;
2601
    if (gl_info->supported[ATI_FRAGMENT_SHADER])
2602 2603 2604 2605 2606 2607
        return &atifs_fragment_pipeline;
    if (gl_info->supported[NV_REGISTER_COMBINERS] && gl_info->supported[NV_TEXTURE_SHADER2])
        return &nvts_fragment_pipeline;
    if (gl_info->supported[NV_REGISTER_COMBINERS])
        return &nvrc_fragment_pipeline;
    return &ffp_fragment_pipeline;
2608 2609
}

2610
static const struct wined3d_shader_backend_ops *select_shader_backend(const struct wined3d_gl_info *gl_info)
2611
{
2612
    BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
2613

2614
    if (glsl && gl_info->supported[ARB_VERTEX_SHADER] && gl_info->supported[ARB_FRAGMENT_SHADER])
2615
        return &glsl_shader_backend;
2616 2617 2618
    if (gl_info->supported[ARB_VERTEX_PROGRAM] && gl_info->supported[ARB_FRAGMENT_PROGRAM])
        return &arb_program_shader_backend;
    if (glsl && (gl_info->supported[ARB_VERTEX_SHADER] || gl_info->supported[ARB_FRAGMENT_SHADER]))
2619 2620 2621
        return &glsl_shader_backend;
    if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
        return &arb_program_shader_backend;
2622 2623 2624
    return &none_shader_backend;
}

2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643
static void parse_extension_string(struct wined3d_gl_info *gl_info, const char *extensions,
        const struct wined3d_extension_map *map, UINT entry_count)
{
    while (*extensions)
    {
        const char *start;
        size_t len;
        UINT i;

        while (isspace(*extensions))
            ++extensions;
        start = extensions;
        while (!isspace(*extensions) && *extensions)
            ++extensions;

        len = extensions - start;
        if (!len)
            continue;

2644
        TRACE("- %s.\n", debugstr_an(start, len));
2645 2646 2647 2648 2649 2650

        for (i = 0; i < entry_count; ++i)
        {
            if (len == strlen(map[i].extension_string)
                    && !memcmp(start, map[i].extension_string, len))
            {
2651
                TRACE(" FOUND: %s support.\n", map[i].extension_string);
2652 2653 2654 2655 2656 2657 2658
                gl_info->supported[map[i].extension] = TRUE;
                break;
            }
        }
    }
}

2659 2660 2661 2662 2663 2664 2665
static void enumerate_gl_extensions(struct wined3d_gl_info *gl_info,
        const struct wined3d_extension_map *map, unsigned int map_entries_count)
{
    const char *gl_extension_name;
    unsigned int i, j;
    GLint extensions_count;

2666
    gl_info->gl_ops.gl.p_glGetIntegerv(GL_NUM_EXTENSIONS, &extensions_count);
2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682
    for (i = 0; i < extensions_count; ++i)
    {
        gl_extension_name = (const char *)GL_EXTCALL(glGetStringi(GL_EXTENSIONS, i));
        TRACE("- %s.\n", debugstr_a(gl_extension_name));
        for (j = 0; j < map_entries_count; ++j)
        {
            if (!strcmp(gl_extension_name, map[j].extension_string))
            {
                TRACE("FOUND: %s support.\n", map[j].extension_string);
                gl_info->supported[map[j].extension] = TRUE;
                break;
            }
        }
    }
}

2683
static void load_gl_funcs(struct wined3d_gl_info *gl_info)
2684
{
2685
#define USE_GL_FUNC(pfn) gl_info->gl_ops.ext.p_##pfn = (void *)wglGetProcAddress(#pfn);
2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697
    /* GL_APPLE_fence */
    USE_GL_FUNC(glDeleteFencesAPPLE)
    USE_GL_FUNC(glFinishFenceAPPLE)
    USE_GL_FUNC(glFinishObjectAPPLE)
    USE_GL_FUNC(glGenFencesAPPLE)
    USE_GL_FUNC(glIsFenceAPPLE)
    USE_GL_FUNC(glSetFenceAPPLE)
    USE_GL_FUNC(glTestFenceAPPLE)
    USE_GL_FUNC(glTestObjectAPPLE)
    /* GL_APPLE_flush_buffer_range */
    USE_GL_FUNC(glBufferParameteriAPPLE)
    USE_GL_FUNC(glFlushMappedBufferRangeAPPLE)
2698 2699 2700
    /* GL_ARB_base_instance */
    USE_GL_FUNC(glDrawArraysInstancedBaseInstance)
    USE_GL_FUNC(glDrawElementsInstancedBaseVertexBaseInstance)
2701 2702 2703
    /* GL_ARB_blend_func_extended */
    USE_GL_FUNC(glBindFragDataLocationIndexed)
    USE_GL_FUNC(glGetFragDataIndex)
2704 2705 2706
    /* GL_ARB_clear_buffer_object */
    USE_GL_FUNC(glClearBufferData)
    USE_GL_FUNC(glClearBufferSubData)
2707 2708 2709
    /* GL_ARB_clear_texture */
    USE_GL_FUNC(glClearTexImage)
    USE_GL_FUNC(glClearTexSubImage)
2710 2711
    /* GL_ARB_clip_control */
    USE_GL_FUNC(glClipControl)
2712 2713
    /* GL_ARB_color_buffer_float */
    USE_GL_FUNC(glClampColorARB)
2714 2715 2716
    /* GL_ARB_compute_shader */
    USE_GL_FUNC(glDispatchCompute)
    USE_GL_FUNC(glDispatchComputeIndirect)
2717 2718
    /* GL_ARB_copy_buffer */
    USE_GL_FUNC(glCopyBufferSubData)
2719 2720
    /* GL_ARB_copy_image */
    USE_GL_FUNC(glCopyImageSubData)
2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732
    /* GL_ARB_debug_output */
    USE_GL_FUNC(glDebugMessageCallbackARB)
    USE_GL_FUNC(glDebugMessageControlARB)
    USE_GL_FUNC(glDebugMessageInsertARB)
    USE_GL_FUNC(glGetDebugMessageLogARB)
    /* GL_ARB_draw_buffers */
    USE_GL_FUNC(glDrawBuffersARB)
    /* GL_ARB_draw_elements_base_vertex */
    USE_GL_FUNC(glDrawElementsBaseVertex)
    USE_GL_FUNC(glDrawElementsInstancedBaseVertex)
    USE_GL_FUNC(glDrawRangeElementsBaseVertex)
    USE_GL_FUNC(glMultiDrawElementsBaseVertex)
2733 2734 2735
    /* GL_ARB_draw_indirect */
    USE_GL_FUNC(glDrawArraysIndirect)
    USE_GL_FUNC(glDrawElementsIndirect)
2736 2737 2738
    /* GL_ARB_draw_instanced */
    USE_GL_FUNC(glDrawArraysInstancedARB)
    USE_GL_FUNC(glDrawElementsInstancedARB)
2739 2740 2741 2742 2743 2744
    /* GL_ARB_ES2_compatibility */
    USE_GL_FUNC(glReleaseShaderCompiler)
    USE_GL_FUNC(glShaderBinary)
    USE_GL_FUNC(glGetShaderPrecisionFormat)
    USE_GL_FUNC(glDepthRangef)
    USE_GL_FUNC(glClearDepthf)
2745 2746
    /* GL_ARB_framebuffer_no_attachments */
    USE_GL_FUNC(glFramebufferParameteri)
2747 2748 2749 2750 2751 2752 2753 2754
    /* GL_ARB_framebuffer_object */
    USE_GL_FUNC(glBindFramebuffer)
    USE_GL_FUNC(glBindRenderbuffer)
    USE_GL_FUNC(glBlitFramebuffer)
    USE_GL_FUNC(glCheckFramebufferStatus)
    USE_GL_FUNC(glDeleteFramebuffers)
    USE_GL_FUNC(glDeleteRenderbuffers)
    USE_GL_FUNC(glFramebufferRenderbuffer)
2755
    USE_GL_FUNC(glFramebufferTexture)
2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811
    USE_GL_FUNC(glFramebufferTexture1D)
    USE_GL_FUNC(glFramebufferTexture2D)
    USE_GL_FUNC(glFramebufferTexture3D)
    USE_GL_FUNC(glFramebufferTextureLayer)
    USE_GL_FUNC(glGenFramebuffers)
    USE_GL_FUNC(glGenRenderbuffers)
    USE_GL_FUNC(glGenerateMipmap)
    USE_GL_FUNC(glGetFramebufferAttachmentParameteriv)
    USE_GL_FUNC(glGetRenderbufferParameteriv)
    USE_GL_FUNC(glIsFramebuffer)
    USE_GL_FUNC(glIsRenderbuffer)
    USE_GL_FUNC(glRenderbufferStorage)
    USE_GL_FUNC(glRenderbufferStorageMultisample)
    /* GL_ARB_geometry_shader4 */
    USE_GL_FUNC(glFramebufferTextureARB)
    USE_GL_FUNC(glFramebufferTextureFaceARB)
    USE_GL_FUNC(glFramebufferTextureLayerARB)
    USE_GL_FUNC(glProgramParameteriARB)
    /* GL_ARB_instanced_arrays */
    USE_GL_FUNC(glVertexAttribDivisorARB)
    /* GL_ARB_internalformat_query */
    USE_GL_FUNC(glGetInternalformativ)
    /* GL_ARB_internalformat_query2 */
    USE_GL_FUNC(glGetInternalformati64v)
    /* GL_ARB_map_buffer_range */
    USE_GL_FUNC(glFlushMappedBufferRange)
    USE_GL_FUNC(glMapBufferRange)
    /* GL_ARB_multisample */
    USE_GL_FUNC(glSampleCoverageARB)
    /* GL_ARB_multitexture */
    USE_GL_FUNC(glActiveTextureARB)
    USE_GL_FUNC(glClientActiveTextureARB)
    USE_GL_FUNC(glMultiTexCoord1fARB)
    USE_GL_FUNC(glMultiTexCoord1fvARB)
    USE_GL_FUNC(glMultiTexCoord2fARB)
    USE_GL_FUNC(glMultiTexCoord2fvARB)
    USE_GL_FUNC(glMultiTexCoord2svARB)
    USE_GL_FUNC(glMultiTexCoord3fARB)
    USE_GL_FUNC(glMultiTexCoord3fvARB)
    USE_GL_FUNC(glMultiTexCoord4fARB)
    USE_GL_FUNC(glMultiTexCoord4fvARB)
    USE_GL_FUNC(glMultiTexCoord4svARB)
    /* GL_ARB_occlusion_query */
    USE_GL_FUNC(glBeginQueryARB)
    USE_GL_FUNC(glDeleteQueriesARB)
    USE_GL_FUNC(glEndQueryARB)
    USE_GL_FUNC(glGenQueriesARB)
    USE_GL_FUNC(glGetQueryivARB)
    USE_GL_FUNC(glGetQueryObjectivARB)
    USE_GL_FUNC(glGetQueryObjectuivARB)
    USE_GL_FUNC(glIsQueryARB)
    /* GL_ARB_point_parameters */
    USE_GL_FUNC(glPointParameterfARB)
    USE_GL_FUNC(glPointParameterfvARB)
    /* GL_ARB_provoking_vertex */
    USE_GL_FUNC(glProvokingVertex)
2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826
    /* GL_ARB_sampler_objects */
    USE_GL_FUNC(glGenSamplers)
    USE_GL_FUNC(glDeleteSamplers)
    USE_GL_FUNC(glIsSampler)
    USE_GL_FUNC(glBindSampler)
    USE_GL_FUNC(glSamplerParameteri)
    USE_GL_FUNC(glSamplerParameterf)
    USE_GL_FUNC(glSamplerParameteriv)
    USE_GL_FUNC(glSamplerParameterfv)
    USE_GL_FUNC(glSamplerParameterIiv)
    USE_GL_FUNC(glSamplerParameterIuiv)
    USE_GL_FUNC(glGetSamplerParameteriv)
    USE_GL_FUNC(glGetSamplerParameterfv)
    USE_GL_FUNC(glGetSamplerParameterIiv)
    USE_GL_FUNC(glGetSamplerParameterIuiv)
2827 2828
    /* GL_ARB_shader_atomic_counters */
    USE_GL_FUNC(glGetActiveAtomicCounterBufferiv)
2829 2830 2831
    /* GL_ARB_shader_image_load_store */
    USE_GL_FUNC(glBindImageTexture)
    USE_GL_FUNC(glMemoryBarrier)
2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873
    /* GL_ARB_shader_objects */
    USE_GL_FUNC(glAttachObjectARB)
    USE_GL_FUNC(glBindAttribLocationARB)
    USE_GL_FUNC(glCompileShaderARB)
    USE_GL_FUNC(glCreateProgramObjectARB)
    USE_GL_FUNC(glCreateShaderObjectARB)
    USE_GL_FUNC(glDeleteObjectARB)
    USE_GL_FUNC(glDetachObjectARB)
    USE_GL_FUNC(glGetActiveUniformARB)
    USE_GL_FUNC(glGetAttachedObjectsARB)
    USE_GL_FUNC(glGetAttribLocationARB)
    USE_GL_FUNC(glGetHandleARB)
    USE_GL_FUNC(glGetInfoLogARB)
    USE_GL_FUNC(glGetObjectParameterfvARB)
    USE_GL_FUNC(glGetObjectParameterivARB)
    USE_GL_FUNC(glGetShaderSourceARB)
    USE_GL_FUNC(glGetUniformLocationARB)
    USE_GL_FUNC(glGetUniformfvARB)
    USE_GL_FUNC(glGetUniformivARB)
    USE_GL_FUNC(glLinkProgramARB)
    USE_GL_FUNC(glShaderSourceARB)
    USE_GL_FUNC(glUniform1fARB)
    USE_GL_FUNC(glUniform1fvARB)
    USE_GL_FUNC(glUniform1iARB)
    USE_GL_FUNC(glUniform1ivARB)
    USE_GL_FUNC(glUniform2fARB)
    USE_GL_FUNC(glUniform2fvARB)
    USE_GL_FUNC(glUniform2iARB)
    USE_GL_FUNC(glUniform2ivARB)
    USE_GL_FUNC(glUniform3fARB)
    USE_GL_FUNC(glUniform3fvARB)
    USE_GL_FUNC(glUniform3iARB)
    USE_GL_FUNC(glUniform3ivARB)
    USE_GL_FUNC(glUniform4fARB)
    USE_GL_FUNC(glUniform4fvARB)
    USE_GL_FUNC(glUniform4iARB)
    USE_GL_FUNC(glUniform4ivARB)
    USE_GL_FUNC(glUniformMatrix2fvARB)
    USE_GL_FUNC(glUniformMatrix3fvARB)
    USE_GL_FUNC(glUniformMatrix4fvARB)
    USE_GL_FUNC(glUseProgramObjectARB)
    USE_GL_FUNC(glValidateProgramARB)
2874 2875
    /* GL_ARB_shader_storage_buffer_object */
    USE_GL_FUNC(glShaderStorageBlockBinding)
2876 2877 2878 2879 2880 2881 2882 2883
    /* GL_ARB_sync */
    USE_GL_FUNC(glClientWaitSync)
    USE_GL_FUNC(glDeleteSync)
    USE_GL_FUNC(glFenceSync)
    USE_GL_FUNC(glGetInteger64v)
    USE_GL_FUNC(glGetSynciv)
    USE_GL_FUNC(glIsSync)
    USE_GL_FUNC(glWaitSync)
2884 2885 2886
    /* GL_ARB_tessellation_shader */
    USE_GL_FUNC(glPatchParameteri)
    USE_GL_FUNC(glPatchParameterfv)
2887 2888
    /* GL_ARB_texture_buffer_object */
    USE_GL_FUNC(glTexBufferARB)
2889 2890
    /* GL_ARB_texture_buffer_range */
    USE_GL_FUNC(glTexBufferRange)
2891 2892 2893 2894 2895 2896
    /* GL_ARB_texture_compression */
    USE_GL_FUNC(glCompressedTexImage2DARB)
    USE_GL_FUNC(glCompressedTexImage3DARB)
    USE_GL_FUNC(glCompressedTexSubImage2DARB)
    USE_GL_FUNC(glCompressedTexSubImage3DARB)
    USE_GL_FUNC(glGetCompressedTexImageARB)
2897 2898 2899 2900 2901
    /* GL_ARB_texture_multisample */
    USE_GL_FUNC(glGetMultisamplefv);
    USE_GL_FUNC(glSampleMaski);
    USE_GL_FUNC(glTexImage2DMultisample);
    USE_GL_FUNC(glTexImage3DMultisample);
2902 2903 2904 2905
    /* GL_ARB_texture_storage */
    USE_GL_FUNC(glTexStorage1D)
    USE_GL_FUNC(glTexStorage2D)
    USE_GL_FUNC(glTexStorage3D)
2906 2907 2908
    /* GL_ARB_texture_storage_multisample */
    USE_GL_FUNC(glTexStorage2DMultisample);
    USE_GL_FUNC(glTexStorage3DMultisample);
2909 2910
    /* GL_ARB_texture_view */
    USE_GL_FUNC(glTextureView)
2911 2912 2913
    /* GL_ARB_timer_query */
    USE_GL_FUNC(glQueryCounter)
    USE_GL_FUNC(glGetQueryObjectui64v)
2914 2915 2916 2917 2918 2919 2920 2921
    /* GL_ARB_transform_feedback2 */
    USE_GL_FUNC(glBindTransformFeedback);
    USE_GL_FUNC(glDeleteTransformFeedbacks);
    USE_GL_FUNC(glDrawTransformFeedback);
    USE_GL_FUNC(glGenTransformFeedbacks);
    USE_GL_FUNC(glIsTransformFeedback);
    USE_GL_FUNC(glPauseTransformFeedback);
    USE_GL_FUNC(glResumeTransformFeedback);
2922 2923 2924 2925 2926
    /* GL_ARB_transform_feedback3 */
    USE_GL_FUNC(glBeginQueryIndexed);
    USE_GL_FUNC(glDrawTransformFeedbackStream);
    USE_GL_FUNC(glEndQueryIndexed);
    USE_GL_FUNC(glGetQueryIndexediv);
2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007
    /* GL_ARB_uniform_buffer_object */
    USE_GL_FUNC(glBindBufferBase)
    USE_GL_FUNC(glBindBufferRange)
    USE_GL_FUNC(glGetActiveUniformBlockName)
    USE_GL_FUNC(glGetActiveUniformBlockiv)
    USE_GL_FUNC(glGetActiveUniformName)
    USE_GL_FUNC(glGetActiveUniformsiv)
    USE_GL_FUNC(glGetIntegeri_v)
    USE_GL_FUNC(glGetUniformBlockIndex)
    USE_GL_FUNC(glGetUniformIndices)
    USE_GL_FUNC(glUniformBlockBinding)
    /* GL_ARB_vertex_blend */
    USE_GL_FUNC(glVertexBlendARB)
    USE_GL_FUNC(glWeightPointerARB)
    USE_GL_FUNC(glWeightbvARB)
    USE_GL_FUNC(glWeightdvARB)
    USE_GL_FUNC(glWeightfvARB)
    USE_GL_FUNC(glWeightivARB)
    USE_GL_FUNC(glWeightsvARB)
    USE_GL_FUNC(glWeightubvARB)
    USE_GL_FUNC(glWeightuivARB)
    USE_GL_FUNC(glWeightusvARB)
    /* GL_ARB_vertex_buffer_object */
    USE_GL_FUNC(glBindBufferARB)
    USE_GL_FUNC(glBufferDataARB)
    USE_GL_FUNC(glBufferSubDataARB)
    USE_GL_FUNC(glDeleteBuffersARB)
    USE_GL_FUNC(glGenBuffersARB)
    USE_GL_FUNC(glGetBufferParameterivARB)
    USE_GL_FUNC(glGetBufferPointervARB)
    USE_GL_FUNC(glGetBufferSubDataARB)
    USE_GL_FUNC(glIsBufferARB)
    USE_GL_FUNC(glMapBufferARB)
    USE_GL_FUNC(glUnmapBufferARB)
    /* GL_ARB_vertex_program */
    USE_GL_FUNC(glBindProgramARB)
    USE_GL_FUNC(glDeleteProgramsARB)
    USE_GL_FUNC(glDisableVertexAttribArrayARB)
    USE_GL_FUNC(glEnableVertexAttribArrayARB)
    USE_GL_FUNC(glGenProgramsARB)
    USE_GL_FUNC(glGetProgramivARB)
    USE_GL_FUNC(glProgramEnvParameter4fvARB)
    USE_GL_FUNC(glProgramLocalParameter4fvARB)
    USE_GL_FUNC(glProgramStringARB)
    USE_GL_FUNC(glVertexAttrib1dARB)
    USE_GL_FUNC(glVertexAttrib1dvARB)
    USE_GL_FUNC(glVertexAttrib1fARB)
    USE_GL_FUNC(glVertexAttrib1fvARB)
    USE_GL_FUNC(glVertexAttrib1sARB)
    USE_GL_FUNC(glVertexAttrib1svARB)
    USE_GL_FUNC(glVertexAttrib2dARB)
    USE_GL_FUNC(glVertexAttrib2dvARB)
    USE_GL_FUNC(glVertexAttrib2fARB)
    USE_GL_FUNC(glVertexAttrib2fvARB)
    USE_GL_FUNC(glVertexAttrib2sARB)
    USE_GL_FUNC(glVertexAttrib2svARB)
    USE_GL_FUNC(glVertexAttrib3dARB)
    USE_GL_FUNC(glVertexAttrib3dvARB)
    USE_GL_FUNC(glVertexAttrib3fARB)
    USE_GL_FUNC(glVertexAttrib3fvARB)
    USE_GL_FUNC(glVertexAttrib3sARB)
    USE_GL_FUNC(glVertexAttrib3svARB)
    USE_GL_FUNC(glVertexAttrib4NbvARB)
    USE_GL_FUNC(glVertexAttrib4NivARB)
    USE_GL_FUNC(glVertexAttrib4NsvARB)
    USE_GL_FUNC(glVertexAttrib4NubARB)
    USE_GL_FUNC(glVertexAttrib4NubvARB)
    USE_GL_FUNC(glVertexAttrib4NuivARB)
    USE_GL_FUNC(glVertexAttrib4NusvARB)
    USE_GL_FUNC(glVertexAttrib4bvARB)
    USE_GL_FUNC(glVertexAttrib4dARB)
    USE_GL_FUNC(glVertexAttrib4dvARB)
    USE_GL_FUNC(glVertexAttrib4fARB)
    USE_GL_FUNC(glVertexAttrib4fvARB)
    USE_GL_FUNC(glVertexAttrib4ivARB)
    USE_GL_FUNC(glVertexAttrib4sARB)
    USE_GL_FUNC(glVertexAttrib4svARB)
    USE_GL_FUNC(glVertexAttrib4ubvARB)
    USE_GL_FUNC(glVertexAttrib4uivARB)
    USE_GL_FUNC(glVertexAttrib4usvARB)
    USE_GL_FUNC(glVertexAttribPointerARB)
3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018
    /* GL_ARB_viewport_array */
    USE_GL_FUNC(glDepthRangeArrayv)
    USE_GL_FUNC(glDepthRangeIndexed)
    USE_GL_FUNC(glGetDoublei_v)
    USE_GL_FUNC(glGetFloati_v)
    USE_GL_FUNC(glScissorArrayv)
    USE_GL_FUNC(glScissorIndexed)
    USE_GL_FUNC(glScissorIndexedv)
    USE_GL_FUNC(glViewportArrayv)
    USE_GL_FUNC(glViewportIndexedf)
    USE_GL_FUNC(glViewportIndexedfv)
3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208
    /* GL_ATI_fragment_shader */
    USE_GL_FUNC(glAlphaFragmentOp1ATI)
    USE_GL_FUNC(glAlphaFragmentOp2ATI)
    USE_GL_FUNC(glAlphaFragmentOp3ATI)
    USE_GL_FUNC(glBeginFragmentShaderATI)
    USE_GL_FUNC(glBindFragmentShaderATI)
    USE_GL_FUNC(glColorFragmentOp1ATI)
    USE_GL_FUNC(glColorFragmentOp2ATI)
    USE_GL_FUNC(glColorFragmentOp3ATI)
    USE_GL_FUNC(glDeleteFragmentShaderATI)
    USE_GL_FUNC(glEndFragmentShaderATI)
    USE_GL_FUNC(glGenFragmentShadersATI)
    USE_GL_FUNC(glPassTexCoordATI)
    USE_GL_FUNC(glSampleMapATI)
    USE_GL_FUNC(glSetFragmentShaderConstantATI)
    /* GL_ATI_separate_stencil */
    USE_GL_FUNC(glStencilOpSeparateATI)
    USE_GL_FUNC(glStencilFuncSeparateATI)
    /* GL_EXT_blend_color */
    USE_GL_FUNC(glBlendColorEXT)
    /* GL_EXT_blend_equation_separate */
    USE_GL_FUNC(glBlendFuncSeparateEXT)
    /* GL_EXT_blend_func_separate */
    USE_GL_FUNC(glBlendEquationSeparateEXT)
    /* GL_EXT_blend_minmax */
    USE_GL_FUNC(glBlendEquationEXT)
    /* GL_EXT_depth_bounds_test */
    USE_GL_FUNC(glDepthBoundsEXT)
    /* GL_EXT_draw_buffers2 */
    USE_GL_FUNC(glColorMaskIndexedEXT)
    USE_GL_FUNC(glDisableIndexedEXT)
    USE_GL_FUNC(glEnableIndexedEXT)
    USE_GL_FUNC(glGetBooleanIndexedvEXT)
    USE_GL_FUNC(glGetIntegerIndexedvEXT)
    USE_GL_FUNC(glIsEnabledIndexedEXT)
    /* GL_EXT_fog_coord */
    USE_GL_FUNC(glFogCoordPointerEXT)
    USE_GL_FUNC(glFogCoorddEXT)
    USE_GL_FUNC(glFogCoorddvEXT)
    USE_GL_FUNC(glFogCoordfEXT)
    USE_GL_FUNC(glFogCoordfvEXT)
    /* GL_EXT_framebuffer_blit */
    USE_GL_FUNC(glBlitFramebufferEXT)
    /* GL_EXT_framebuffer_multisample */
    USE_GL_FUNC(glRenderbufferStorageMultisampleEXT)
    /* GL_EXT_framebuffer_object */
    USE_GL_FUNC(glBindFramebufferEXT)
    USE_GL_FUNC(glBindRenderbufferEXT)
    USE_GL_FUNC(glCheckFramebufferStatusEXT)
    USE_GL_FUNC(glDeleteFramebuffersEXT)
    USE_GL_FUNC(glDeleteRenderbuffersEXT)
    USE_GL_FUNC(glFramebufferRenderbufferEXT)
    USE_GL_FUNC(glFramebufferTexture1DEXT)
    USE_GL_FUNC(glFramebufferTexture2DEXT)
    USE_GL_FUNC(glFramebufferTexture3DEXT)
    USE_GL_FUNC(glGenFramebuffersEXT)
    USE_GL_FUNC(glGenRenderbuffersEXT)
    USE_GL_FUNC(glGenerateMipmapEXT)
    USE_GL_FUNC(glGetFramebufferAttachmentParameterivEXT)
    USE_GL_FUNC(glGetRenderbufferParameterivEXT)
    USE_GL_FUNC(glIsFramebufferEXT)
    USE_GL_FUNC(glIsRenderbufferEXT)
    USE_GL_FUNC(glRenderbufferStorageEXT)
    /* GL_EXT_gpu_program_parameters */
    USE_GL_FUNC(glProgramEnvParameters4fvEXT)
    USE_GL_FUNC(glProgramLocalParameters4fvEXT)
    /* GL_EXT_gpu_shader4 */
    USE_GL_FUNC(glBindFragDataLocationEXT)
    USE_GL_FUNC(glGetFragDataLocationEXT)
    USE_GL_FUNC(glGetUniformuivEXT)
    USE_GL_FUNC(glGetVertexAttribIivEXT)
    USE_GL_FUNC(glGetVertexAttribIuivEXT)
    USE_GL_FUNC(glUniform1uiEXT)
    USE_GL_FUNC(glUniform1uivEXT)
    USE_GL_FUNC(glUniform2uiEXT)
    USE_GL_FUNC(glUniform2uivEXT)
    USE_GL_FUNC(glUniform3uiEXT)
    USE_GL_FUNC(glUniform3uivEXT)
    USE_GL_FUNC(glUniform4uiEXT)
    USE_GL_FUNC(glUniform4uivEXT)
    USE_GL_FUNC(glVertexAttribI1iEXT)
    USE_GL_FUNC(glVertexAttribI1ivEXT)
    USE_GL_FUNC(glVertexAttribI1uiEXT)
    USE_GL_FUNC(glVertexAttribI1uivEXT)
    USE_GL_FUNC(glVertexAttribI2iEXT)
    USE_GL_FUNC(glVertexAttribI2ivEXT)
    USE_GL_FUNC(glVertexAttribI2uiEXT)
    USE_GL_FUNC(glVertexAttribI2uivEXT)
    USE_GL_FUNC(glVertexAttribI3iEXT)
    USE_GL_FUNC(glVertexAttribI3ivEXT)
    USE_GL_FUNC(glVertexAttribI3uiEXT)
    USE_GL_FUNC(glVertexAttribI3uivEXT)
    USE_GL_FUNC(glVertexAttribI4bvEXT)
    USE_GL_FUNC(glVertexAttribI4iEXT)
    USE_GL_FUNC(glVertexAttribI4ivEXT)
    USE_GL_FUNC(glVertexAttribI4svEXT)
    USE_GL_FUNC(glVertexAttribI4ubvEXT)
    USE_GL_FUNC(glVertexAttribI4uiEXT)
    USE_GL_FUNC(glVertexAttribI4uivEXT)
    USE_GL_FUNC(glVertexAttribI4usvEXT)
    USE_GL_FUNC(glVertexAttribIPointerEXT)
    /* GL_EXT_point_parameters */
    USE_GL_FUNC(glPointParameterfEXT)
    USE_GL_FUNC(glPointParameterfvEXT)
    /* GL_EXT_provoking_vertex */
    USE_GL_FUNC(glProvokingVertexEXT)
    /* GL_EXT_secondary_color */
    USE_GL_FUNC(glSecondaryColor3fEXT)
    USE_GL_FUNC(glSecondaryColor3fvEXT)
    USE_GL_FUNC(glSecondaryColor3ubEXT)
    USE_GL_FUNC(glSecondaryColor3ubvEXT)
    USE_GL_FUNC(glSecondaryColorPointerEXT)
    /* GL_EXT_stencil_two_side */
    USE_GL_FUNC(glActiveStencilFaceEXT)
    /* GL_EXT_texture3D */
    USE_GL_FUNC(glTexImage3D)
    USE_GL_FUNC(glTexImage3DEXT)
    USE_GL_FUNC(glTexSubImage3D)
    USE_GL_FUNC(glTexSubImage3DEXT)
    /* GL_NV_fence */
    USE_GL_FUNC(glDeleteFencesNV)
    USE_GL_FUNC(glFinishFenceNV)
    USE_GL_FUNC(glGenFencesNV)
    USE_GL_FUNC(glGetFenceivNV)
    USE_GL_FUNC(glIsFenceNV)
    USE_GL_FUNC(glSetFenceNV)
    USE_GL_FUNC(glTestFenceNV)
    /* GL_NV_half_float */
    USE_GL_FUNC(glColor3hNV)
    USE_GL_FUNC(glColor3hvNV)
    USE_GL_FUNC(glColor4hNV)
    USE_GL_FUNC(glColor4hvNV)
    USE_GL_FUNC(glFogCoordhNV)
    USE_GL_FUNC(glFogCoordhvNV)
    USE_GL_FUNC(glMultiTexCoord1hNV)
    USE_GL_FUNC(glMultiTexCoord1hvNV)
    USE_GL_FUNC(glMultiTexCoord2hNV)
    USE_GL_FUNC(glMultiTexCoord2hvNV)
    USE_GL_FUNC(glMultiTexCoord3hNV)
    USE_GL_FUNC(glMultiTexCoord3hvNV)
    USE_GL_FUNC(glMultiTexCoord4hNV)
    USE_GL_FUNC(glMultiTexCoord4hvNV)
    USE_GL_FUNC(glNormal3hNV)
    USE_GL_FUNC(glNormal3hvNV)
    USE_GL_FUNC(glSecondaryColor3hNV)
    USE_GL_FUNC(glSecondaryColor3hvNV)
    USE_GL_FUNC(glTexCoord1hNV)
    USE_GL_FUNC(glTexCoord1hvNV)
    USE_GL_FUNC(glTexCoord2hNV)
    USE_GL_FUNC(glTexCoord2hvNV)
    USE_GL_FUNC(glTexCoord3hNV)
    USE_GL_FUNC(glTexCoord3hvNV)
    USE_GL_FUNC(glTexCoord4hNV)
    USE_GL_FUNC(glTexCoord4hvNV)
    USE_GL_FUNC(glVertex2hNV)
    USE_GL_FUNC(glVertex2hvNV)
    USE_GL_FUNC(glVertex3hNV)
    USE_GL_FUNC(glVertex3hvNV)
    USE_GL_FUNC(glVertex4hNV)
    USE_GL_FUNC(glVertex4hvNV)
    USE_GL_FUNC(glVertexAttrib1hNV)
    USE_GL_FUNC(glVertexAttrib1hvNV)
    USE_GL_FUNC(glVertexAttrib2hNV)
    USE_GL_FUNC(glVertexAttrib2hvNV)
    USE_GL_FUNC(glVertexAttrib3hNV)
    USE_GL_FUNC(glVertexAttrib3hvNV)
    USE_GL_FUNC(glVertexAttrib4hNV)
    USE_GL_FUNC(glVertexAttrib4hvNV)
    USE_GL_FUNC(glVertexAttribs1hvNV)
    USE_GL_FUNC(glVertexAttribs2hvNV)
    USE_GL_FUNC(glVertexAttribs3hvNV)
    USE_GL_FUNC(glVertexAttribs4hvNV)
    USE_GL_FUNC(glVertexWeighthNV)
    USE_GL_FUNC(glVertexWeighthvNV)
    /* GL_NV_point_sprite */
    USE_GL_FUNC(glPointParameteriNV)
    USE_GL_FUNC(glPointParameterivNV)
    /* GL_NV_register_combiners */
    USE_GL_FUNC(glCombinerInputNV)
    USE_GL_FUNC(glCombinerOutputNV)
    USE_GL_FUNC(glCombinerParameterfNV)
    USE_GL_FUNC(glCombinerParameterfvNV)
    USE_GL_FUNC(glCombinerParameteriNV)
    USE_GL_FUNC(glCombinerParameterivNV)
    USE_GL_FUNC(glFinalCombinerInputNV)
    /* WGL extensions */
    USE_GL_FUNC(wglChoosePixelFormatARB)
    USE_GL_FUNC(wglGetExtensionsStringARB)
    USE_GL_FUNC(wglGetPixelFormatAttribfvARB)
    USE_GL_FUNC(wglGetPixelFormatAttribivARB)
3209 3210 3211 3212
    USE_GL_FUNC(wglQueryCurrentRendererIntegerWINE)
    USE_GL_FUNC(wglQueryCurrentRendererStringWINE)
    USE_GL_FUNC(wglQueryRendererIntegerWINE)
    USE_GL_FUNC(wglQueryRendererStringWINE)
3213 3214
    USE_GL_FUNC(wglSetPixelFormatWINE)
    USE_GL_FUNC(wglSwapIntervalEXT)
3215 3216

    /* Newer core functions */
3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332
    USE_GL_FUNC(glActiveTexture)                               /* OpenGL 1.3 */
    USE_GL_FUNC(glAttachShader)                                /* OpenGL 2.0 */
    USE_GL_FUNC(glBeginQuery)                                  /* OpenGL 1.5 */
    USE_GL_FUNC(glBeginTransformFeedback)                      /* OpenGL 3.0 */
    USE_GL_FUNC(glBindAttribLocation)                          /* OpenGL 2.0 */
    USE_GL_FUNC(glBindBuffer)                                  /* OpenGL 1.5 */
    USE_GL_FUNC(glBindFragDataLocation)                        /* OpenGL 3.0 */
    USE_GL_FUNC(glBindVertexArray)                             /* OpenGL 3.0 */
    USE_GL_FUNC(glBlendColor)                                  /* OpenGL 1.4 */
    USE_GL_FUNC(glBlendEquation)                               /* OpenGL 1.4 */
    USE_GL_FUNC(glBlendEquationSeparate)                       /* OpenGL 2.0 */
    USE_GL_FUNC(glBlendFuncSeparate)                           /* OpenGL 1.4 */
    USE_GL_FUNC(glBufferData)                                  /* OpenGL 1.5 */
    USE_GL_FUNC(glBufferSubData)                               /* OpenGL 1.5 */
    USE_GL_FUNC(glColorMaski)                                  /* OpenGL 3.0 */
    USE_GL_FUNC(glCompileShader)                               /* OpenGL 2.0 */
    USE_GL_FUNC(glCompressedTexImage2D)                        /* OpenGL 1.3 */
    USE_GL_FUNC(glCompressedTexImage3D)                        /* OpenGL 1.3 */
    USE_GL_FUNC(glCompressedTexSubImage2D)                     /* OpenGL 1.3 */
    USE_GL_FUNC(glCompressedTexSubImage3D)                     /* OpenGL 1.3 */
    USE_GL_FUNC(glCreateProgram)                               /* OpenGL 2.0 */
    USE_GL_FUNC(glCreateShader)                                /* OpenGL 2.0 */
    USE_GL_FUNC(glDebugMessageCallback)                        /* OpenGL 4.3 */
    USE_GL_FUNC(glDebugMessageControl)                         /* OpenGL 4.3 */
    USE_GL_FUNC(glDebugMessageInsert)                          /* OpenGL 4.3 */
    USE_GL_FUNC(glDeleteBuffers)                               /* OpenGL 1.5 */
    USE_GL_FUNC(glDeleteProgram)                               /* OpenGL 2.0 */
    USE_GL_FUNC(glDeleteQueries)                               /* OpenGL 1.5 */
    USE_GL_FUNC(glDeleteShader)                                /* OpenGL 2.0 */
    USE_GL_FUNC(glDeleteVertexArrays)                          /* OpenGL 3.0 */
    USE_GL_FUNC(glDetachShader)                                /* OpenGL 2.0 */
    USE_GL_FUNC(glDisablei)                                    /* OpenGL 3.0 */
    USE_GL_FUNC(glDisableVertexAttribArray)                    /* OpenGL 2.0 */
    USE_GL_FUNC(glDrawArraysInstanced)                         /* OpenGL 3.1 */
    USE_GL_FUNC(glDrawBuffers)                                 /* OpenGL 2.0 */
    USE_GL_FUNC(glDrawElementsInstanced)                       /* OpenGL 3.1 */
    USE_GL_FUNC(glEnablei)                                     /* OpenGL 3.0 */
    USE_GL_FUNC(glEnableVertexAttribArray)                     /* OpenGL 2.0 */
    USE_GL_FUNC(glEndQuery)                                    /* OpenGL 1.5 */
    USE_GL_FUNC(glEndTransformFeedback)                        /* OpenGL 3.0 */
    USE_GL_FUNC(glFramebufferTexture)                          /* OpenGL 3.2 */
    USE_GL_FUNC(glGenBuffers)                                  /* OpenGL 1.5 */
    USE_GL_FUNC(glGenQueries)                                  /* OpenGL 1.5 */
    USE_GL_FUNC(glGenVertexArrays)                             /* OpenGL 3.0 */
    USE_GL_FUNC(glGetActiveUniform)                            /* OpenGL 2.0 */
    USE_GL_FUNC(glGetAttachedShaders)                          /* OpenGL 2.0 */
    USE_GL_FUNC(glGetAttribLocation)                           /* OpenGL 2.0 */
    USE_GL_FUNC(glGetBooleani_v)                               /* OpenGL 3.0 */
    USE_GL_FUNC(glGetBufferSubData)                            /* OpenGL 1.5 */
    USE_GL_FUNC(glGetCompressedTexImage)                       /* OpenGL 1.3 */
    USE_GL_FUNC(glGetDebugMessageLog)                          /* OpenGL 4.3 */
    USE_GL_FUNC(glGetIntegeri_v)                               /* OpenGL 3.0 */
    USE_GL_FUNC(glGetProgramInfoLog)                           /* OpenGL 2.0 */
    USE_GL_FUNC(glGetProgramiv)                                /* OpenGL 2.0 */
    USE_GL_FUNC(glGetQueryiv)                                  /* OpenGL 1.5 */
    USE_GL_FUNC(glGetQueryObjectuiv)                           /* OpenGL 1.5 */
    USE_GL_FUNC(glGetShaderInfoLog)                            /* OpenGL 2.0 */
    USE_GL_FUNC(glGetShaderiv)                                 /* OpenGL 2.0 */
    USE_GL_FUNC(glGetShaderSource)                             /* OpenGL 2.0 */
    USE_GL_FUNC(glGetStringi)                                  /* OpenGL 3.0 */
    USE_GL_FUNC(glGetTextureLevelParameteriv)                  /* OpenGL 4.5 */
    USE_GL_FUNC(glGetTextureParameteriv)                       /* OpenGL 4.5 */
    USE_GL_FUNC(glGetUniformfv)                                /* OpenGL 2.0 */
    USE_GL_FUNC(glGetUniformiv)                                /* OpenGL 2.0 */
    USE_GL_FUNC(glGetUniformLocation)                          /* OpenGL 2.0 */
    USE_GL_FUNC(glIsEnabledi)                                  /* OpenGL 3.0 */
    USE_GL_FUNC(glLinkProgram)                                 /* OpenGL 2.0 */
    USE_GL_FUNC(glMapBuffer)                                   /* OpenGL 1.5 */
    USE_GL_FUNC(glPointParameteri)                             /* OpenGL 1.4 */
    USE_GL_FUNC(glPointParameteriv)                            /* OpenGL 1.4 */
    USE_GL_FUNC(glShaderSource)                                /* OpenGL 2.0 */
    USE_GL_FUNC(glStencilFuncSeparate)                         /* OpenGL 2.0 */
    USE_GL_FUNC(glStencilOpSeparate)                           /* OpenGL 2.0 */
    USE_GL_FUNC(glTexBuffer)                                   /* OpenGL 3.1 */
    USE_GL_FUNC(glTexImage3D)                                  /* OpenGL 1.2 */
    USE_GL_FUNC(glTexSubImage3D)                               /* OpenGL 1.2 */
    USE_GL_FUNC(glTransformFeedbackVaryings)                   /* OpenGL 3.0 */
    USE_GL_FUNC(glUniform1f)                                   /* OpenGL 2.0 */
    USE_GL_FUNC(glUniform1fv)                                  /* OpenGL 2.0 */
    USE_GL_FUNC(glUniform1i)                                   /* OpenGL 2.0 */
    USE_GL_FUNC(glUniform1iv)                                  /* OpenGL 2.0 */
    USE_GL_FUNC(glUniform2f)                                   /* OpenGL 2.0 */
    USE_GL_FUNC(glUniform2fv)                                  /* OpenGL 2.0 */
    USE_GL_FUNC(glUniform2i)                                   /* OpenGL 2.0 */
    USE_GL_FUNC(glUniform2iv)                                  /* OpenGL 2.0 */
    USE_GL_FUNC(glUniform3f)                                   /* OpenGL 2.0 */
    USE_GL_FUNC(glUniform3fv)                                  /* OpenGL 2.0 */
    USE_GL_FUNC(glUniform3i)                                   /* OpenGL 2.0 */
    USE_GL_FUNC(glUniform3iv)                                  /* OpenGL 2.0 */
    USE_GL_FUNC(glUniform4f)                                   /* OpenGL 2.0 */
    USE_GL_FUNC(glUniform4fv)                                  /* OpenGL 2.0 */
    USE_GL_FUNC(glUniform4i)                                   /* OpenGL 2.0 */
    USE_GL_FUNC(glUniform4iv)                                  /* OpenGL 2.0 */
    USE_GL_FUNC(glUniformMatrix2fv)                            /* OpenGL 2.0 */
    USE_GL_FUNC(glUniformMatrix3fv)                            /* OpenGL 2.0 */
    USE_GL_FUNC(glUniformMatrix4fv)                            /* OpenGL 2.0 */
    USE_GL_FUNC(glUnmapBuffer)                                 /* OpenGL 1.5 */
    USE_GL_FUNC(glUseProgram)                                  /* OpenGL 2.0 */
    USE_GL_FUNC(glValidateProgram)                             /* OpenGL 2.0 */
    USE_GL_FUNC(glVertexAttrib1f)                              /* OpenGL 2.0 */
    USE_GL_FUNC(glVertexAttrib1fv)                             /* OpenGL 2.0 */
    USE_GL_FUNC(glVertexAttrib2f)                              /* OpenGL 2.0 */
    USE_GL_FUNC(glVertexAttrib2fv)                             /* OpenGL 2.0 */
    USE_GL_FUNC(glVertexAttrib3f)                              /* OpenGL 2.0 */
    USE_GL_FUNC(glVertexAttrib3fv)                             /* OpenGL 2.0 */
    USE_GL_FUNC(glVertexAttrib4f)                              /* OpenGL 2.0 */
    USE_GL_FUNC(glVertexAttrib4fv)                             /* OpenGL 2.0 */
    USE_GL_FUNC(glVertexAttrib4Nsv)                            /* OpenGL 2.0 */
    USE_GL_FUNC(glVertexAttrib4Nub)                            /* OpenGL 2.0 */
    USE_GL_FUNC(glVertexAttrib4Nubv)                           /* OpenGL 2.0 */
    USE_GL_FUNC(glVertexAttrib4Nusv)                           /* OpenGL 2.0 */
    USE_GL_FUNC(glVertexAttrib4sv)                             /* OpenGL 2.0 */
    USE_GL_FUNC(glVertexAttrib4ubv)                            /* OpenGL 2.0 */
    USE_GL_FUNC(glVertexAttribDivisor)                         /* OpenGL 3.3 */
    USE_GL_FUNC(glVertexAttribIPointer)                        /* OpenGL 3.0 */
    USE_GL_FUNC(glVertexAttribPointer)                         /* OpenGL 2.0 */
3333
#undef USE_GL_FUNC
3334 3335 3336 3337 3338 3339

#ifndef USE_WIN32_OPENGL
    /* hack: use the functions directly from the TEB table to bypass the thunks */
    /* note that we still need the above wglGetProcAddress calls to initialize the table */
    gl_info->gl_ops.ext = ((struct opengl_funcs *)NtCurrentTeb()->glTable)->ext;
#endif
3340

3341
#define MAP_GL_FUNCTION(core_func, ext_func)                                          \
3342 3343 3344 3345 3346
        do                                                                            \
        {                                                                             \
            if (!gl_info->gl_ops.ext.p_##core_func)                                   \
                gl_info->gl_ops.ext.p_##core_func = gl_info->gl_ops.ext.p_##ext_func; \
        } while (0)
3347 3348 3349 3350 3351 3352
#define MAP_GL_FUNCTION_CAST(core_func, ext_func)                                             \
        do                                                                                    \
        {                                                                                     \
            if (!gl_info->gl_ops.ext.p_##core_func)                                           \
                gl_info->gl_ops.ext.p_##core_func = (void *)gl_info->gl_ops.ext.p_##ext_func; \
        } while (0)
3353 3354

    MAP_GL_FUNCTION(glActiveTexture, glActiveTextureARB);
3355
    MAP_GL_FUNCTION(glAttachShader, glAttachObjectARB);
3356
    MAP_GL_FUNCTION(glBeginQuery, glBeginQueryARB);
3357
    MAP_GL_FUNCTION(glBindAttribLocation, glBindAttribLocationARB);
3358
    MAP_GL_FUNCTION(glBindBuffer, glBindBufferARB);
3359
    MAP_GL_FUNCTION(glBindFragDataLocation, glBindFragDataLocationEXT);
3360 3361 3362 3363
    MAP_GL_FUNCTION(glBlendColor, glBlendColorEXT);
    MAP_GL_FUNCTION(glBlendEquation, glBlendEquationEXT);
    MAP_GL_FUNCTION(glBlendEquationSeparate, glBlendEquationSeparateEXT);
    MAP_GL_FUNCTION(glBlendFuncSeparate, glBlendFuncSeparateEXT);
3364 3365
    MAP_GL_FUNCTION(glBufferData, glBufferDataARB);
    MAP_GL_FUNCTION(glBufferSubData, glBufferSubDataARB);
3366
    MAP_GL_FUNCTION(glColorMaski, glColorMaskIndexedEXT);
3367
    MAP_GL_FUNCTION(glCompileShader, glCompileShaderARB);
3368 3369 3370 3371
    MAP_GL_FUNCTION(glCompressedTexImage2D, glCompressedTexImage2DARB);
    MAP_GL_FUNCTION(glCompressedTexImage3D, glCompressedTexImage3DARB);
    MAP_GL_FUNCTION(glCompressedTexSubImage2D, glCompressedTexSubImage2DARB);
    MAP_GL_FUNCTION(glCompressedTexSubImage3D, glCompressedTexSubImage3DARB);
3372 3373
    MAP_GL_FUNCTION(glCreateProgram, glCreateProgramObjectARB);
    MAP_GL_FUNCTION(glCreateShader, glCreateShaderObjectARB);
3374 3375 3376
    MAP_GL_FUNCTION(glDebugMessageCallback, glDebugMessageCallbackARB);
    MAP_GL_FUNCTION(glDebugMessageControl, glDebugMessageControlARB);
    MAP_GL_FUNCTION(glDebugMessageInsert, glDebugMessageInsertARB);
3377
    MAP_GL_FUNCTION(glDeleteBuffers, glDeleteBuffersARB);
3378
    MAP_GL_FUNCTION(glDeleteProgram, glDeleteObjectARB);
3379
    MAP_GL_FUNCTION(glDeleteQueries, glDeleteQueriesARB);
3380 3381
    MAP_GL_FUNCTION(glDeleteShader, glDeleteObjectARB);
    MAP_GL_FUNCTION(glDetachShader, glDetachObjectARB);
3382
    MAP_GL_FUNCTION(glDisablei, glDisableIndexedEXT);
3383
    MAP_GL_FUNCTION(glDisableVertexAttribArray, glDisableVertexAttribArrayARB);
3384
    MAP_GL_FUNCTION(glDrawArraysInstanced, glDrawArraysInstancedARB);
3385
    MAP_GL_FUNCTION(glDrawBuffers, glDrawBuffersARB);
3386
    MAP_GL_FUNCTION(glDrawElementsInstanced, glDrawElementsInstancedARB);
3387
    MAP_GL_FUNCTION(glEnablei, glEnableIndexedEXT);
3388
    MAP_GL_FUNCTION(glEnableVertexAttribArray, glEnableVertexAttribArrayARB);
3389
    MAP_GL_FUNCTION(glEndQuery, glEndQueryARB);
3390
    MAP_GL_FUNCTION(glFramebufferTexture, glFramebufferTextureARB);
3391
    MAP_GL_FUNCTION(glGenBuffers, glGenBuffersARB);
3392
    MAP_GL_FUNCTION(glGenQueries, glGenQueriesARB);
3393 3394 3395
    MAP_GL_FUNCTION(glGetActiveUniform, glGetActiveUniformARB);
    MAP_GL_FUNCTION(glGetAttachedShaders, glGetAttachedObjectsARB);
    MAP_GL_FUNCTION(glGetAttribLocation, glGetAttribLocationARB);
3396
    MAP_GL_FUNCTION(glGetBooleani_v, glGetBooleanIndexedvEXT);
3397
    MAP_GL_FUNCTION(glGetBufferSubData, glGetBufferSubDataARB);
3398
    MAP_GL_FUNCTION(glGetCompressedTexImage, glGetCompressedTexImageARB);
3399
    MAP_GL_FUNCTION(glGetDebugMessageLog, glGetDebugMessageLogARB);
3400
    MAP_GL_FUNCTION(glGetIntegeri_v, glGetIntegerIndexedvEXT);
3401 3402
    MAP_GL_FUNCTION(glGetProgramInfoLog, glGetInfoLogARB);
    MAP_GL_FUNCTION(glGetProgramiv, glGetObjectParameterivARB);
3403 3404
    MAP_GL_FUNCTION(glGetQueryiv, glGetQueryivARB);
    MAP_GL_FUNCTION(glGetQueryObjectuiv, glGetQueryObjectuivARB);
3405 3406 3407 3408 3409 3410
    MAP_GL_FUNCTION(glGetShaderInfoLog, glGetInfoLogARB);
    MAP_GL_FUNCTION(glGetShaderiv, glGetObjectParameterivARB);
    MAP_GL_FUNCTION(glGetShaderSource, glGetShaderSourceARB);
    MAP_GL_FUNCTION(glGetUniformfv, glGetUniformfvARB);
    MAP_GL_FUNCTION(glGetUniformiv, glGetUniformivARB);
    MAP_GL_FUNCTION(glGetUniformLocation, glGetUniformLocationARB);
3411
    MAP_GL_FUNCTION(glIsEnabledi, glIsEnabledIndexedEXT);
3412
    MAP_GL_FUNCTION(glLinkProgram, glLinkProgramARB);
3413
    MAP_GL_FUNCTION(glMapBuffer, glMapBufferARB);
3414
    MAP_GL_FUNCTION_CAST(glShaderSource, glShaderSourceARB);
3415
    MAP_GL_FUNCTION(glTexBuffer, glTexBufferARB);
3416 3417
    MAP_GL_FUNCTION_CAST(glTexImage3D, glTexImage3DEXT);
    MAP_GL_FUNCTION(glTexSubImage3D, glTexSubImage3DEXT);
3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436
    MAP_GL_FUNCTION(glUniform1f, glUniform1fARB);
    MAP_GL_FUNCTION(glUniform1fv, glUniform1fvARB);
    MAP_GL_FUNCTION(glUniform1i, glUniform1iARB);
    MAP_GL_FUNCTION(glUniform1iv, glUniform1ivARB);
    MAP_GL_FUNCTION(glUniform2f, glUniform2fARB);
    MAP_GL_FUNCTION(glUniform2fv, glUniform2fvARB);
    MAP_GL_FUNCTION(glUniform2i, glUniform2iARB);
    MAP_GL_FUNCTION(glUniform2iv, glUniform2ivARB);
    MAP_GL_FUNCTION(glUniform3f, glUniform3fARB);
    MAP_GL_FUNCTION(glUniform3fv, glUniform3fvARB);
    MAP_GL_FUNCTION(glUniform3i, glUniform3iARB);
    MAP_GL_FUNCTION(glUniform3iv, glUniform3ivARB);
    MAP_GL_FUNCTION(glUniform4f, glUniform4fARB);
    MAP_GL_FUNCTION(glUniform4fv, glUniform4fvARB);
    MAP_GL_FUNCTION(glUniform4i, glUniform4iARB);
    MAP_GL_FUNCTION(glUniform4iv, glUniform4ivARB);
    MAP_GL_FUNCTION(glUniformMatrix2fv, glUniformMatrix2fvARB);
    MAP_GL_FUNCTION(glUniformMatrix3fv, glUniformMatrix3fvARB);
    MAP_GL_FUNCTION(glUniformMatrix4fv, glUniformMatrix4fvARB);
3437
    MAP_GL_FUNCTION(glUnmapBuffer, glUnmapBufferARB);
3438 3439
    MAP_GL_FUNCTION(glUseProgram, glUseProgramObjectARB);
    MAP_GL_FUNCTION(glValidateProgram, glValidateProgramARB);
3440 3441 3442 3443 3444 3445 3446 3447 3448
    MAP_GL_FUNCTION(glVertexAttrib1f, glVertexAttrib1fARB);
    MAP_GL_FUNCTION(glVertexAttrib1fv, glVertexAttrib1fvARB);
    MAP_GL_FUNCTION(glVertexAttrib2f, glVertexAttrib2fARB);
    MAP_GL_FUNCTION(glVertexAttrib2fv, glVertexAttrib2fvARB);
    MAP_GL_FUNCTION(glVertexAttrib3f, glVertexAttrib3fARB);
    MAP_GL_FUNCTION(glVertexAttrib3fv, glVertexAttrib3fvARB);
    MAP_GL_FUNCTION(glVertexAttrib4f, glVertexAttrib4fARB);
    MAP_GL_FUNCTION(glVertexAttrib4fv, glVertexAttrib4fvARB);
    MAP_GL_FUNCTION(glVertexAttrib4Nsv, glVertexAttrib4NsvARB);
3449
    MAP_GL_FUNCTION(glVertexAttrib4Nub, glVertexAttrib4NubARB);
3450 3451 3452 3453 3454
    MAP_GL_FUNCTION(glVertexAttrib4Nubv, glVertexAttrib4NubvARB);
    MAP_GL_FUNCTION(glVertexAttrib4Nusv, glVertexAttrib4NusvARB);
    MAP_GL_FUNCTION(glVertexAttrib4sv, glVertexAttrib4svARB);
    MAP_GL_FUNCTION(glVertexAttrib4ubv, glVertexAttrib4ubvARB);
    MAP_GL_FUNCTION(glVertexAttribDivisor, glVertexAttribDivisorARB);
3455
    MAP_GL_FUNCTION(glVertexAttribIPointer, glVertexAttribIPointerEXT);
3456
    MAP_GL_FUNCTION(glVertexAttribPointer, glVertexAttribPointerARB);
3457
#undef MAP_GL_FUNCTION
3458
#undef MAP_GL_FUNCTION_CAST
3459 3460
}

3461
static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info)
3462
{
3463
    unsigned int i, sampler_count;
3464 3465
    GLfloat gl_floatv[2];
    GLint gl_max;
3466

3467
    gl_info->limits.blends = 1;
3468
    gl_info->limits.buffers = 1;
3469 3470
    gl_info->limits.textures = 0;
    gl_info->limits.texture_coords = 0;
3471
    for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i)
3472
    {
3473
        gl_info->limits.uniform_blocks[i] = 0;
3474 3475 3476 3477
        gl_info->limits.samplers[i] = 0;
    }
    gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = 1;
    gl_info->limits.combined_samplers = gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL];
3478
    gl_info->limits.graphics_samplers = gl_info->limits.combined_samplers;
3479
    gl_info->limits.vertex_attribs = 16;
3480
    gl_info->limits.texture_buffer_offset_alignment = 1;
3481 3482 3483 3484 3485 3486 3487 3488 3489 3490
    gl_info->limits.glsl_vs_float_constants = 0;
    gl_info->limits.glsl_ps_float_constants = 0;
    gl_info->limits.arb_vs_float_constants = 0;
    gl_info->limits.arb_vs_native_constants = 0;
    gl_info->limits.arb_vs_instructions = 0;
    gl_info->limits.arb_vs_temps = 0;
    gl_info->limits.arb_ps_float_constants = 0;
    gl_info->limits.arb_ps_local_constants = 0;
    gl_info->limits.arb_ps_instructions = 0;
    gl_info->limits.arb_ps_temps = 0;
3491

3492 3493
    gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_CLIP_DISTANCES, &gl_max);
    gl_info->limits.user_clip_distances = min(MAX_CLIP_DISTANCES, gl_max);
3494
    TRACE("Clip plane support - max planes %d.\n", gl_max);
3495

3496 3497 3498 3499 3500 3501
    if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
    {
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
        gl_info->limits.lights = gl_max;
        TRACE("Light support - max lights %d.\n", gl_max);
    }
3502

3503
    gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max);
3504
    gl_info->limits.texture_size = gl_max;
3505
    TRACE("Maximum texture size support - max texture size %d.\n", gl_max);
3506

3507 3508
    gl_info->gl_ops.gl.p_glGetFloatv(gl_info->supported[WINED3D_GL_LEGACY_CONTEXT]
            ? GL_ALIASED_POINT_SIZE_RANGE : GL_POINT_SIZE_RANGE, gl_floatv);
3509 3510
    gl_info->limits.pointsize_min = gl_floatv[0];
    gl_info->limits.pointsize_max = gl_floatv[1];
3511
    TRACE("Maximum point size support - max point size %f.\n", gl_floatv[1]);
3512

3513 3514
    if (gl_info->supported[ARB_MAP_BUFFER_ALIGNMENT])
    {
3515
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MIN_MAP_BUFFER_ALIGNMENT, &gl_max);
3516
        TRACE("Minimum buffer map alignment: %d.\n", gl_max);
3517 3518 3519
    }
    else
    {
3520
        WARN_(d3d_perf)("Driver doesn't guarantee a minimum buffer map alignment.\n");
3521
    }
3522 3523
    if (gl_info->supported[NV_REGISTER_COMBINERS])
    {
3524
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &gl_max);
3525
        gl_info->limits.general_combiners = gl_max;
3526
        TRACE("Max general combiners: %d.\n", gl_max);
3527
    }
3528
    if (gl_info->supported[ARB_DRAW_BUFFERS] && wined3d_settings.offscreen_rendering_mode == ORM_FBO)
3529
    {
3530
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
3531
        gl_info->limits.buffers = min(MAX_RENDER_TARGET_VIEWS, gl_max);
3532
        TRACE("Max draw buffers: %u.\n", gl_max);
3533 3534 3535
    }
    if (gl_info->supported[ARB_MULTITEXTURE])
    {
3536 3537 3538 3539 3540
        if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
        {
            gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
            gl_info->limits.textures = min(MAX_TEXTURES, gl_max);
            TRACE("Max textures: %d.\n", gl_info->limits.textures);
3541

3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554
            if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
            {
                gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_COORDS_ARB, &gl_max);
                gl_info->limits.texture_coords = min(MAX_TEXTURES, gl_max);
            }
            else
            {
                gl_info->limits.texture_coords = gl_info->limits.textures;
            }
            TRACE("Max texture coords: %d.\n", gl_info->limits.texture_coords);
        }

        if (gl_info->supported[ARB_FRAGMENT_PROGRAM] || gl_info->supported[ARB_FRAGMENT_SHADER])
3555
        {
3556
            gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &gl_max);
3557
            gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = gl_max;
3558
        }
3559 3560
        else
        {
3561
            gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = gl_info->limits.textures;
3562
        }
3563
        TRACE("Max fragment samplers: %d.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL]);
3564 3565 3566

        if (gl_info->supported[ARB_VERTEX_SHADER])
        {
3567 3568
            unsigned int vertex_sampler_count;

3569
            gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &gl_max);
3570
            vertex_sampler_count = gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX] = gl_max;
3571 3572 3573 3574
            gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &gl_max);
            gl_info->limits.combined_samplers = gl_max;
            gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_ATTRIBS_ARB, &gl_max);
            gl_info->limits.vertex_attribs = gl_max;
3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589

            /* Loading GLSL sampler uniforms is much simpler if we can assume that the sampler setup
             * is known at shader link time. In a vertex shader + pixel shader combination this isn't
             * an issue because then the sampler setup only depends on the two shaders. If a pixel
             * shader is used with fixed function vertex processing we're fine too because fixed function
             * vertex processing doesn't use any samplers. If fixed function fragment processing is
             * used we have to make sure that all vertex sampler setups are valid together with all
             * possible fixed function fragment processing setups. This is true if vsamplers + MAX_TEXTURES
             * <= max_samplers. This is true on all d3d9 cards that support vtf(gf 6 and gf7 cards).
             * dx9 radeon cards do not support vertex texture fetch. DX10 cards have 128 samplers, and
             * dx9 is limited to 8 fixed function texture stages and 4 vertex samplers. DX10 does not have
             * a fixed function pipeline anymore.
             *
             * So this is just a check to check that our assumption holds true. If not, write a warning
             * and reduce the number of vertex samplers or probably disable vertex texture fetch. */
3590 3591
            if (vertex_sampler_count && gl_info->limits.combined_samplers < 12
                    && MAX_TEXTURES + vertex_sampler_count > gl_info->limits.combined_samplers)
3592 3593
            {
                FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers.\n",
3594
                        vertex_sampler_count, gl_info->limits.combined_samplers);
3595
                FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers.\n");
3596
                if (gl_info->limits.combined_samplers > MAX_TEXTURES)
3597
                    vertex_sampler_count = gl_info->limits.combined_samplers - MAX_TEXTURES;
3598
                else
3599 3600
                    vertex_sampler_count = 0;
                gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX] = vertex_sampler_count;
3601
            }
3602
        }
3603 3604
        else
        {
3605
            gl_info->limits.combined_samplers = gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL];
3606
        }
3607
        TRACE("Max vertex samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX]);
3608
        TRACE("Max combined samplers: %u.\n", gl_info->limits.combined_samplers);
3609
        TRACE("Max vertex attributes: %u.\n", gl_info->limits.vertex_attribs);
3610
    }
3611 3612 3613 3614 3615 3616
    else
    {
        gl_info->limits.textures = 1;
        gl_info->limits.texture_coords = 1;
    }

3617
    if (gl_info->supported[ARB_VERTEX_BLEND])
3618
    {
3619
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
3620
        gl_info->limits.blends = gl_max;
3621
        TRACE("Max blends: %u.\n", gl_info->limits.blends);
3622 3623 3624
    }
    if (gl_info->supported[EXT_TEXTURE3D])
    {
3625
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
3626
        gl_info->limits.texture3d_size = gl_max;
3627
        TRACE("Max texture3D size: %d.\n", gl_info->limits.texture3d_size);
3628
    }
3629
    if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC])
3630
    {
3631
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &gl_max);
3632
        gl_info->limits.anisotropy = gl_max;
3633
        TRACE("Max anisotropy: %d.\n", gl_info->limits.anisotropy);
3634 3635 3636 3637
    }
    if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
    {
        GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
3638
        gl_info->limits.arb_ps_float_constants = gl_max;
3639
        TRACE("Max ARB_FRAGMENT_PROGRAM float constants: %d.\n", gl_info->limits.arb_ps_float_constants);
3640
        GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
3641
        gl_info->limits.arb_ps_native_constants = gl_max;
3642
        TRACE("Max ARB_FRAGMENT_PROGRAM native float constants: %d.\n",
3643
                gl_info->limits.arb_ps_native_constants);
3644
        GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
3645
        gl_info->limits.arb_ps_temps = gl_max;
3646
        TRACE("Max ARB_FRAGMENT_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_ps_temps);
3647
        GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
3648
        gl_info->limits.arb_ps_instructions = gl_max;
3649
        TRACE("Max ARB_FRAGMENT_PROGRAM native instructions: %d.\n", gl_info->limits.arb_ps_instructions);
3650
        GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &gl_max));
3651
        gl_info->limits.arb_ps_local_constants = gl_max;
3652
        TRACE("Max ARB_FRAGMENT_PROGRAM local parameters: %d.\n", gl_info->limits.arb_ps_instructions);
3653 3654 3655 3656
    }
    if (gl_info->supported[ARB_VERTEX_PROGRAM])
    {
        GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
3657
        gl_info->limits.arb_vs_float_constants = gl_max;
3658
        TRACE("Max ARB_VERTEX_PROGRAM float constants: %d.\n", gl_info->limits.arb_vs_float_constants);
3659
        GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
3660
        gl_info->limits.arb_vs_native_constants = gl_max;
3661
        TRACE("Max ARB_VERTEX_PROGRAM native float constants: %d.\n",
3662
                gl_info->limits.arb_vs_native_constants);
3663
        GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
3664
        gl_info->limits.arb_vs_temps = gl_max;
3665
        TRACE("Max ARB_VERTEX_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_vs_temps);
3666
        GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
3667
        gl_info->limits.arb_vs_instructions = gl_max;
3668
        TRACE("Max ARB_VERTEX_PROGRAM native instructions: %d.\n", gl_info->limits.arb_vs_instructions);
3669 3670 3671
    }
    if (gl_info->supported[ARB_VERTEX_SHADER])
    {
3672
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
3673
        gl_info->limits.glsl_vs_float_constants = gl_max / 4;
3674
        TRACE("Max ARB_VERTEX_SHADER float constants: %u.\n", gl_info->limits.glsl_vs_float_constants);
3675 3676 3677 3678

        if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT])
        {
            gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, &gl_max);
3679 3680 3681
            gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_VERTEX] = min(gl_max, WINED3D_MAX_CBS);
            TRACE("Max vertex uniform blocks: %u (%d).\n",
                    gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_VERTEX], gl_max);
3682 3683
        }
    }
3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701
    if (gl_info->supported[ARB_TESSELLATION_SHADER])
    {
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS, &gl_max);
        gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_HULL] = min(gl_max, WINED3D_MAX_CBS);
        TRACE("Max hull uniform blocks: %u (%d).\n",
                gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_HULL], gl_max);
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS, &gl_max);
        gl_info->limits.samplers[WINED3D_SHADER_TYPE_HULL] = gl_max;
        TRACE("Max hull samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_HULL]);

        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS, &gl_max);
        gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_DOMAIN] = min(gl_max, WINED3D_MAX_CBS);
        TRACE("Max domain uniform blocks: %u (%d).\n",
                gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_DOMAIN], gl_max);
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS, &gl_max);
        gl_info->limits.samplers[WINED3D_SHADER_TYPE_DOMAIN] = gl_max;
        TRACE("Max domain samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_DOMAIN]);
    }
3702
    if (gl_info->supported[WINED3D_GL_VERSION_3_2] && gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT])
3703 3704
    {
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_GEOMETRY_UNIFORM_BLOCKS, &gl_max);
3705 3706 3707
        gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_GEOMETRY] = min(gl_max, WINED3D_MAX_CBS);
        TRACE("Max geometry uniform blocks: %u (%d).\n",
                gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_GEOMETRY], gl_max);
3708
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &gl_max);
3709 3710
        gl_info->limits.samplers[WINED3D_SHADER_TYPE_GEOMETRY] = gl_max;
        TRACE("Max geometry samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_GEOMETRY]);
3711 3712 3713
    }
    if (gl_info->supported[ARB_FRAGMENT_SHADER])
    {
3714
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
3715
        gl_info->limits.glsl_ps_float_constants = gl_max / 4;
3716
        TRACE("Max ARB_FRAGMENT_SHADER float constants: %u.\n", gl_info->limits.glsl_ps_float_constants);
3717
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max);
3718
        gl_info->limits.glsl_varyings = gl_max;
3719
        TRACE("Max GLSL varyings: %u (%u 4 component varyings).\n", gl_max, gl_max / 4);
3720 3721 3722 3723

        if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT])
        {
            gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &gl_max);
3724 3725 3726
            gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_PIXEL] = min(gl_max, WINED3D_MAX_CBS);
            TRACE("Max fragment uniform blocks: %u (%d).\n",
                    gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_PIXEL], gl_max);
3727 3728
        }
    }
3729 3730 3731 3732 3733 3734
    if (gl_info->supported[ARB_COMPUTE_SHADER])
    {
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMPUTE_UNIFORM_BLOCKS, &gl_max);
        gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_COMPUTE] = min(gl_max, WINED3D_MAX_CBS);
        TRACE("Max compute uniform blocks: %u (%d).\n",
                gl_info->limits.uniform_blocks[WINED3D_SHADER_TYPE_COMPUTE], gl_max);
3735
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, &gl_max);
3736 3737
        gl_info->limits.samplers[WINED3D_SHADER_TYPE_COMPUTE] = gl_max;
        TRACE("Max compute samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_COMPUTE]);
3738
    }
3739 3740 3741 3742 3743 3744
    if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT])
    {
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS, &gl_max);
        TRACE("Max combined uniform blocks: %d.\n", gl_max);
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &gl_max);
        TRACE("Max uniform buffer bindings: %d.\n", gl_max);
3745
    }
3746 3747 3748 3749 3750 3751
    if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE])
    {
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT, &gl_max);
        gl_info->limits.texture_buffer_offset_alignment = gl_max;
        TRACE("Minimum required texture buffer offset alignment %d.\n", gl_max);
    }
3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768
    if (gl_info->supported[ARB_SHADER_ATOMIC_COUNTERS])
    {
        GLint max_fragment_buffers, max_combined_buffers, max_bindings;
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS, &max_fragment_buffers);
        TRACE("Max fragment atomic counter buffers: %d.\n", max_fragment_buffers);
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS, &max_combined_buffers);
        TRACE("Max combined atomic counter buffers: %d.\n", max_combined_buffers);
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &max_bindings);
        TRACE("Max atomic counter buffer bindings: %d.\n", max_bindings);
        if (max_fragment_buffers < MAX_UNORDERED_ACCESS_VIEWS
                || max_combined_buffers < MAX_UNORDERED_ACCESS_VIEWS
                || max_bindings < MAX_UNORDERED_ACCESS_VIEWS)
        {
            WARN("Disabling ARB_shader_atomic_counters.\n");
            gl_info->supported[ARB_SHADER_ATOMIC_COUNTERS] = FALSE;
        }
    }
3769 3770 3771 3772 3773
    if (gl_info->supported[ARB_TRANSFORM_FEEDBACK3])
    {
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_STREAMS, &gl_max);
        TRACE("Max vertex streams: %d.\n", gl_max);
    }
3774 3775

    if (gl_info->supported[NV_LIGHT_MAX_EXPONENT])
3776
        gl_info->gl_ops.gl.p_glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess);
3777 3778 3779
    else
        gl_info->limits.shininess = 128.0f;

3780
    if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE])
3781
    {
3782
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_SAMPLES, &gl_max);
3783 3784
        gl_info->limits.samples = gl_max;
    }
3785

3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798
    if (gl_info->supported[ARB_FRAMEBUFFER_NO_ATTACHMENTS])
    {
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAMEBUFFER_WIDTH, &gl_max);
        gl_info->limits.framebuffer_width = gl_max;
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAMEBUFFER_HEIGHT, &gl_max);
        gl_info->limits.framebuffer_height = gl_max;
    }
    else
    {
        gl_info->limits.framebuffer_width = gl_info->limits.texture_size;
        gl_info->limits.framebuffer_height = gl_info->limits.texture_size;
    }

3799 3800 3801 3802 3803
    gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] =
            min(gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL], MAX_GL_FRAGMENT_SAMPLERS);
    sampler_count = 0;
    for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i)
        sampler_count += gl_info->limits.samplers[i];
3804 3805 3806 3807 3808 3809 3810
    if (gl_info->supported[WINED3D_GL_VERSION_3_2] && gl_info->limits.combined_samplers < sampler_count)
    {
        /* The minimum value for GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS in OpenGL
         * 3.2 is 48 (16 per stage). When tessellation shaders are supported
         * the minimum value is increased to 80. */
        WARN("Graphics pipeline sampler count %u is greater than combined sampler count %u.\n",
                sampler_count, gl_info->limits.combined_samplers);
3811 3812
        for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i)
            gl_info->limits.samplers[i] = min(gl_info->limits.samplers[i], 16);
3813 3814 3815 3816 3817
    }

    /* A majority of OpenGL implementations allow us to statically partition
     * the set of texture bindings into six separate sets. */
    gl_info->limits.graphics_samplers = gl_info->limits.combined_samplers;
3818 3819 3820
    sampler_count = 0;
    for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i)
        sampler_count += gl_info->limits.samplers[i];
3821 3822
    if (gl_info->limits.combined_samplers >= sampler_count)
        gl_info->limits.graphics_samplers -= gl_info->limits.samplers[WINED3D_SHADER_TYPE_COMPUTE];
3823
}
3824

3825
/* Context activation is done by the caller. */
3826 3827
static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
        struct wined3d_caps_gl_ctx *caps_gl_ctx, DWORD wined3d_creation_flags)
3828
{
3829 3830 3831 3832 3833 3834 3835 3836
    static const struct
    {
        enum wined3d_gl_extension extension;
        DWORD min_gl_version;
    }
    core_extensions[] =
    {
        {EXT_TEXTURE3D,                    MAKEDWORD_VERSION(1, 2)},
3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847
        {ARB_MULTISAMPLE,                  MAKEDWORD_VERSION(1, 3)},
        {ARB_MULTITEXTURE,                 MAKEDWORD_VERSION(1, 3)},
        {ARB_TEXTURE_BORDER_CLAMP,         MAKEDWORD_VERSION(1, 3)},
        {ARB_TEXTURE_COMPRESSION,          MAKEDWORD_VERSION(1, 3)},
        {ARB_TEXTURE_CUBE_MAP,             MAKEDWORD_VERSION(1, 3)},
        {ARB_DEPTH_TEXTURE,                MAKEDWORD_VERSION(1, 4)},
        {ARB_POINT_PARAMETERS,             MAKEDWORD_VERSION(1, 4)},
        {ARB_SHADOW,                       MAKEDWORD_VERSION(1, 4)},
        {ARB_TEXTURE_MIRRORED_REPEAT,      MAKEDWORD_VERSION(1, 4)},
        {EXT_BLEND_COLOR,                  MAKEDWORD_VERSION(1, 4)},
        {EXT_BLEND_FUNC_SEPARATE,          MAKEDWORD_VERSION(1, 4)},
3848 3849
        {EXT_BLEND_MINMAX,                 MAKEDWORD_VERSION(1, 4)},
        {EXT_BLEND_SUBTRACT,               MAKEDWORD_VERSION(1, 4)},
3850
        {EXT_STENCIL_WRAP,                 MAKEDWORD_VERSION(1, 4)},
3851
        {NV_POINT_SPRITE,                  MAKEDWORD_VERSION(1, 4)},
3852 3853 3854 3855 3856
        {ARB_OCCLUSION_QUERY,              MAKEDWORD_VERSION(1, 5)},
        {ARB_VERTEX_BUFFER_OBJECT,         MAKEDWORD_VERSION(1, 5)},
        {ARB_DRAW_BUFFERS,                 MAKEDWORD_VERSION(2, 0)},
        {ARB_FRAGMENT_SHADER,              MAKEDWORD_VERSION(2, 0)},
        {ARB_SHADING_LANGUAGE_100,         MAKEDWORD_VERSION(2, 0)},
3857
        {ARB_TEXTURE_NON_POWER_OF_TWO,     MAKEDWORD_VERSION(2, 0)},
3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872
        {ARB_VERTEX_SHADER,                MAKEDWORD_VERSION(2, 0)},
        {EXT_BLEND_EQUATION_SEPARATE,      MAKEDWORD_VERSION(2, 0)},
        {ARB_PIXEL_BUFFER_OBJECT,          MAKEDWORD_VERSION(2, 1)},
        {EXT_TEXTURE_SRGB,                 MAKEDWORD_VERSION(2, 1)},
        {ARB_COLOR_BUFFER_FLOAT,           MAKEDWORD_VERSION(3, 0)},
        {ARB_DEPTH_BUFFER_FLOAT,           MAKEDWORD_VERSION(3, 0)},
        {ARB_FRAMEBUFFER_OBJECT,           MAKEDWORD_VERSION(3, 0)},
        {ARB_FRAMEBUFFER_SRGB,             MAKEDWORD_VERSION(3, 0)},
        {ARB_HALF_FLOAT_PIXEL,             MAKEDWORD_VERSION(3, 0)},
        {ARB_HALF_FLOAT_VERTEX,            MAKEDWORD_VERSION(3, 0)},
        {ARB_MAP_BUFFER_RANGE,             MAKEDWORD_VERSION(3, 0)},
        {ARB_TEXTURE_COMPRESSION_RGTC,     MAKEDWORD_VERSION(3, 0)},
        {ARB_TEXTURE_FLOAT,                MAKEDWORD_VERSION(3, 0)},
        {ARB_TEXTURE_RG,                   MAKEDWORD_VERSION(3, 0)},
        {EXT_DRAW_BUFFERS2,                MAKEDWORD_VERSION(3, 0)},
3873
        {EXT_PACKED_FLOAT,                 MAKEDWORD_VERSION(3, 0)},
3874
        {EXT_TEXTURE_ARRAY,                MAKEDWORD_VERSION(3, 0)},
3875
        {EXT_TEXTURE_INTEGER,              MAKEDWORD_VERSION(3, 0)},
3876
        {EXT_TEXTURE_SHARED_EXPONENT,      MAKEDWORD_VERSION(3, 0)},
3877 3878 3879 3880 3881 3882 3883 3884
        /* We don't want to enable EXT_GPU_SHADER4: even though similar
         * functionality is available in core GL 3.0 / GLSL 1.30, it's different
         * enough that reusing the same flag for the new features hurts more
         * than it helps. */
        /* EXT_framebuffer_object, EXT_framebuffer_blit,
         * EXT_framebuffer_multisample and EXT_packed_depth_stencil
         * are integrated into ARB_framebuffer_object. */

3885
        {ARB_COPY_BUFFER,                  MAKEDWORD_VERSION(3, 1)},
3886
        {ARB_DRAW_INSTANCED,               MAKEDWORD_VERSION(3, 1)},
3887
        {ARB_TEXTURE_BUFFER_OBJECT,        MAKEDWORD_VERSION(3, 1)},
3888 3889 3890 3891 3892 3893 3894 3895
        {ARB_UNIFORM_BUFFER_OBJECT,        MAKEDWORD_VERSION(3, 1)},
        {EXT_TEXTURE_SNORM,                MAKEDWORD_VERSION(3, 1)},
        /* We don't need or want GL_ARB_texture_rectangle (core in 3.1). */

        {ARB_DRAW_ELEMENTS_BASE_VERTEX,    MAKEDWORD_VERSION(3, 2)},
        /* ARB_geometry_shader4 exposes a somewhat different API compared to 3.2
         * core geometry shaders so it's not really correct to expose the
         * extension for core-only support. */
3896
        {ARB_FRAGMENT_COORD_CONVENTIONS,   MAKEDWORD_VERSION(3, 2)},
3897
        {ARB_PROVOKING_VERTEX,             MAKEDWORD_VERSION(3, 2)},
3898
        {ARB_SEAMLESS_CUBE_MAP,            MAKEDWORD_VERSION(3, 2)},
3899
        {ARB_SYNC,                         MAKEDWORD_VERSION(3, 2)},
3900
        {ARB_TEXTURE_MULTISAMPLE,          MAKEDWORD_VERSION(3, 2)},
3901 3902 3903
        {ARB_VERTEX_ARRAY_BGRA,            MAKEDWORD_VERSION(3, 2)},

        {ARB_BLEND_FUNC_EXTENDED,          MAKEDWORD_VERSION(3, 3)},
3904
        {ARB_EXPLICIT_ATTRIB_LOCATION,     MAKEDWORD_VERSION(3, 3)},
3905 3906 3907
        {ARB_INSTANCED_ARRAYS,             MAKEDWORD_VERSION(3, 3)},
        {ARB_SAMPLER_OBJECTS,              MAKEDWORD_VERSION(3, 3)},
        {ARB_SHADER_BIT_ENCODING,          MAKEDWORD_VERSION(3, 3)},
3908
        {ARB_TEXTURE_RGB10_A2UI,           MAKEDWORD_VERSION(3, 3)},
3909
        {ARB_TEXTURE_SWIZZLE,              MAKEDWORD_VERSION(3, 3)},
3910
        {ARB_TIMER_QUERY,                  MAKEDWORD_VERSION(3, 3)},
3911
        {ARB_VERTEX_TYPE_2_10_10_10_REV,   MAKEDWORD_VERSION(3, 3)},
3912

3913
        {ARB_DRAW_INDIRECT,                MAKEDWORD_VERSION(4, 0)},
3914
        {ARB_GPU_SHADER5,                  MAKEDWORD_VERSION(4, 0)},
3915
        {ARB_TESSELLATION_SHADER,          MAKEDWORD_VERSION(4, 0)},
3916
        {ARB_TEXTURE_CUBE_MAP_ARRAY,       MAKEDWORD_VERSION(4, 0)},
3917
        {ARB_TEXTURE_GATHER,               MAKEDWORD_VERSION(4, 0)},
3918
        {ARB_TRANSFORM_FEEDBACK2,          MAKEDWORD_VERSION(4, 0)},
3919
        {ARB_TRANSFORM_FEEDBACK3,          MAKEDWORD_VERSION(4, 0)},
3920

3921
        {ARB_ES2_COMPATIBILITY,            MAKEDWORD_VERSION(4, 1)},
3922
        {ARB_VIEWPORT_ARRAY,               MAKEDWORD_VERSION(4, 1)},
3923

3924
        {ARB_BASE_INSTANCE,                MAKEDWORD_VERSION(4, 2)},
3925
        {ARB_CONSERVATIVE_DEPTH,           MAKEDWORD_VERSION(4, 2)},
3926
        {ARB_INTERNALFORMAT_QUERY,         MAKEDWORD_VERSION(4, 2)},
3927
        {ARB_MAP_BUFFER_ALIGNMENT,         MAKEDWORD_VERSION(4, 2)},
3928
        {ARB_SHADER_ATOMIC_COUNTERS,       MAKEDWORD_VERSION(4, 2)},
3929
        {ARB_SHADER_IMAGE_LOAD_STORE,      MAKEDWORD_VERSION(4, 2)},
3930
        {ARB_SHADING_LANGUAGE_420PACK,     MAKEDWORD_VERSION(4, 2)},
3931
        {ARB_SHADING_LANGUAGE_PACKING,     MAKEDWORD_VERSION(4, 2)},
3932
        {ARB_TEXTURE_COMPRESSION_BPTC,     MAKEDWORD_VERSION(4, 2)},
3933
        {ARB_TEXTURE_STORAGE,              MAKEDWORD_VERSION(4, 2)},
3934

3935
        {ARB_CLEAR_BUFFER_OBJECT,          MAKEDWORD_VERSION(4, 3)},
3936
        {ARB_COMPUTE_SHADER,               MAKEDWORD_VERSION(4, 3)},
3937
        {ARB_COPY_IMAGE,                   MAKEDWORD_VERSION(4, 3)},
3938
        {ARB_DEBUG_OUTPUT,                 MAKEDWORD_VERSION(4, 3)},
3939
        {ARB_ES3_COMPATIBILITY,            MAKEDWORD_VERSION(4, 3)},
3940
        {ARB_FRAGMENT_LAYER_VIEWPORT,      MAKEDWORD_VERSION(4, 3)},
3941
        {ARB_FRAMEBUFFER_NO_ATTACHMENTS,   MAKEDWORD_VERSION(4, 3)},
3942
        {ARB_INTERNALFORMAT_QUERY2,        MAKEDWORD_VERSION(4, 3)},
3943
        {ARB_SHADER_IMAGE_SIZE,            MAKEDWORD_VERSION(4, 3)},
3944
        {ARB_SHADER_STORAGE_BUFFER_OBJECT, MAKEDWORD_VERSION(4, 3)},
3945
        {ARB_STENCIL_TEXTURING,            MAKEDWORD_VERSION(4, 3)},
3946
        {ARB_TEXTURE_BUFFER_RANGE,         MAKEDWORD_VERSION(4, 3)},
3947
        {ARB_TEXTURE_QUERY_LEVELS,         MAKEDWORD_VERSION(4, 3)},
3948
        {ARB_TEXTURE_STORAGE_MULTISAMPLE,  MAKEDWORD_VERSION(4, 2)},
3949
        {ARB_TEXTURE_VIEW,                 MAKEDWORD_VERSION(4, 3)},
3950

3951 3952
        {ARB_CLEAR_TEXTURE,                MAKEDWORD_VERSION(4, 4)},

3953
        {ARB_CLIP_CONTROL,                 MAKEDWORD_VERSION(4, 5)},
3954
        {ARB_CULL_DISTANCE,                MAKEDWORD_VERSION(4, 5)},
3955
        {ARB_DERIVATIVE_CONTROL,           MAKEDWORD_VERSION(4, 5)},
3956 3957

        {ARB_PIPELINE_STATISTICS_QUERY,    MAKEDWORD_VERSION(4, 6)},
3958
        {ARB_TEXTURE_FILTER_ANISOTROPIC,   MAKEDWORD_VERSION(4, 6)},
3959
    };
3960 3961 3962
    struct wined3d_driver_info *driver_info = &adapter->driver_info;
    const char *gl_vendor_str, *gl_renderer_str, *gl_version_str;
    struct wined3d_gl_info *gl_info = &adapter->gl_info;
3963
    const struct gpu_description *gpu_description;
3964
    struct wined3d_vertex_caps vertex_caps;
3965
    struct fragment_caps fragment_caps;
3966
    struct shader_caps shader_caps;
3967 3968
    const char *WGL_Extensions = NULL;
    enum wined3d_gl_vendor gl_vendor;
3969
    DWORD gl_version, gl_ext_emul_mask;
3970
    UINT64 vram_bytes = 0;
3971
    HDC hdc;
3972
    unsigned int i, j;
3973
    GLint context_profile = 0;
3974

3975 3976
    TRACE("adapter %p.\n", adapter);

3977
    gl_renderer_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_RENDERER);
3978 3979 3980 3981 3982
    TRACE("GL_RENDERER: %s.\n", debugstr_a(gl_renderer_str));
    if (!gl_renderer_str)
    {
        ERR("Received a NULL GL_RENDERER.\n");
        return FALSE;
3983
    }
3984

3985
    gl_vendor_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_VENDOR);
3986 3987
    TRACE("GL_VENDOR: %s.\n", debugstr_a(gl_vendor_str));
    if (!gl_vendor_str)
3988
    {
3989 3990 3991 3992 3993
        ERR("Received a NULL GL_VENDOR.\n");
        return FALSE;
    }

    /* Parse the GL_VERSION field into major and minor information */
3994
    gl_version_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_VERSION);
3995 3996 3997 3998 3999 4000 4001 4002
    TRACE("GL_VERSION: %s.\n", debugstr_a(gl_version_str));
    if (!gl_version_str)
    {
        ERR("Received a NULL GL_VERSION.\n");
        return FALSE;
    }
    gl_version = wined3d_parse_gl_version(gl_version_str);

4003
    load_gl_funcs(gl_info);
4004 4005 4006 4007

    memset(gl_info->supported, 0, sizeof(gl_info->supported));
    gl_info->supported[WINED3D_GL_EXT_NONE] = TRUE;

4008 4009
    if (gl_version >= MAKEDWORD_VERSION(3, 2))
    {
4010
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &context_profile);
4011 4012 4013 4014 4015 4016 4017
        checkGLcall("Querying context profile");
    }
    if (context_profile & GL_CONTEXT_CORE_PROFILE_BIT)
        TRACE("Got a core profile context.\n");
    else
        gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] = TRUE;

4018
    TRACE("GL extensions reported:\n");
4019 4020 4021
    if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
    {
        const char *gl_extensions = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_EXTENSIONS);
4022

4023 4024 4025 4026 4027
        if (!gl_extensions)
        {
            ERR("Received a NULL GL_EXTENSIONS.\n");
            return FALSE;
        }
4028
        parse_extension_string(gl_info, gl_extensions, gl_extension_map, ARRAY_SIZE(gl_extension_map));
4029 4030 4031
    }
    else
    {
4032
        enumerate_gl_extensions(gl_info, gl_extension_map, ARRAY_SIZE(gl_extension_map));
4033
    }
4034

4035
    hdc = wglGetCurrentDC();
4036 4037
    /* Not all GL drivers might offer WGL extensions e.g. VirtualBox. */
    if (GL_EXTCALL(wglGetExtensionsStringARB))
4038
        WGL_Extensions = (const char *)GL_EXTCALL(wglGetExtensionsStringARB(hdc));
4039 4040
    if (!WGL_Extensions)
        WARN("WGL extensions not supported.\n");
4041
    else
4042
        parse_extension_string(gl_info, WGL_Extensions, wgl_extension_map, ARRAY_SIZE(wgl_extension_map));
4043

4044
    for (i = 0; i < ARRAY_SIZE(core_extensions); ++i)
4045
    {
4046 4047 4048 4049 4050 4051
        if (!gl_info->supported[core_extensions[i].extension]
                && gl_version >= core_extensions[i].min_gl_version)
        {
            for (j = 0; j < ARRAY_SIZE(gl_extension_map); ++j)
                if (gl_extension_map[j].extension == core_extensions[i].extension)
                    break;
4052

4053 4054 4055 4056 4057 4058 4059 4060 4061 4062
            if (j < ARRAY_SIZE(gl_extension_map))
            {
                TRACE("GL CORE: %s support.\n", gl_extension_map[j].extension_string);
                gl_info->supported[core_extensions[i].extension] = TRUE;
            }
            else
            {
                FIXME("GL extension %u not in the GL extensions map.\n", core_extensions[i].extension);
            }
        }
4063 4064
    }

4065 4066 4067 4068 4069
    if (gl_info->supported[EXT_BLEND_MINMAX] || gl_info->supported[EXT_BLEND_SUBTRACT])
        gl_info->supported[WINED3D_GL_BLEND_EQUATION] = TRUE;

    if (gl_version >= MAKEDWORD_VERSION(2, 0))
        gl_info->supported[WINED3D_GL_VERSION_2_0] = TRUE;
4070 4071
    if (gl_version >= MAKEDWORD_VERSION(3, 2))
        gl_info->supported[WINED3D_GL_VERSION_3_2] = TRUE;
4072

4073 4074 4075 4076 4077
    /* All the points are actually point sprites in core contexts, the APIs from
     * ARB_point_sprite are not supported anymore. */
    if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
        gl_info->supported[ARB_POINT_SPRITE] = FALSE;

4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123
    if (gl_info->supported[APPLE_FENCE])
    {
        /* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
         * The apple extension interacts with some other apple exts. Disable the NV
         * extension if the apple one is support to prevent confusion in other parts
         * of the code. */
        gl_info->supported[NV_FENCE] = FALSE;
    }
    if (gl_info->supported[APPLE_FLOAT_PIXELS])
    {
        /* GL_APPLE_float_pixels == GL_ARB_texture_float + GL_ARB_half_float_pixel
         *
         * The enums are the same:
         * GL_RGBA16F_ARB     = GL_RGBA_FLOAT16_APPLE = 0x881a
         * GL_RGB16F_ARB      = GL_RGB_FLOAT16_APPLE  = 0x881b
         * GL_RGBA32F_ARB     = GL_RGBA_FLOAT32_APPLE = 0x8814
         * GL_RGB32F_ARB      = GL_RGB_FLOAT32_APPLE  = 0x8815
         * GL_HALF_FLOAT_ARB  = GL_HALF_APPLE         = 0x140b
         */
        if (!gl_info->supported[ARB_TEXTURE_FLOAT])
        {
            TRACE(" IMPLIED: GL_ARB_texture_float support (by GL_APPLE_float_pixels).\n");
            gl_info->supported[ARB_TEXTURE_FLOAT] = TRUE;
        }
        if (!gl_info->supported[ARB_HALF_FLOAT_PIXEL])
        {
            TRACE(" IMPLIED: GL_ARB_half_float_pixel support (by GL_APPLE_float_pixels).\n");
            gl_info->supported[ARB_HALF_FLOAT_PIXEL] = TRUE;
        }
    }
    if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
    {
        /* GL_ARB_map_buffer_range and GL_APPLE_flush_buffer_range provide the same
         * functionality. Prefer the ARB extension */
        gl_info->supported[APPLE_FLUSH_BUFFER_RANGE] = FALSE;
    }
    if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
    {
        TRACE(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support.\n");
        gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
    }
    if (!gl_info->supported[ARB_VERTEX_ARRAY_BGRA] && gl_info->supported[EXT_VERTEX_ARRAY_BGRA])
    {
        TRACE(" IMPLIED: ARB_vertex_array_bgra support (by EXT_vertex_array_bgra).\n");
        gl_info->supported[ARB_VERTEX_ARRAY_BGRA] = TRUE;
    }
4124 4125 4126 4127 4128
    if (!gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC] && gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC])
    {
        TRACE(" IMPLIED: EXT_texture_compression_rgtc support (by ARB_texture_compression_rgtc).\n");
        gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC] = TRUE;
    }
4129 4130 4131 4132 4133
    if (!gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] && gl_info->supported[EXT_TEXTURE_COMPRESSION_RGTC])
    {
        TRACE(" IMPLIED: ARB_texture_compression_rgtc support (by EXT_texture_compression_rgtc).\n");
        gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] = TRUE;
    }
4134 4135 4136 4137 4138
    if (gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] && !gl_info->supported[ARB_TEXTURE_RG])
    {
        TRACE("ARB_texture_rg not supported, disabling ARB_texture_compression_rgtc.\n");
        gl_info->supported[ARB_TEXTURE_COMPRESSION_RGTC] = FALSE;
    }
4139 4140 4141 4142 4143 4144 4145 4146 4147
    if (gl_info->supported[NV_TEXTURE_SHADER2])
    {
        if (gl_info->supported[NV_REGISTER_COMBINERS])
        {
            /* Also disable ATI_FRAGMENT_SHADER if register combiners and texture_shader2
             * are supported. The nv extensions provide the same functionality as the
             * ATI one, and a bit more(signed pixelformats). */
            gl_info->supported[ATI_FRAGMENT_SHADER] = FALSE;
        }
4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172
    }
    if (gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
    {
        /* If we have full NP2 texture support, disable
         * GL_ARB_texture_rectangle because we will never use it.
         * This saves a few redundant glDisable calls. */
        gl_info->supported[ARB_TEXTURE_RECTANGLE] = FALSE;
    }
    if (gl_info->supported[ATI_FRAGMENT_SHADER])
    {
        /* Disable NV_register_combiners and fragment shader if this is supported.
         * generally the NV extensions are preferred over the ATI ones, and this
         * extension is disabled if register_combiners and texture_shader2 are both
         * supported. So we reach this place only if we have incomplete NV dxlevel 8
         * fragment processing support. */
        gl_info->supported[NV_REGISTER_COMBINERS] = FALSE;
        gl_info->supported[NV_REGISTER_COMBINERS2] = FALSE;
        gl_info->supported[NV_TEXTURE_SHADER] = FALSE;
        gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
    }
    if (gl_info->supported[NV_HALF_FLOAT])
    {
        /* GL_ARB_half_float_vertex is a subset of GL_NV_half_float. */
        gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE;
    }
4173 4174 4175 4176 4177
    if (gl_info->supported[ARB_FRAMEBUFFER_SRGB] && !gl_info->supported[EXT_TEXTURE_SRGB_DECODE])
    {
        /* Current wined3d sRGB infrastructure requires EXT_texture_sRGB_decode
         * for GL_ARB_framebuffer_sRGB support (without EXT_texture_sRGB_decode
         * we never render to sRGB surfaces). */
4178
        TRACE("EXT_texture_sRGB_decode is not supported, disabling ARB_framebuffer_sRGB.\n");
4179 4180
        gl_info->supported[ARB_FRAMEBUFFER_SRGB] = FALSE;
    }
4181 4182 4183 4184
    if (gl_info->supported[ARB_OCCLUSION_QUERY])
    {
        GLint counter_bits;

4185
        GL_EXTCALL(glGetQueryiv(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &counter_bits));
4186 4187 4188 4189
        TRACE("Occlusion query counter has %d bits.\n", counter_bits);
        if (!counter_bits)
            gl_info->supported[ARB_OCCLUSION_QUERY] = FALSE;
    }
4190 4191 4192 4193
    if (gl_info->supported[ARB_TIMER_QUERY])
    {
        GLint counter_bits;

4194
        GL_EXTCALL(glGetQueryiv(GL_TIMESTAMP, GL_QUERY_COUNTER_BITS, &counter_bits));
4195 4196 4197 4198
        TRACE("Timestamp query counter has %d bits.\n", counter_bits);
        if (!counter_bits)
            gl_info->supported[ARB_TIMER_QUERY] = FALSE;
    }
4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214
    if (gl_version >= MAKEDWORD_VERSION(3, 0))
    {
        GLint counter_bits;

        gl_info->supported[WINED3D_GL_PRIMITIVE_QUERY] = TRUE;

        GL_EXTCALL(glGetQueryiv(GL_PRIMITIVES_GENERATED, GL_QUERY_COUNTER_BITS, &counter_bits));
        TRACE("Primitives query counter has %d bits.\n", counter_bits);
        if (!counter_bits)
            gl_info->supported[WINED3D_GL_PRIMITIVE_QUERY] = FALSE;

        GL_EXTCALL(glGetQueryiv(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_QUERY_COUNTER_BITS, &counter_bits));
        TRACE("Transform feedback primitives query counter has %d bits.\n", counter_bits);
        if (!counter_bits)
            gl_info->supported[WINED3D_GL_PRIMITIVE_QUERY] = FALSE;
    }
4215 4216 4217 4218 4219 4220
    if (gl_info->supported[ARB_VIEWPORT_ARRAY])
    {
        GLint subpixel_bits;

        gl_info->gl_ops.gl.p_glGetIntegerv(GL_VIEWPORT_SUBPIXEL_BITS, &subpixel_bits);
        TRACE("Viewport supports %d subpixel bits.\n", subpixel_bits);
4221 4222 4223 4224 4225
        if (subpixel_bits < 8 && gl_info->supported[ARB_CLIP_CONTROL])
        {
            TRACE("Disabling ARB_clip_control because viewport subpixel bits < 8.\n");
            gl_info->supported[ARB_CLIP_CONTROL] = FALSE;
        }
4226 4227 4228 4229 4230 4231 4232 4233 4234
    }
    if (gl_info->supported[ARB_CLIP_CONTROL] && !gl_info->supported[ARB_VIEWPORT_ARRAY])
    {
        /* When using ARB_clip_control we need the float viewport parameters
         * introduced by ARB_viewport_array to take care of the shifted pixel
         * coordinates. */
        TRACE("Disabling ARB_clip_control because ARB_viewport_array is not supported.\n");
        gl_info->supported[ARB_CLIP_CONTROL] = FALSE;
    }
4235 4236 4237 4238 4239 4240
    if (gl_info->supported[ARB_STENCIL_TEXTURING] && !gl_info->supported[ARB_TEXTURE_SWIZZLE])
    {
        /* The stencil value needs to be placed in the green channel.  */
        TRACE("Disabling ARB_stencil_texturing because ARB_texture_swizzle is not supported.\n");
        gl_info->supported[ARB_STENCIL_TEXTURING] = FALSE;
    }
4241 4242 4243 4244 4245
    if (!gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] && gl_info->supported[EXT_TEXTURE_MIRROR_CLAMP])
    {
        TRACE(" IMPLIED: ATI_texture_mirror_once support (by EXT_texture_mirror_clamp).\n");
        gl_info->supported[ATI_TEXTURE_MIRROR_ONCE] = TRUE;
    }
4246 4247 4248 4249 4250
    if (!gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE] && gl_info->supported[ATI_TEXTURE_MIRROR_ONCE])
    {
        TRACE(" IMPLIED: ARB_texture_mirror_clamp_to_edge support (by ATI_texture_mirror_once).\n");
        gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE] = TRUE;
    }
4251 4252 4253
    if (gl_info->supported[ARB_TEXTURE_STORAGE] && gl_info->supported[APPLE_YCBCR_422])
    {
        /* AFAIK APPLE_ycbcr_422 is only available in legacy contexts so we shouldn't ever hit this. */
4254
        ERR("Disabling APPLE_ycbcr_422 because of ARB_texture_storage.\n");
4255 4256
        gl_info->supported[APPLE_YCBCR_422] = FALSE;
    }
4257 4258 4259 4260 4261 4262 4263 4264
    if (gl_info->supported[ARB_DRAW_INDIRECT] && !gl_info->supported[ARB_BASE_INSTANCE])
    {
        /* If ARB_base_instance is not supported the baseInstance field
         * in indirect draw parameters must be 0 or behavior is undefined.
         */
        WARN("Disabling ARB_draw_indirect because ARB_base_instance is not supported.\n");
        gl_info->supported[ARB_DRAW_INDIRECT] = FALSE;
    }
4265 4266
    if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE] && !wined3d_settings.multisample_textures)
        gl_info->supported[ARB_TEXTURE_MULTISAMPLE] = FALSE;
4267 4268 4269 4270 4271
    if (gl_info->supported[ARB_TEXTURE_MULTISAMPLE] && !gl_info->supported[ARB_TEXTURE_STORAGE_MULTISAMPLE])
    {
        WARN("Disabling ARB_texture_multisample because immutable storage is not supported.\n");
        gl_info->supported[ARB_TEXTURE_MULTISAMPLE] = FALSE;
    }
4272 4273 4274 4275 4276 4277 4278 4279

    wined3d_adapter_init_limits(gl_info);

    if (gl_info->supported[ARB_VERTEX_PROGRAM] && test_arb_vs_offset_limit(gl_info))
        gl_info->quirks |= WINED3D_QUIRK_ARB_VS_OFFSET_LIMIT;

    if (gl_info->supported[ARB_SHADING_LANGUAGE_100])
    {
4280
        const char *str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_SHADING_LANGUAGE_VERSION_ARB);
4281 4282 4283 4284 4285 4286 4287
        unsigned int major, minor;

        TRACE("GLSL version string: %s.\n", debugstr_a(str));

        /* The format of the GLSL version string is "major.minor[.release] [vendor info]". */
        sscanf(str, "%u.%u", &major, &minor);
        gl_info->glsl_version = MAKEDWORD_VERSION(major, minor);
4288 4289
        if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 30))
            gl_info->supported[WINED3D_GLSL_130] = TRUE;
4290 4291
    }

4292
    checkGLcall("extension detection");
4293

4294
    adapter->shader_backend = select_shader_backend(gl_info);
4295
    adapter->vertex_pipe = select_vertex_implementation(gl_info, adapter->shader_backend);
4296
    adapter->fragment_pipe = select_fragment_implementation(gl_info, adapter->shader_backend);
4297

4298
    adapter->shader_backend->shader_get_caps(gl_info, &shader_caps);
4299
    adapter->d3d_info.vs_clipping = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_VS_CLIPPING;
4300
    adapter->d3d_info.limits.vs_version = shader_caps.vs_version;
4301
    adapter->d3d_info.limits.hs_version = shader_caps.hs_version;
4302
    adapter->d3d_info.limits.ds_version = shader_caps.ds_version;
4303 4304
    adapter->d3d_info.limits.gs_version = shader_caps.gs_version;
    adapter->d3d_info.limits.ps_version = shader_caps.ps_version;
4305
    adapter->d3d_info.limits.cs_version = shader_caps.cs_version;
4306 4307
    adapter->d3d_info.limits.vs_uniform_count = shader_caps.vs_uniform_count;
    adapter->d3d_info.limits.ps_uniform_count = shader_caps.ps_uniform_count;
4308
    adapter->d3d_info.limits.varying_count = shader_caps.varying_count;
4309
    adapter->d3d_info.shader_double_precision = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_DOUBLE_PRECISION;
4310

4311 4312
    adapter->vertex_pipe->vp_get_caps(gl_info, &vertex_caps);
    adapter->d3d_info.xyzrhw = vertex_caps.xyzrhw;
4313
    adapter->d3d_info.ffp_generic_attributes = vertex_caps.ffp_generic_attributes;
4314
    adapter->d3d_info.limits.ffp_vertex_blend_matrices = vertex_caps.max_vertex_blend_matrices;
4315
    adapter->d3d_info.limits.active_light_count = vertex_caps.max_active_lights;
4316
    adapter->d3d_info.emulated_flatshading = vertex_caps.emulated_flatshading;
4317

4318
    adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
4319
    adapter->d3d_info.limits.ffp_blend_stages = fragment_caps.MaxTextureBlendStages;
4320
    adapter->d3d_info.limits.ffp_textures = fragment_caps.MaxSimultaneousTextures;
4321
    adapter->d3d_info.shader_color_key = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_COLOR_KEY;
4322
    adapter->d3d_info.wined3d_creation_flags = wined3d_creation_flags;
4323
    TRACE("Max texture stages: %u.\n", adapter->d3d_info.limits.ffp_blend_stages);
4324

4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335
    adapter->d3d_info.valid_rt_mask = 0;
    for (i = 0; i < gl_info->limits.buffers; ++i)
        adapter->d3d_info.valid_rt_mask |= (1u << i);

    if (!adapter->d3d_info.shader_color_key)
    {
        /* We do not want to deal with re-creating immutable texture storage for color keying emulation. */
        WARN("Disabling ARB_texture_storage because fragment pipe doesn't support color keying.\n");
        gl_info->supported[ARB_TEXTURE_STORAGE] = FALSE;
    }

4336 4337
    if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
    {
4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352
        gl_info->fbo_ops.glIsRenderbuffer = gl_info->gl_ops.ext.p_glIsRenderbuffer;
        gl_info->fbo_ops.glBindRenderbuffer = gl_info->gl_ops.ext.p_glBindRenderbuffer;
        gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->gl_ops.ext.p_glDeleteRenderbuffers;
        gl_info->fbo_ops.glGenRenderbuffers = gl_info->gl_ops.ext.p_glGenRenderbuffers;
        gl_info->fbo_ops.glRenderbufferStorage = gl_info->gl_ops.ext.p_glRenderbufferStorage;
        gl_info->fbo_ops.glRenderbufferStorageMultisample = gl_info->gl_ops.ext.p_glRenderbufferStorageMultisample;
        gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->gl_ops.ext.p_glGetRenderbufferParameteriv;
        gl_info->fbo_ops.glIsFramebuffer = gl_info->gl_ops.ext.p_glIsFramebuffer;
        gl_info->fbo_ops.glBindFramebuffer = gl_info->gl_ops.ext.p_glBindFramebuffer;
        gl_info->fbo_ops.glDeleteFramebuffers = gl_info->gl_ops.ext.p_glDeleteFramebuffers;
        gl_info->fbo_ops.glGenFramebuffers = gl_info->gl_ops.ext.p_glGenFramebuffers;
        gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->gl_ops.ext.p_glCheckFramebufferStatus;
        gl_info->fbo_ops.glFramebufferTexture1D = gl_info->gl_ops.ext.p_glFramebufferTexture1D;
        gl_info->fbo_ops.glFramebufferTexture2D = gl_info->gl_ops.ext.p_glFramebufferTexture2D;
        gl_info->fbo_ops.glFramebufferTexture3D = gl_info->gl_ops.ext.p_glFramebufferTexture3D;
4353
        gl_info->fbo_ops.glFramebufferTextureLayer = gl_info->gl_ops.ext.p_glFramebufferTextureLayer;
4354 4355 4356 4357 4358
        gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->gl_ops.ext.p_glFramebufferRenderbuffer;
        gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv
                = gl_info->gl_ops.ext.p_glGetFramebufferAttachmentParameteriv;
        gl_info->fbo_ops.glBlitFramebuffer = gl_info->gl_ops.ext.p_glBlitFramebuffer;
        gl_info->fbo_ops.glGenerateMipmap = gl_info->gl_ops.ext.p_glGenerateMipmap;
4359
        gl_info->fbo_ops.glFramebufferTexture = gl_info->gl_ops.ext.p_glFramebufferTexture;
4360 4361 4362 4363 4364
    }
    else
    {
        if (gl_info->supported[EXT_FRAMEBUFFER_OBJECT])
        {
4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382
            gl_info->fbo_ops.glIsRenderbuffer = gl_info->gl_ops.ext.p_glIsRenderbufferEXT;
            gl_info->fbo_ops.glBindRenderbuffer = gl_info->gl_ops.ext.p_glBindRenderbufferEXT;
            gl_info->fbo_ops.glDeleteRenderbuffers = gl_info->gl_ops.ext.p_glDeleteRenderbuffersEXT;
            gl_info->fbo_ops.glGenRenderbuffers = gl_info->gl_ops.ext.p_glGenRenderbuffersEXT;
            gl_info->fbo_ops.glRenderbufferStorage = gl_info->gl_ops.ext.p_glRenderbufferStorageEXT;
            gl_info->fbo_ops.glGetRenderbufferParameteriv = gl_info->gl_ops.ext.p_glGetRenderbufferParameterivEXT;
            gl_info->fbo_ops.glIsFramebuffer = gl_info->gl_ops.ext.p_glIsFramebufferEXT;
            gl_info->fbo_ops.glBindFramebuffer = gl_info->gl_ops.ext.p_glBindFramebufferEXT;
            gl_info->fbo_ops.glDeleteFramebuffers = gl_info->gl_ops.ext.p_glDeleteFramebuffersEXT;
            gl_info->fbo_ops.glGenFramebuffers = gl_info->gl_ops.ext.p_glGenFramebuffersEXT;
            gl_info->fbo_ops.glCheckFramebufferStatus = gl_info->gl_ops.ext.p_glCheckFramebufferStatusEXT;
            gl_info->fbo_ops.glFramebufferTexture1D = gl_info->gl_ops.ext.p_glFramebufferTexture1DEXT;
            gl_info->fbo_ops.glFramebufferTexture2D = gl_info->gl_ops.ext.p_glFramebufferTexture2DEXT;
            gl_info->fbo_ops.glFramebufferTexture3D = gl_info->gl_ops.ext.p_glFramebufferTexture3DEXT;
            gl_info->fbo_ops.glFramebufferRenderbuffer = gl_info->gl_ops.ext.p_glFramebufferRenderbufferEXT;
            gl_info->fbo_ops.glGetFramebufferAttachmentParameteriv
                    = gl_info->gl_ops.ext.p_glGetFramebufferAttachmentParameterivEXT;
            gl_info->fbo_ops.glGenerateMipmap = gl_info->gl_ops.ext.p_glGenerateMipmapEXT;
4383 4384 4385
        }
        else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
        {
4386
            WARN_(d3d_perf)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n");
4387 4388
            wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
        }
4389 4390 4391

        if (gl_info->supported[ARB_GEOMETRY_SHADER4])
        {
4392
            gl_info->fbo_ops.glFramebufferTexture = gl_info->gl_ops.ext.p_glFramebufferTextureARB;
4393 4394
            gl_info->fbo_ops.glFramebufferTextureLayer = gl_info->gl_ops.ext.p_glFramebufferTextureLayerARB;
        }
4395 4396
        if (gl_info->supported[EXT_FRAMEBUFFER_BLIT])
        {
4397
            gl_info->fbo_ops.glBlitFramebuffer = gl_info->gl_ops.ext.p_glBlitFramebufferEXT;
4398 4399 4400
        }
        if (gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE])
        {
4401 4402
            gl_info->fbo_ops.glRenderbufferStorageMultisample
                    = gl_info->gl_ops.ext.p_glRenderbufferStorageMultisampleEXT;
4403
        }
4404 4405
    }

4406 4407
    gl_info->wrap_lookup[WINED3D_TADDRESS_WRAP - WINED3D_TADDRESS_WRAP] = GL_REPEAT;
    gl_info->wrap_lookup[WINED3D_TADDRESS_MIRROR - WINED3D_TADDRESS_WRAP] =
4408
            gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT;
4409 4410
    gl_info->wrap_lookup[WINED3D_TADDRESS_CLAMP - WINED3D_TADDRESS_WRAP] = GL_CLAMP_TO_EDGE;
    gl_info->wrap_lookup[WINED3D_TADDRESS_BORDER - WINED3D_TADDRESS_WRAP] =
4411
            gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
4412
    gl_info->wrap_lookup[WINED3D_TADDRESS_MIRROR_ONCE - WINED3D_TADDRESS_WRAP] =
4413
            gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE] ? GL_MIRROR_CLAMP_TO_EDGE : GL_REPEAT;
4414

4415 4416 4417 4418 4419 4420 4421 4422 4423
    if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
    {
        GLuint vao;

        GL_EXTCALL(glGenVertexArrays(1, &vao));
        GL_EXTCALL(glBindVertexArray(vao));
        checkGLcall("creating VAO");
    }

4424
    gl_vendor = wined3d_guess_gl_vendor(gl_info, gl_vendor_str, gl_renderer_str, gl_version_str);
4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441
    TRACE("Guessed GL vendor %#x.\n", gl_vendor);

    if (!(gpu_description = query_gpu_description(gl_info, &vram_bytes)))
    {
        enum wined3d_pci_vendor vendor;
        enum wined3d_pci_device device;

        vendor = wined3d_guess_card_vendor(gl_vendor_str, gl_renderer_str);
        TRACE("Guessed vendor PCI ID 0x%04x.\n", vendor);

        device = wined3d_guess_card(&shader_caps, &fragment_caps, gl_info->glsl_version,
                gl_renderer_str, &gl_vendor, &vendor);
        TRACE("Guessed device PCI ID 0x%04x.\n", device);

        if (!(gpu_description = get_gpu_description(vendor, device)))
        {
            ERR("Card %04x:%04x not found in driver DB.\n", vendor, device);
4442
            return FALSE;
4443 4444
        }
    }
4445 4446
    fixup_extensions(gl_info, caps_gl_ctx, gl_renderer_str, gl_vendor,
            gpu_description->vendor, gpu_description->card);
4447 4448
    init_driver_info(driver_info, gpu_description, vram_bytes);

4449 4450 4451 4452 4453 4454
    gl_ext_emul_mask = adapter->vertex_pipe->vp_get_emul_mask(gl_info)
            | adapter->fragment_pipe->get_emul_mask(gl_info);
    if (gl_ext_emul_mask & GL_EXT_EMUL_ARB_MULTITEXTURE)
        install_gl_compat_wrapper(gl_info, ARB_MULTITEXTURE);
    if (gl_ext_emul_mask & GL_EXT_EMUL_EXT_FOG_COORD)
        install_gl_compat_wrapper(gl_info, EXT_FOG_COORD);
4455

4456
    return TRUE;
4457 4458
}

4459 4460
UINT CDECL wined3d_get_adapter_count(const struct wined3d *wined3d)
{
4461
    TRACE("wined3d %p, reporting %u adapters.\n",
4462
            wined3d, wined3d->adapter_count);
4463

4464
    return wined3d->adapter_count;
4465 4466
}

4467
HRESULT CDECL wined3d_register_software_device(struct wined3d *wined3d, void *init_function)
4468
{
4469
    FIXME("wined3d %p, init_function %p stub!\n", wined3d, init_function);
4470

4471
    return WINED3D_OK;
4472 4473
}

4474 4475
HRESULT CDECL wined3d_get_output_desc(const struct wined3d *wined3d, unsigned int adapter_idx,
        struct wined3d_output_desc *desc)
4476
{
4477 4478 4479 4480 4481 4482 4483
    enum wined3d_display_rotation rotation;
    const struct wined3d_adapter *adapter;
    struct wined3d_display_mode mode;
    HMONITOR monitor;
    HRESULT hr;

    TRACE("wined3d %p, adapter_idx %u, desc %p.\n", wined3d, adapter_idx, desc);
4484

4485
    if (adapter_idx >= wined3d->adapter_count)
4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502
        return WINED3DERR_INVALIDCALL;

    adapter = &wined3d->adapters[adapter_idx];
    if (!(monitor = MonitorFromPoint(adapter->monitor_position, MONITOR_DEFAULTTOPRIMARY)))
        return WINED3DERR_INVALIDCALL;

    if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx, &mode, &rotation)))
        return hr;

    memcpy(desc->device_name, adapter->DeviceName, sizeof(desc->device_name));
    SetRect(&desc->desktop_rect, 0, 0, mode.width, mode.height);
    OffsetRect(&desc->desktop_rect, adapter->monitor_position.x, adapter->monitor_position.y);
    /* FIXME: We should get this from EnumDisplayDevices() when the adapters
     * are created. */
    desc->attached_to_desktop = TRUE;
    desc->rotation = rotation;
    desc->monitor = monitor;
4503

4504
    return WINED3D_OK;
4505 4506
}

4507
/* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
4508 4509
     of the same bpp but different resolutions                                  */

4510
/* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
4511
UINT CDECL wined3d_get_adapter_mode_count(const struct wined3d *wined3d, UINT adapter_idx,
4512
        enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering)
4513
{
4514 4515 4516 4517 4518 4519 4520
    const struct wined3d_adapter *adapter;
    const struct wined3d_format *format;
    unsigned int i = 0;
    unsigned int j = 0;
    UINT format_bits;
    DEVMODEW mode;

4521 4522
    TRACE("wined3d %p, adapter_idx %u, format %s, scanline_ordering %#x.\n",
            wined3d, adapter_idx, debug_d3dformat(format_id), scanline_ordering);
4523

4524
    if (adapter_idx >= wined3d->adapter_count)
4525 4526
        return 0;

4527
    adapter = &wined3d->adapters[adapter_idx];
4528
    format = wined3d_get_format(&adapter->gl_info, format_id, WINED3DUSAGE_RENDERTARGET);
4529
    format_bits = format->byte_count * CHAR_BIT;
4530

4531 4532
    memset(&mode, 0, sizeof(mode));
    mode.dmSize = sizeof(mode);
4533

4534 4535
    while (EnumDisplaySettingsExW(adapter->DeviceName, j++, &mode, 0))
    {
4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546
        if (mode.dmFields & DM_DISPLAYFLAGS)
        {
            if (scanline_ordering == WINED3D_SCANLINE_ORDERING_PROGRESSIVE
                    && (mode.u2.dmDisplayFlags & DM_INTERLACED))
                continue;

            if (scanline_ordering == WINED3D_SCANLINE_ORDERING_INTERLACED
                    && !(mode.u2.dmDisplayFlags & DM_INTERLACED))
                continue;
        }

4547
        if (format_id == WINED3DFMT_UNKNOWN)
4548
        {
4549 4550 4551 4552 4553 4554
            /* This is for d3d8, do not enumerate P8 here. */
            if (mode.dmBitsPerPel == 32 || mode.dmBitsPerPel == 16) ++i;
        }
        else if (mode.dmBitsPerPel == format_bits)
        {
            ++i;
4555
        }
4556 4557
    }

4558 4559 4560
    TRACE("Returning %u matching modes (out of %u total) for adapter %u.\n", i, j, adapter_idx);

    return i;
4561 4562
}

4563
/* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
4564
HRESULT CDECL wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT adapter_idx,
4565 4566
        enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering,
        UINT mode_idx, struct wined3d_display_mode *mode)
4567
{
4568 4569 4570 4571 4572 4573 4574
    const struct wined3d_adapter *adapter;
    const struct wined3d_format *format;
    UINT format_bits;
    DEVMODEW m;
    UINT i = 0;
    int j = 0;

4575 4576
    TRACE("wined3d %p, adapter_idx %u, format %s, scanline_ordering %#x, mode_idx %u, mode %p.\n",
            wined3d, adapter_idx, debug_d3dformat(format_id), scanline_ordering, mode_idx, mode);
4577

4578
    if (!mode || adapter_idx >= wined3d->adapter_count)
4579
        return WINED3DERR_INVALIDCALL;
4580

4581
    adapter = &wined3d->adapters[adapter_idx];
4582
    format = wined3d_get_format(&adapter->gl_info, format_id, WINED3DUSAGE_RENDERTARGET);
4583
    format_bits = format->byte_count * CHAR_BIT;
4584

4585 4586
    memset(&m, 0, sizeof(m));
    m.dmSize = sizeof(m);
4587

4588 4589 4590
    while (i <= mode_idx)
    {
        if (!EnumDisplaySettingsExW(adapter->DeviceName, j++, &m, 0))
4591
        {
4592 4593
            WARN("Invalid mode_idx %u.\n", mode_idx);
            return WINED3DERR_INVALIDCALL;
4594 4595
        }

4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606
        if (m.dmFields & DM_DISPLAYFLAGS)
        {
            if (scanline_ordering == WINED3D_SCANLINE_ORDERING_PROGRESSIVE
                    && (m.u2.dmDisplayFlags & DM_INTERLACED))
                continue;

            if (scanline_ordering == WINED3D_SCANLINE_ORDERING_INTERLACED
                    && !(m.u2.dmDisplayFlags & DM_INTERLACED))
                continue;
        }

4607
        if (format_id == WINED3DFMT_UNKNOWN)
4608 4609 4610 4611 4612 4613 4614 4615 4616
        {
            /* This is for d3d8, do not enumerate P8 here. */
            if (m.dmBitsPerPel == 32 || m.dmBitsPerPel == 16) ++i;
        }
        else if (m.dmBitsPerPel == format_bits)
        {
            ++i;
        }
    }
4617

4618 4619 4620 4621 4622
    mode->width = m.dmPelsWidth;
    mode->height = m.dmPelsHeight;
    mode->refresh_rate = DEFAULT_REFRESH_RATE;
    if (m.dmFields & DM_DISPLAYFREQUENCY)
        mode->refresh_rate = m.dmDisplayFrequency;
4623

4624 4625
    if (format_id == WINED3DFMT_UNKNOWN)
        mode->format_id = pixelformat_for_depth(m.dmBitsPerPel);
4626
    else
4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637
        mode->format_id = format_id;

    if (!(m.dmFields & DM_DISPLAYFLAGS))
        mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
    else if (m.u2.dmDisplayFlags & DM_INTERLACED)
        mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_INTERLACED;
    else
        mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_PROGRESSIVE;

    TRACE("%ux%u@%u %u bpp, %s %#x.\n", mode->width, mode->height, mode->refresh_rate,
            m.dmBitsPerPel, debug_d3dformat(mode->format_id), mode->scanline_ordering);
4638

4639
    return WINED3D_OK;
4640 4641
}

4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658
HRESULT CDECL wined3d_find_closest_matching_adapter_mode(const struct wined3d *wined3d,
        unsigned int adapter_idx, struct wined3d_display_mode *mode)
{
    unsigned int i, j, mode_count, matching_mode_count, closest;
    struct wined3d_display_mode **matching_modes;
    struct wined3d_display_mode *modes;
    HRESULT hr;

    TRACE("wined3d %p, adapter_idx %u, mode %p.\n", wined3d, adapter_idx, mode);

    if (!(mode_count = wined3d_get_adapter_mode_count(wined3d, adapter_idx,
            mode->format_id, WINED3D_SCANLINE_ORDERING_UNKNOWN)))
    {
        WARN("Adapter has 0 matching modes.\n");
        return E_FAIL;
    }

4659
    if (!(modes = heap_calloc(mode_count, sizeof(*modes))))
4660
        return E_OUTOFMEMORY;
4661
    if (!(matching_modes = heap_calloc(mode_count, sizeof(*matching_modes))))
4662
    {
4663
        heap_free(modes);
4664 4665 4666 4667 4668 4669 4670 4671
        return E_OUTOFMEMORY;
    }

    for (i = 0; i < mode_count; ++i)
    {
        if (FAILED(hr = wined3d_enum_adapter_modes(wined3d, adapter_idx,
                mode->format_id, WINED3D_SCANLINE_ORDERING_UNKNOWN, i, &modes[i])))
        {
4672 4673
            heap_free(matching_modes);
            heap_free(modes);
4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708
            return hr;
        }
        matching_modes[i] = &modes[i];
    }

    matching_mode_count = mode_count;

    if (mode->scanline_ordering != WINED3D_SCANLINE_ORDERING_UNKNOWN)
    {
        for (i = 0, j = 0; i < matching_mode_count; ++i)
        {
            if (matching_modes[i]->scanline_ordering == mode->scanline_ordering)
                matching_modes[j++] = matching_modes[i];
        }
        if (j > 0)
            matching_mode_count = j;
    }

    if (mode->refresh_rate)
    {
        for (i = 0, j = 0; i < matching_mode_count; ++i)
        {
            if (matching_modes[i]->refresh_rate == mode->refresh_rate)
                matching_modes[j++] = matching_modes[i];
        }
        if (j > 0)
            matching_mode_count = j;
    }

    if (!mode->width || !mode->height)
    {
        struct wined3d_display_mode current_mode;
        if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx,
                &current_mode, NULL)))
        {
4709 4710
            heap_free(matching_modes);
            heap_free(modes);
4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731
            return hr;
        }
        mode->width = current_mode.width;
        mode->height = current_mode.height;
    }

    closest = ~0u;
    for (i = 0, j = 0; i < matching_mode_count; ++i)
    {
        unsigned int d = abs(mode->width - matching_modes[i]->width)
                + abs(mode->height - matching_modes[i]->height);

        if (closest > d)
        {
            closest = d;
            j = i;
        }
    }

    *mode = *matching_modes[j];

4732 4733
    heap_free(matching_modes);
    heap_free(modes);
4734 4735 4736 4737 4738 4739 4740 4741

    TRACE("Returning %ux%u@%u %s %#x.\n", mode->width, mode->height,
            mode->refresh_rate, debug_d3dformat(mode->format_id),
            mode->scanline_ordering);

    return WINED3D_OK;
}

4742
HRESULT CDECL wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UINT adapter_idx,
4743
        struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation)
4744
{
4745
    const struct wined3d_adapter *adapter;
4746
    DEVMODEW m;
4747

4748 4749
    TRACE("wined3d %p, adapter_idx %u, display_mode %p, rotation %p.\n",
            wined3d, adapter_idx, mode, rotation);
4750

4751
    if (!mode || adapter_idx >= wined3d->adapter_count)
4752
        return WINED3DERR_INVALIDCALL;
4753

4754 4755
    adapter = &wined3d->adapters[adapter_idx];

4756 4757
    memset(&m, 0, sizeof(m));
    m.dmSize = sizeof(m);
4758

4759 4760 4761 4762 4763 4764 4765
    EnumDisplaySettingsExW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &m, 0);
    mode->width = m.dmPelsWidth;
    mode->height = m.dmPelsHeight;
    mode->refresh_rate = DEFAULT_REFRESH_RATE;
    if (m.dmFields & DM_DISPLAYFREQUENCY)
        mode->refresh_rate = m.dmDisplayFrequency;
    mode->format_id = pixelformat_for_depth(m.dmBitsPerPel);
4766

4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777
    /* Lie about the format. X11 can't change the color depth, and some apps
     * are pretty angry if they SetDisplayMode from 24 to 16 bpp and find out
     * that GetDisplayMode still returns 24 bpp. This should probably be
     * handled in winex11 instead. */
    if (adapter->screen_format && adapter->screen_format != mode->format_id)
    {
        WARN("Overriding format %s with stored format %s.\n",
                debug_d3dformat(mode->format_id),
                debug_d3dformat(adapter->screen_format));
        mode->format_id = adapter->screen_format;
    }
4778

4779 4780 4781 4782 4783 4784
    if (!(m.dmFields & DM_DISPLAYFLAGS))
        mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_UNKNOWN;
    else if (m.u2.dmDisplayFlags & DM_INTERLACED)
        mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_INTERLACED;
    else
        mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_PROGRESSIVE;
4785

4786 4787 4788
    if (rotation)
    {
        switch (m.u1.s2.dmDisplayOrientation)
4789
        {
4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805
            case DMDO_DEFAULT:
                *rotation = WINED3D_DISPLAY_ROTATION_0;
                break;
            case DMDO_90:
                *rotation = WINED3D_DISPLAY_ROTATION_90;
                break;
            case DMDO_180:
                *rotation = WINED3D_DISPLAY_ROTATION_180;
                break;
            case DMDO_270:
                *rotation = WINED3D_DISPLAY_ROTATION_270;
                break;
            default:
                FIXME("Unhandled display rotation %#x.\n", m.u1.s2.dmDisplayOrientation);
                *rotation = WINED3D_DISPLAY_ROTATION_UNSPECIFIED;
                break;
4806
        }
4807
    }
4808

4809 4810 4811
    TRACE("Returning %ux%u@%u %s %#x.\n", mode->width, mode->height,
            mode->refresh_rate, debug_d3dformat(mode->format_id),
            mode->scanline_ordering);
4812
    return WINED3D_OK;
4813
}
4814

4815 4816 4817 4818
HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d,
        UINT adapter_idx, const struct wined3d_display_mode *mode)
{
    struct wined3d_adapter *adapter;
4819
    DEVMODEW new_mode, current_mode;
4820 4821
    RECT clip_rc;
    LONG ret;
4822
    enum wined3d_format_id new_format_id;
4823

4824
    TRACE("wined3d %p, adapter_idx %u, mode %p.\n", wined3d, adapter_idx, mode);
4825 4826 4827 4828 4829

    if (adapter_idx >= wined3d->adapter_count)
        return WINED3DERR_INVALIDCALL;
    adapter = &wined3d->adapters[adapter_idx];

4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840
    memset(&new_mode, 0, sizeof(new_mode));
    new_mode.dmSize = sizeof(new_mode);
    memset(&current_mode, 0, sizeof(current_mode));
    current_mode.dmSize = sizeof(current_mode);
    if (mode)
    {
        const struct wined3d_format *format;

        TRACE("mode %ux%u@%u %s %#x.\n", mode->width, mode->height, mode->refresh_rate,
                debug_d3dformat(mode->format_id), mode->scanline_ordering);

4841
        format = wined3d_get_format(&adapter->gl_info, mode->format_id, WINED3DUSAGE_RENDERTARGET);
4842 4843 4844 4845 4846

        new_mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
        new_mode.dmBitsPerPel = format->byte_count * CHAR_BIT;
        new_mode.dmPelsWidth = mode->width;
        new_mode.dmPelsHeight = mode->height;
4847

4848 4849 4850
        new_mode.dmDisplayFrequency = mode->refresh_rate;
        if (mode->refresh_rate)
            new_mode.dmFields |= DM_DISPLAYFREQUENCY;
4851

4852 4853 4854 4855 4856 4857 4858 4859 4860
        if (mode->scanline_ordering != WINED3D_SCANLINE_ORDERING_UNKNOWN)
        {
            new_mode.dmFields |= DM_DISPLAYFLAGS;
            if (mode->scanline_ordering == WINED3D_SCANLINE_ORDERING_INTERLACED)
                new_mode.u2.dmDisplayFlags |= DM_INTERLACED;
        }
        new_format_id = mode->format_id;
    }
    else
4861
    {
4862
        if (!EnumDisplaySettingsW(adapter->DeviceName, ENUM_REGISTRY_SETTINGS, &new_mode))
4863 4864 4865 4866 4867
        {
            ERR("Failed to read mode from registry.\n");
            return WINED3DERR_NOTAVAILABLE;
        }
        new_format_id = pixelformat_for_depth(new_mode.dmBitsPerPel);
4868 4869
    }

4870
    /* Only change the mode if necessary. */
4871
    if (!EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &current_mode))
4872
    {
4873
        ERR("Failed to get current display mode.\n");
4874
    }
4875 4876 4877 4878 4879 4880
    else if (current_mode.dmPelsWidth == new_mode.dmPelsWidth
            && current_mode.dmPelsHeight == new_mode.dmPelsHeight
            && current_mode.dmBitsPerPel == new_mode.dmBitsPerPel
            && (current_mode.dmDisplayFrequency == new_mode.dmDisplayFrequency
            || !(new_mode.dmFields & DM_DISPLAYFREQUENCY))
            && (current_mode.u2.dmDisplayFlags == new_mode.u2.dmDisplayFlags
4881
            || !(new_mode.dmFields & DM_DISPLAYFLAGS)))
4882 4883
    {
        TRACE("Skipping redundant mode setting call.\n");
4884
        adapter->screen_format = new_format_id;
4885 4886 4887
        return WINED3D_OK;
    }

4888
    ret = ChangeDisplaySettingsExW(adapter->DeviceName, &new_mode, NULL, CDS_FULLSCREEN, NULL);
4889 4890
    if (ret != DISP_CHANGE_SUCCESSFUL)
    {
4891
        if (new_mode.dmFields & DM_DISPLAYFREQUENCY)
4892 4893
        {
            WARN("ChangeDisplaySettingsExW failed, trying without the refresh rate.\n");
4894 4895 4896
            new_mode.dmFields &= ~DM_DISPLAYFREQUENCY;
            new_mode.dmDisplayFrequency = 0;
            ret = ChangeDisplaySettingsExW(adapter->DeviceName, &new_mode, NULL, CDS_FULLSCREEN, NULL);
4897 4898 4899 4900 4901 4902
        }
        if (ret != DISP_CHANGE_SUCCESSFUL)
            return WINED3DERR_NOTAVAILABLE;
    }

    /* Store the new values. */
4903
    adapter->screen_format = new_format_id;
4904 4905

    /* And finally clip mouse to our screen. */
4906
    SetRect(&clip_rc, 0, 0, new_mode.dmPelsWidth, new_mode.dmPelsHeight);
4907 4908 4909 4910 4911
    ClipCursor(&clip_rc);

    return WINED3D_OK;
}

4912
/* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
4913
   and fields being inserted in the middle, a new structure is used in place    */
4914
HRESULT CDECL wined3d_get_adapter_identifier(const struct wined3d *wined3d,
4915
        UINT adapter_idx, DWORD flags, struct wined3d_adapter_identifier *identifier)
4916
{
4917
    const struct wined3d_adapter *adapter;
4918
    size_t len;
4919

4920
    TRACE("wined3d %p, adapter_idx %u, flags %#x, identifier %p.\n",
4921
            wined3d, adapter_idx, flags, identifier);
4922

4923
    if (adapter_idx >= wined3d->adapter_count)
4924
        return WINED3DERR_INVALIDCALL;
4925

4926
    adapter = &wined3d->adapters[adapter_idx];
4927

4928
    if (identifier->driver_size)
4929
    {
4930
        const char *name = adapter->driver_info.name;
4931 4932
        len = min(strlen(name), identifier->driver_size - 1);
        memcpy(identifier->driver, name, len);
4933
        memset(&identifier->driver[len], 0, identifier->driver_size - len);
4934 4935
    }

4936
    if (identifier->description_size)
4937
    {
4938
        const char *description = adapter->driver_info.description;
4939 4940
        len = min(strlen(description), identifier->description_size - 1);
        memcpy(identifier->description, description, len);
4941
        memset(&identifier->description[len], 0, identifier->description_size - len);
4942 4943 4944
    }

    /* Note that d3d8 doesn't supply a device name. */
4945
    if (identifier->device_name_size)
4946
    {
4947 4948
        if (!WideCharToMultiByte(CP_ACP, 0, adapter->DeviceName, -1, identifier->device_name,
                identifier->device_name_size, NULL, NULL))
4949
        {
4950
            ERR("Failed to convert device name, last error %#x.\n", GetLastError());
4951 4952 4953 4954
            return WINED3DERR_INVALIDCALL;
        }
    }

4955 4956 4957 4958 4959 4960 4961 4962 4963
    identifier->driver_version.u.HighPart = adapter->driver_info.version_high;
    identifier->driver_version.u.LowPart = adapter->driver_info.version_low;
    identifier->vendor_id = adapter->driver_info.vendor;
    identifier->device_id = adapter->driver_info.device;
    identifier->subsystem_id = 0;
    identifier->revision = 0;
    memcpy(&identifier->device_identifier, &IID_D3DDEVICE_D3DUID, sizeof(identifier->device_identifier));
    identifier->whql_level = (flags & WINED3DENUM_NO_WHQL_LEVEL) ? 0 : 1;
    memcpy(&identifier->adapter_luid, &adapter->luid, sizeof(identifier->adapter_luid));
4964
    identifier->video_memory = min(~(SIZE_T)0, adapter->vram_bytes);
4965

4966
    return WINED3D_OK;
4967 4968
}

4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015
HRESULT CDECL wined3d_get_adapter_raster_status(const struct wined3d *wined3d, UINT adapter_idx,
        struct wined3d_raster_status *raster_status)
{
    LONGLONG freq_per_frame, freq_per_line;
    LARGE_INTEGER counter, freq_per_sec;
    struct wined3d_display_mode mode;
    static UINT once;

    if (!once++)
        FIXME("wined3d %p, adapter_idx %u, raster_status %p semi-stub!\n",
                wined3d, adapter_idx, raster_status);
    else
        WARN("wined3d %p, adapter_idx %u, raster_status %p semi-stub!\n",
                wined3d, adapter_idx, raster_status);

    /* Obtaining the raster status is a widely implemented but optional
     * feature. When this method returns OK StarCraft 2 expects the
     * raster_status->InVBlank value to actually change over time.
     * And Endless Alice Crysis doesn't care even if this method fails.
     * Thus this method returns OK and fakes raster_status by
     * QueryPerformanceCounter. */

    if (!QueryPerformanceCounter(&counter) || !QueryPerformanceFrequency(&freq_per_sec))
        return WINED3DERR_INVALIDCALL;
    if (FAILED(wined3d_get_adapter_display_mode(wined3d, adapter_idx, &mode, NULL)))
        return WINED3DERR_INVALIDCALL;
    if (mode.refresh_rate == DEFAULT_REFRESH_RATE)
        mode.refresh_rate = 60;

    freq_per_frame = freq_per_sec.QuadPart / mode.refresh_rate;
    /* Assume 20 scan lines in the vertical blank. */
    freq_per_line = freq_per_frame / (mode.height + 20);
    raster_status->scan_line = (counter.QuadPart % freq_per_frame) / freq_per_line;
    if (raster_status->scan_line < mode.height)
        raster_status->in_vblank = FALSE;
    else
    {
        raster_status->scan_line = 0;
        raster_status->in_vblank = TRUE;
    }

    TRACE("Returning fake value, in_vblank %u, scan_line %u.\n",
            raster_status->in_vblank, raster_status->scan_line);

    return WINED3D_OK;
}

5016
static BOOL wined3d_check_pixel_format_color(const struct wined3d_gl_info *gl_info,
5017
        const struct wined3d_pixel_format *cfg, const struct wined3d_format *format)
5018
{
5019
    /* Float formats need FBOs. If FBOs are used this function isn't called */
5020 5021
    if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT)
        return FALSE;
5022

5023 5024 5025
    /* Probably a RGBA_float or color index mode. */
    if (cfg->iPixelType != WGL_TYPE_RGBA_ARB)
        return FALSE;
5026

5027 5028 5029 5030 5031
    if (cfg->redSize < format->red_size
            || cfg->greenSize < format->green_size
            || cfg->blueSize < format->blue_size
            || cfg->alphaSize < format->alpha_size)
        return FALSE;
5032

5033
    return TRUE;
5034 5035
}

5036
static BOOL wined3d_check_pixel_format_depth(const struct wined3d_gl_info *gl_info,
5037
        const struct wined3d_pixel_format *cfg, const struct wined3d_format *format)
5038
{
5039
    BOOL lockable = FALSE;
5040

5041
    /* Float formats need FBOs. If FBOs are used this function isn't called */
5042 5043
    if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT)
        return FALSE;
5044

5045
    if ((format->id == WINED3DFMT_D16_LOCKABLE) || (format->id == WINED3DFMT_D32_FLOAT))
5046 5047
        lockable = TRUE;

5048
    /* On some modern cards like the Geforce8/9, GLX doesn't offer some
5049
     * depth/stencil formats which D3D9 reports. We can safely report
5050 5051 5052 5053
     * "compatible" formats (e.g. D24 can be used for D16) as long as we
     * aren't dealing with a lockable format. This also helps D3D <= 7 as they
     * expect D16 which isn't offered without this on Geforce8 cards. */
    if (!(cfg->depthSize == format->depth_size || (!lockable && cfg->depthSize > format->depth_size)))
5054 5055
        return FALSE;

5056
    /* Some cards like Intel i915 ones only offer D24S8 but lots of games also
5057 5058 5059 5060
     * need a format without stencil. We can allow a mismatch if the format
     * doesn't have any stencil bits. If it does have stencil bits the size
     * must match, or stencil wrapping would break. */
    if (format->stencil_size && cfg->stencilSize != format->stencil_size)
5061 5062
        return FALSE;

5063
    return TRUE;
5064 5065
}

5066
HRESULT CDECL wined3d_check_depth_stencil_match(const struct wined3d *wined3d,
5067
        UINT adapter_idx, enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id,
5068
        enum wined3d_format_id render_target_format_id, enum wined3d_format_id depth_stencil_format_id)
5069
{
5070 5071
    const struct wined3d_format *rt_format;
    const struct wined3d_format *ds_format;
5072
    const struct wined3d_adapter *adapter;
5073

5074
    TRACE("wined3d %p, adapter_idx %u, device_type %s,\n"
5075 5076 5077
            "adapter_format %s, render_target_format %s, depth_stencil_format %s.\n",
            wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(adapter_format_id),
            debug_d3dformat(render_target_format_id), debug_d3dformat(depth_stencil_format_id));
5078

5079
    if (adapter_idx >= wined3d->adapter_count)
5080
        return WINED3DERR_INVALIDCALL;
5081

5082
    adapter = &wined3d->adapters[adapter_idx];
5083 5084
    rt_format = wined3d_get_format(&adapter->gl_info, render_target_format_id, WINED3DUSAGE_RENDERTARGET);
    ds_format = wined3d_get_format(&adapter->gl_info, depth_stencil_format_id, WINED3DUSAGE_DEPTHSTENCIL);
5085 5086
    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
    {
5087 5088
        if ((rt_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_RENDERTARGET)
                && (ds_format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
5089
        {
5090
            TRACE("Formats match.\n");
5091 5092 5093 5094 5095
            return WINED3D_OK;
        }
    }
    else
    {
5096
        const struct wined3d_pixel_format *cfgs;
5097 5098 5099
        unsigned int cfg_count;
        unsigned int i;

5100
        cfgs = adapter->cfgs;
5101
        cfg_count = adapter->cfg_count;
5102
        for (i = 0; i < cfg_count; ++i)
5103
        {
5104 5105
            if (wined3d_check_pixel_format_color(&adapter->gl_info, &cfgs[i], rt_format)
                    && wined3d_check_pixel_format_depth(&adapter->gl_info, &cfgs[i], ds_format))
5106
            {
5107
                TRACE("Formats match.\n");
5108
                return WINED3D_OK;
5109 5110
            }
        }
5111
    }
5112

5113
    TRACE("Unsupported format pair: %s and %s.\n",
5114 5115
            debug_d3dformat(render_target_format_id),
            debug_d3dformat(depth_stencil_format_id));
5116

5117
    return WINED3DERR_NOTAVAILABLE;
5118 5119
}

5120
HRESULT CDECL wined3d_check_device_multisample_type(const struct wined3d *wined3d, UINT adapter_idx,
5121
        enum wined3d_device_type device_type, enum wined3d_format_id surface_format_id, BOOL windowed,
5122
        enum wined3d_multisample_type multisample_type, DWORD *quality_levels)
5123
{
5124
    const struct wined3d_gl_info *gl_info = &wined3d->adapters[adapter_idx].gl_info;
5125
    const struct wined3d_format *format = wined3d_get_format(gl_info, surface_format_id, 0);
5126
    HRESULT hr = WINED3D_OK;
5127

5128
    TRACE("wined3d %p, adapter_idx %u, device_type %s, surface_format %s, "
5129 5130 5131
            "windowed %#x, multisample_type %#x, quality_levels %p.\n",
            wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(surface_format_id),
            windowed, multisample_type, quality_levels);
5132

5133
    if (adapter_idx >= wined3d->adapter_count)
5134
        return WINED3DERR_INVALIDCALL;
5135 5136
    if (surface_format_id == WINED3DFMT_UNKNOWN)
        return WINED3DERR_INVALIDCALL;
5137
    if (multisample_type < WINED3D_MULTISAMPLE_NONE)
5138
        return WINED3DERR_INVALIDCALL;
5139 5140 5141 5142 5143
    if (multisample_type > WINED3D_MULTISAMPLE_16_SAMPLES)
    {
        FIXME("multisample_type %u not handled yet.\n", multisample_type);
        return WINED3DERR_NOTAVAILABLE;
    }
5144

5145 5146
    if (multisample_type && !(format->multisample_types & 1u << (multisample_type - 1)))
        hr = WINED3DERR_NOTAVAILABLE;
5147

5148
    if (SUCCEEDED(hr) || (multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE && format->multisample_types))
5149
    {
5150
        if (quality_levels)
5151 5152 5153 5154 5155 5156 5157
        {
            if (multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE)
                *quality_levels = wined3d_popcount(format->multisample_types);
            else
                *quality_levels = 1;
        }
        return WINED3D_OK;
5158 5159
    }

5160 5161
    TRACE("Returning not supported.\n");
    return hr;
5162 5163
}

5164
/* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
5165
static BOOL CheckDepthStencilCapability(const struct wined3d_adapter *adapter,
5166 5167
        const struct wined3d_format *display_format, const struct wined3d_format *ds_format,
        enum wined3d_gl_resource_type gl_type)
5168
{
5169
    /* Only allow depth/stencil formats */
5170
    if (!(ds_format->depth_size || ds_format->stencil_size)) return FALSE;
5171

5172 5173 5174 5175 5176
    /* Blacklist formats not supported on Windows */
    switch (ds_format->id)
    {
        case WINED3DFMT_S1_UINT_D15_UNORM: /* Breaks the shadowvol2 dx7 sdk sample */
        case WINED3DFMT_S4X4_UINT_D24_UNORM:
5177
            TRACE("[FAILED] - not supported on windows.\n");
5178 5179 5180 5181 5182 5183
            return FALSE;

        default:
            break;
    }

5184 5185 5186
    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
    {
        /* With FBOs WGL limitations do not apply, but the format needs to be FBO attachable */
5187
        if (ds_format->flags[gl_type] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
5188
            return TRUE;
5189 5190
    }
    else
5191
    {
5192 5193
        unsigned int i;

5194
        /* Walk through all WGL pixel formats to find a match */
5195
        for (i = 0; i < adapter->cfg_count; ++i)
5196
        {
5197
            const struct wined3d_pixel_format *cfg = &adapter->cfgs[i];
5198 5199 5200
            if (wined3d_check_pixel_format_color(&adapter->gl_info, cfg, display_format)
                    && wined3d_check_pixel_format_depth(&adapter->gl_info, cfg, ds_format))
                return TRUE;
5201 5202 5203 5204 5205 5206
        }
    }

    return FALSE;
}

5207
/* Check the render target capabilities of a format */
5208
static BOOL CheckRenderTargetCapability(const struct wined3d_adapter *adapter,
5209 5210
        const struct wined3d_format *adapter_format, const struct wined3d_format *check_format,
        enum wined3d_gl_resource_type gl_type)
5211 5212
{
    /* Filter out non-RT formats */
5213
    if (!(check_format->flags[gl_type] & WINED3DFMT_FLAG_RENDERTARGET))
5214
        return FALSE;
5215 5216
    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
        return TRUE;
5217 5218
    if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER)
    {
5219
        const struct wined3d_pixel_format *cfgs = adapter->cfgs;
5220
        unsigned int i;
5221

5222 5223 5224 5225 5226 5227
        /* In backbuffer mode the front and backbuffer share the same WGL
         * pixelformat. The format must match in RGB, alpha is allowed to be
         * different. (Only the backbuffer can have alpha.) */
        if (adapter_format->red_size != check_format->red_size
                || adapter_format->green_size != check_format->green_size
                || adapter_format->blue_size != check_format->blue_size)
5228 5229
        {
            TRACE("[FAILED]\n");
5230 5231 5232 5233 5234
            return FALSE;
        }

        /* Check if there is a WGL pixel format matching the requirements, the format should also be window
         * drawable (not offscreen; e.g. Nvidia offers R5G6B5 for pbuffers even when X is running at 24bit) */
5235
        for (i = 0; i < adapter->cfg_count; ++i)
5236
        {
5237 5238
            if (cfgs[i].windowDrawable
                    && wined3d_check_pixel_format_color(&adapter->gl_info, &cfgs[i], check_format))
5239
            {
5240
                TRACE("Pixel format %d is compatible with format %s.\n",
5241
                        cfgs[i].iPixelFormat, debug_d3dformat(check_format->id));
5242 5243 5244
                return TRUE;
            }
        }
5245
    }
5246 5247 5248
    return FALSE;
}

5249
static BOOL wined3d_check_surface_capability(const struct wined3d_format *format, BOOL no3d)
5250
{
5251
    if (no3d)
5252
    {
5253
        switch (format->id)
5254
        {
5255
            case WINED3DFMT_B8G8R8_UNORM:
5256
                TRACE("[FAILED] - Not enumerated on Windows.\n");
5257
                return FALSE;
5258 5259 5260 5261 5262 5263 5264
            case WINED3DFMT_B8G8R8A8_UNORM:
            case WINED3DFMT_B8G8R8X8_UNORM:
            case WINED3DFMT_B5G6R5_UNORM:
            case WINED3DFMT_B5G5R5X1_UNORM:
            case WINED3DFMT_B5G5R5A1_UNORM:
            case WINED3DFMT_B4G4R4A4_UNORM:
            case WINED3DFMT_B2G3R3_UNORM:
5265
            case WINED3DFMT_A8_UNORM:
5266 5267
            case WINED3DFMT_B2G3R3A8_UNORM:
            case WINED3DFMT_B4G4R4X4_UNORM:
5268 5269
            case WINED3DFMT_R10G10B10A2_UNORM:
            case WINED3DFMT_R8G8B8A8_UNORM:
5270
            case WINED3DFMT_R8G8B8X8_UNORM:
5271
            case WINED3DFMT_R16G16_UNORM:
5272
            case WINED3DFMT_B10G10R10A2_UNORM:
5273
            case WINED3DFMT_R16G16B16A16_UNORM:
5274
            case WINED3DFMT_P8_UINT:
5275
                TRACE("[OK]\n");
5276 5277
                return TRUE;
            default:
5278
                TRACE("[FAILED] - Not available on GDI surfaces.\n");
5279 5280 5281 5282
                return FALSE;
        }
    }

5283
    if (format->glInternal)
5284
    {
5285
        TRACE("[OK]\n");
5286 5287 5288
        return TRUE;
    }

5289 5290 5291 5292 5293 5294 5295
    if ((format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & (WINED3DFMT_FLAG_EXTENSION | WINED3DFMT_FLAG_TEXTURE))
            == (WINED3DFMT_FLAG_EXTENSION | WINED3DFMT_FLAG_TEXTURE))
    {
        TRACE("[OK]\n");
        return TRUE;
    }

5296
    /* Reject other formats */
5297
    TRACE("[FAILED]\n");
5298 5299 5300
    return FALSE;
}

5301 5302 5303 5304 5305 5306 5307 5308
/* OpenGL supports mipmapping on all formats. Wrapping is unsupported, but we
 * have to report mipmapping so we cannot reject WRAPANDMIP. Tests show that
 * Windows reports WRAPANDMIP on unfilterable surfaces as well, apparently to
 * show that wrapping is supported. The lack of filtering will sort out the
 * mipmapping capability anyway.
 *
 * For now lets report this on all formats, but in the future we may want to
 * restrict it to some should applications need that. */
5309
HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT adapter_idx,
5310
        enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id, DWORD usage,
5311
        enum wined3d_resource_type resource_type, enum wined3d_format_id check_format_id)
5312
{
5313
    const struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx];
5314
    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
5315
    const struct wined3d_format *adapter_format, *format;
5316
    enum wined3d_gl_resource_type gl_type, gl_type_end;
5317
    BOOL mipmap_gen_supported = TRUE;
5318 5319
    DWORD format_flags = 0;
    DWORD allowed_usage;
5320

5321
    TRACE("wined3d %p, adapter_idx %u, device_type %s, adapter_format %s, usage %s, %s, "
5322
            "resource_type %s, check_format %s.\n",
5323 5324
            wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(adapter_format_id),
            debug_d3dusage(usage), debug_d3dusagequery(usage), debug_d3dresourcetype(resource_type),
5325
            debug_d3dformat(check_format_id));
5326 5327

    if (adapter_idx >= wined3d->adapter_count)
5328
        return WINED3DERR_INVALIDCALL;
5329

5330 5331 5332
    adapter_format = wined3d_get_format(gl_info, adapter_format_id, WINED3DUSAGE_RENDERTARGET);
    format = wined3d_get_format(gl_info, check_format_id, usage);

5333 5334
    switch (resource_type)
    {
5335 5336 5337 5338 5339 5340 5341
        case WINED3D_RTYPE_NONE:
            allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
                    | WINED3DUSAGE_RENDERTARGET;
            gl_type = WINED3D_GL_RES_TYPE_TEX_2D;
            gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D;
            break;

5342
        case WINED3D_RTYPE_TEXTURE_2D:
5343 5344 5345
            allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
                    | WINED3DUSAGE_RENDERTARGET
                    | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
5346 5347
            if (usage & WINED3DUSAGE_RENDERTARGET)
                allowed_usage |= WINED3DUSAGE_QUERY_SRGBWRITE;
5348 5349
            if (!(usage & WINED3DUSAGE_TEXTURE))
            {
5350
                if (!wined3d_check_surface_capability(format, wined3d->flags & WINED3D_NO3D))
5351 5352 5353 5354
                {
                    TRACE("[FAILED] - Not supported for plain surfaces.\n");
                    return WINED3DERR_NOTAVAILABLE;
                }
5355

5356
                gl_type = gl_type_end = WINED3D_GL_RES_TYPE_RB;
5357 5358
                break;
            }
5359
            allowed_usage |= WINED3DUSAGE_DYNAMIC
5360
                    | WINED3DUSAGE_LEGACY_CUBEMAP
5361
                    | WINED3DUSAGE_SOFTWAREPROCESSING
5362
                    | WINED3DUSAGE_TEXTURE
5363
                    | WINED3DUSAGE_QUERY_FILTER
5364
                    | WINED3DUSAGE_QUERY_GENMIPMAP
5365 5366 5367 5368 5369
                    | WINED3DUSAGE_QUERY_LEGACYBUMPMAP
                    | WINED3DUSAGE_QUERY_SRGBREAD
                    | WINED3DUSAGE_QUERY_SRGBWRITE
                    | WINED3DUSAGE_QUERY_VERTEXTEXTURE
                    | WINED3DUSAGE_QUERY_WRAPANDMIP;
5370
            gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_2D;
5371 5372 5373
            if (usage & WINED3DUSAGE_LEGACY_CUBEMAP)
            {
                allowed_usage &= ~(WINED3DUSAGE_DEPTHSTENCIL | WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
5374
                gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_CUBE;
5375 5376 5377 5378 5379 5380 5381 5382
            }
            else if ((usage & WINED3DUSAGE_DEPTHSTENCIL)
                    && (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_SHADOW)
                    && !gl_info->supported[ARB_SHADOW])
            {
                TRACE("[FAILED] - No shadow sampler support.\n");
                return WINED3DERR_NOTAVAILABLE;
            }
5383
            break;
5384

5385
        case WINED3D_RTYPE_TEXTURE_3D:
5386 5387
            allowed_usage = WINED3DUSAGE_DYNAMIC
                    | WINED3DUSAGE_SOFTWAREPROCESSING
5388
                    | WINED3DUSAGE_TEXTURE
5389 5390 5391 5392 5393 5394
                    | WINED3DUSAGE_QUERY_FILTER
                    | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
                    | WINED3DUSAGE_QUERY_SRGBREAD
                    | WINED3DUSAGE_QUERY_SRGBWRITE
                    | WINED3DUSAGE_QUERY_VERTEXTEXTURE
                    | WINED3DUSAGE_QUERY_WRAPANDMIP;
5395
            gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D;
5396
            break;
5397

5398 5399 5400 5401
        default:
            FIXME("Unhandled resource type %s.\n", debug_d3dresourcetype(resource_type));
            return WINED3DERR_NOTAVAILABLE;
    }
5402

5403 5404 5405 5406 5407 5408
    if ((usage & allowed_usage) != usage)
    {
        TRACE("Requested usage %#x, but resource type %s only allows %#x.\n",
                usage, debug_d3dresourcetype(resource_type), allowed_usage);
        return WINED3DERR_NOTAVAILABLE;
    }
5409

5410 5411
    if (usage & WINED3DUSAGE_TEXTURE)
        format_flags |= WINED3DFMT_FLAG_TEXTURE;
5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423
    if (usage & WINED3DUSAGE_QUERY_FILTER)
        format_flags |= WINED3DFMT_FLAG_FILTERING;
    if (usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING)
        format_flags |= WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING;
    if (usage & WINED3DUSAGE_QUERY_SRGBREAD)
        format_flags |= WINED3DFMT_FLAG_SRGB_READ;
    if (usage & WINED3DUSAGE_QUERY_SRGBWRITE)
        format_flags |= WINED3DFMT_FLAG_SRGB_WRITE;
    if (usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE)
        format_flags |= WINED3DFMT_FLAG_VTF;
    if (usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP)
        format_flags |= WINED3DFMT_FLAG_BUMPMAP;
5424

5425 5426 5427 5428 5429
    if ((format_flags & WINED3DFMT_FLAG_TEXTURE) && (wined3d->flags & WINED3D_NO3D))
    {
        TRACE("Requested texturing support, but wined3d was created with WINED3D_NO3D.\n");
        return WINED3DERR_NOTAVAILABLE;
    }
5430

5431
    for (; gl_type <= gl_type_end; ++gl_type)
5432
    {
5433 5434 5435 5436 5437 5438
        if ((format->flags[gl_type] & format_flags) != format_flags)
        {
            TRACE("Requested format flags %#x, but format %s only has %#x.\n",
                    format_flags, debug_d3dformat(check_format_id), format->flags[gl_type]);
            return WINED3DERR_NOTAVAILABLE;
        }
5439

5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458
        if ((usage & WINED3DUSAGE_RENDERTARGET)
                && !CheckRenderTargetCapability(adapter, adapter_format, format, gl_type))
        {
            TRACE("Requested WINED3DUSAGE_RENDERTARGET, but format %s is not supported for render targets.\n",
                    debug_d3dformat(check_format_id));
            return WINED3DERR_NOTAVAILABLE;
        }

        /* 3D depth / stencil textures are never supported. */
        if (usage == WINED3DUSAGE_DEPTHSTENCIL && gl_type == WINED3D_GL_RES_TYPE_TEX_3D)
            continue;

        if ((usage & WINED3DUSAGE_DEPTHSTENCIL)
                && !CheckDepthStencilCapability(adapter, adapter_format, format, gl_type))
        {
            TRACE("Requested WINED3DUSAGE_DEPTHSTENCIL, but format %s is not supported for depth / stencil buffers.\n",
                    debug_d3dformat(check_format_id));
            return WINED3DERR_NOTAVAILABLE;
        }
5459

5460
        if (!(format->flags[gl_type] & WINED3DFMT_FLAG_GEN_MIPMAP))
5461
            mipmap_gen_supported = FALSE;
5462 5463
    }

5464
    if ((usage & WINED3DUSAGE_QUERY_GENMIPMAP) && !mipmap_gen_supported)
5465 5466
    {
        TRACE("No WINED3DUSAGE_AUTOGENMIPMAP support, returning WINED3DOK_NOAUTOGEN.\n");
5467
        return WINED3DOK_NOMIPGEN;
5468
    }
5469

5470
    return WINED3D_OK;
5471 5472
}

5473 5474 5475 5476
UINT CDECL wined3d_calculate_format_pitch(const struct wined3d *wined3d, UINT adapter_idx,
        enum wined3d_format_id format_id, UINT width)
{
    const struct wined3d_gl_info *gl_info;
5477
    unsigned int row_pitch, slice_pitch;
5478 5479 5480 5481 5482 5483 5484 5485

    TRACE("wined3d %p, adapter_idx %u, format_id %s, width %u.\n",
            wined3d, adapter_idx, debug_d3dformat(format_id), width);

    if (adapter_idx >= wined3d->adapter_count)
        return ~0u;

    gl_info = &wined3d->adapters[adapter_idx].gl_info;
5486
    wined3d_format_calculate_pitch(wined3d_get_format(gl_info, format_id, 0),
5487 5488 5489
            1, width, 1, &row_pitch, &slice_pitch);

    return row_pitch;
5490 5491
}

5492
HRESULT CDECL wined3d_check_device_format_conversion(const struct wined3d *wined3d, UINT adapter_idx,
5493
        enum wined3d_device_type device_type, enum wined3d_format_id src_format, enum wined3d_format_id dst_format)
5494
{
5495 5496
    FIXME("wined3d %p, adapter_idx %u, device_type %s, src_format %s, dst_format %s stub!\n",
            wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(src_format),
5497
            debug_d3dformat(dst_format));
5498

5499
    return WINED3D_OK;
5500 5501
}

5502 5503 5504
HRESULT CDECL wined3d_check_device_type(const struct wined3d *wined3d, UINT adapter_idx,
        enum wined3d_device_type device_type, enum wined3d_format_id display_format,
        enum wined3d_format_id backbuffer_format, BOOL windowed)
5505
{
5506
    BOOL present_conversion = wined3d->flags & WINED3D_PRESENT_CONVERSION;
5507

5508 5509
    TRACE("wined3d %p, adapter_idx %u, device_type %s, display_format %s, backbuffer_format %s, windowed %#x.\n",
            wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(display_format),
5510 5511
            debug_d3dformat(backbuffer_format), windowed);

5512
    if (adapter_idx >= wined3d->adapter_count)
5513 5514 5515 5516 5517 5518
        return WINED3DERR_INVALIDCALL;

    /* The task of this function is to check whether a certain display / backbuffer format
     * combination is available on the given adapter. In fullscreen mode microsoft specified
     * that the display format shouldn't provide alpha and that ignoring alpha the backbuffer
     * and display format should match exactly.
5519
     * In windowed mode format conversion can occur and this depends on the driver. */
5520 5521 5522 5523 5524 5525 5526

    /* There are only 4 display formats. */
    if (!(display_format == WINED3DFMT_B5G6R5_UNORM
            || display_format == WINED3DFMT_B5G5R5X1_UNORM
            || display_format == WINED3DFMT_B8G8R8X8_UNORM
            || display_format == WINED3DFMT_B10G10R10A2_UNORM))
    {
5527
        TRACE("Format %s is not supported as display format.\n", debug_d3dformat(display_format));
5528 5529 5530
        return WINED3DERR_NOTAVAILABLE;
    }

5531
    if (!windowed)
5532
    {
5533 5534 5535
        /* If the requested display format is not available, don't continue. */
        if (!wined3d_get_adapter_mode_count(wined3d, adapter_idx,
                display_format, WINED3D_SCANLINE_ORDERING_UNKNOWN))
5536
        {
5537
            TRACE("No available modes for display format %s.\n", debug_d3dformat(display_format));
5538 5539
            return WINED3DERR_NOTAVAILABLE;
        }
5540

5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554
        present_conversion = FALSE;
    }
    else if (display_format == WINED3DFMT_B10G10R10A2_UNORM)
    {
        /* WINED3DFMT_B10G10R10A2_UNORM is only allowed in fullscreen mode. */
        TRACE("Unsupported format combination %s / %s in windowed mode.\n",
                debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
        return WINED3DERR_NOTAVAILABLE;
    }

    if (present_conversion)
    {
        /* Use the display format as back buffer format if the latter is
         * WINED3DFMT_UNKNOWN. */
5555 5556
        if (backbuffer_format == WINED3DFMT_UNKNOWN)
            backbuffer_format = display_format;
5557

5558 5559
        if (FAILED(wined3d_check_device_format_conversion(wined3d, adapter_idx,
                device_type, backbuffer_format, display_format)))
5560
        {
5561 5562
            TRACE("Format conversion from %s to %s not supported.\n",
                    debug_d3dformat(backbuffer_format), debug_d3dformat(display_format));
5563 5564
            return WINED3DERR_NOTAVAILABLE;
        }
5565
    }
5566
    else
5567
    {
5568 5569 5570
        /* When format conversion from the back buffer format to the display
         * format is not allowed, only a limited number of combinations are
         * valid. */
5571

5572 5573
        if (display_format == WINED3DFMT_B5G6R5_UNORM && backbuffer_format != WINED3DFMT_B5G6R5_UNORM)
        {
5574
            TRACE("Unsupported format combination %s / %s.\n",
5575 5576 5577 5578 5579 5580 5581
                    debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
            return WINED3DERR_NOTAVAILABLE;
        }

        if (display_format == WINED3DFMT_B5G5R5X1_UNORM
                && !(backbuffer_format == WINED3DFMT_B5G5R5X1_UNORM || backbuffer_format == WINED3DFMT_B5G5R5A1_UNORM))
        {
5582
            TRACE("Unsupported format combination %s / %s.\n",
5583 5584 5585 5586 5587 5588 5589
                    debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
            return WINED3DERR_NOTAVAILABLE;
        }

        if (display_format == WINED3DFMT_B8G8R8X8_UNORM
                && !(backbuffer_format == WINED3DFMT_B8G8R8X8_UNORM || backbuffer_format == WINED3DFMT_B8G8R8A8_UNORM))
        {
5590
            TRACE("Unsupported format combination %s / %s.\n",
5591 5592 5593 5594 5595 5596 5597
                    debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
            return WINED3DERR_NOTAVAILABLE;
        }

        if (display_format == WINED3DFMT_B10G10R10A2_UNORM
                && backbuffer_format != WINED3DFMT_B10G10R10A2_UNORM)
        {
5598
            TRACE("Unsupported format combination %s / %s.\n",
5599 5600 5601
                    debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
            return WINED3DERR_NOTAVAILABLE;
        }
5602 5603
    }

5604 5605
    /* Validate that the back buffer format is usable for render targets. */
    if (FAILED(wined3d_check_device_format(wined3d, adapter_idx, device_type, display_format,
5606
            WINED3DUSAGE_RENDERTARGET, WINED3D_RTYPE_TEXTURE_2D, backbuffer_format)))
5607 5608 5609 5610
    {
        TRACE("Format %s not allowed for render targets.\n", debug_d3dformat(backbuffer_format));
        return WINED3DERR_NOTAVAILABLE;
    }
5611

5612
    return WINED3D_OK;
5613 5614
}

5615
HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapter_idx,
5616
        enum wined3d_device_type device_type, WINED3DCAPS *caps)
5617 5618
{
    const struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx];
5619
    const struct wined3d_d3d_info *d3d_info = &adapter->d3d_info;
5620
    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
5621
    struct wined3d_vertex_caps vertex_caps;
5622
    DWORD ckey_caps, blit_caps, fx_caps;
5623 5624
    struct fragment_caps fragment_caps;
    struct shader_caps shader_caps;
5625

5626
    TRACE("wined3d %p, adapter_idx %u, device_type %s, caps %p.\n",
5627
            wined3d, adapter_idx, debug_d3ddevicetype(device_type), caps);
5628

5629
    if (adapter_idx >= wined3d->adapter_count)
5630
        return WINED3DERR_INVALIDCALL;
5631

5632
    caps->DeviceType = (device_type == WINED3D_DEVICE_TYPE_HAL) ? WINED3D_DEVICE_TYPE_HAL : WINED3D_DEVICE_TYPE_REF;
5633
    caps->AdapterOrdinal           = adapter_idx;
5634

5635 5636
    caps->Caps                     = 0;
    caps->Caps2                    = WINED3DCAPS2_CANRENDERWINDOWED |
5637 5638
                                     WINED3DCAPS2_FULLSCREENGAMMA |
                                     WINED3DCAPS2_DYNAMICTEXTURES;
5639
    if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || gl_info->supported[EXT_FRAMEBUFFER_OBJECT])
5640
        caps->Caps2 |= WINED3DCAPS2_CANGENMIPMAP;
5641

5642
    caps->Caps3                    = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
5643 5644 5645
                                     WINED3DCAPS3_COPY_TO_VIDMEM                   |
                                     WINED3DCAPS3_COPY_TO_SYSTEMMEM;

5646
    caps->PresentationIntervals    = WINED3DPRESENT_INTERVAL_IMMEDIATE  |
5647 5648
                                     WINED3DPRESENT_INTERVAL_ONE;

5649
    caps->CursorCaps               = WINED3DCURSORCAPS_COLOR            |
5650 5651
                                     WINED3DCURSORCAPS_LOWRES;

5652
    caps->DevCaps                  = WINED3DDEVCAPS_FLOATTLVERTEX       |
5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664
                                     WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
                                     WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
                                     WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
                                     WINED3DDEVCAPS_DRAWPRIMTLVERTEX    |
                                     WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
                                     WINED3DDEVCAPS_EXECUTEVIDEOMEMORY  |
                                     WINED3DDEVCAPS_PUREDEVICE          |
                                     WINED3DDEVCAPS_HWRASTERIZATION     |
                                     WINED3DDEVCAPS_TEXTUREVIDEOMEMORY  |
                                     WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
                                     WINED3DDEVCAPS_CANRENDERAFTERFLIP  |
                                     WINED3DDEVCAPS_DRAWPRIMITIVES2     |
5665
                                     WINED3DDEVCAPS_DRAWPRIMITIVES2EX;
5666

5667
    caps->PrimitiveMiscCaps        = WINED3DPMISCCAPS_CULLNONE              |
5668 5669 5670 5671 5672 5673
                                     WINED3DPMISCCAPS_CULLCCW               |
                                     WINED3DPMISCCAPS_CULLCW                |
                                     WINED3DPMISCCAPS_COLORWRITEENABLE      |
                                     WINED3DPMISCCAPS_CLIPTLVERTS           |
                                     WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
                                     WINED3DPMISCCAPS_MASKZ                 |
5674
                                     WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING;
5675
                                    /* TODO:
5676 5677 5678 5679
                                        WINED3DPMISCCAPS_NULLREFERENCE
                                        WINED3DPMISCCAPS_FOGANDSPECULARALPHA
                                        WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
                                        WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
5680

5681 5682
    if (gl_info->supported[WINED3D_GL_BLEND_EQUATION])
        caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_BLENDOP;
5683
    if (gl_info->supported[EXT_BLEND_EQUATION_SEPARATE] && gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
5684
        caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND;
5685
    if (gl_info->supported[EXT_DRAW_BUFFERS2])
5686
        caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS;
5687 5688
    if (gl_info->supported[ARB_FRAMEBUFFER_SRGB])
        caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_POSTBLENDSRGBCONVERT;
5689

5690
    caps->RasterCaps               = WINED3DPRASTERCAPS_DITHER    |
5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701
                                     WINED3DPRASTERCAPS_PAT       |
                                     WINED3DPRASTERCAPS_WFOG      |
                                     WINED3DPRASTERCAPS_ZFOG      |
                                     WINED3DPRASTERCAPS_FOGVERTEX |
                                     WINED3DPRASTERCAPS_FOGTABLE  |
                                     WINED3DPRASTERCAPS_STIPPLE   |
                                     WINED3DPRASTERCAPS_SUBPIXEL  |
                                     WINED3DPRASTERCAPS_ZTEST     |
                                     WINED3DPRASTERCAPS_SCISSORTEST   |
                                     WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
                                     WINED3DPRASTERCAPS_DEPTHBIAS;
5702

5703
    if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC])
5704
    {
5705
        caps->RasterCaps  |= WINED3DPRASTERCAPS_ANISOTROPY    |
5706 5707
                             WINED3DPRASTERCAPS_ZBIAS         |
                             WINED3DPRASTERCAPS_MIPMAPLODBIAS;
5708
    }
5709

5710
    caps->ZCmpCaps =  WINED3DPCMPCAPS_ALWAYS       |
5711 5712 5713 5714 5715 5716 5717 5718
                      WINED3DPCMPCAPS_EQUAL        |
                      WINED3DPCMPCAPS_GREATER      |
                      WINED3DPCMPCAPS_GREATEREQUAL |
                      WINED3DPCMPCAPS_LESS         |
                      WINED3DPCMPCAPS_LESSEQUAL    |
                      WINED3DPCMPCAPS_NEVER        |
                      WINED3DPCMPCAPS_NOTEQUAL;

5719 5720
    /* WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA
     * are legacy settings for srcblend only. */
5721
    caps->SrcBlendCaps  =  WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734
                           WINED3DPBLENDCAPS_BOTHSRCALPHA    |
                           WINED3DPBLENDCAPS_DESTALPHA       |
                           WINED3DPBLENDCAPS_DESTCOLOR       |
                           WINED3DPBLENDCAPS_INVDESTALPHA    |
                           WINED3DPBLENDCAPS_INVDESTCOLOR    |
                           WINED3DPBLENDCAPS_INVSRCALPHA     |
                           WINED3DPBLENDCAPS_INVSRCCOLOR     |
                           WINED3DPBLENDCAPS_ONE             |
                           WINED3DPBLENDCAPS_SRCALPHA        |
                           WINED3DPBLENDCAPS_SRCALPHASAT     |
                           WINED3DPBLENDCAPS_SRCCOLOR        |
                           WINED3DPBLENDCAPS_ZERO;

5735
    caps->DestBlendCaps =  WINED3DPBLENDCAPS_DESTALPHA       |
5736 5737 5738 5739 5740 5741 5742 5743 5744
                           WINED3DPBLENDCAPS_DESTCOLOR       |
                           WINED3DPBLENDCAPS_INVDESTALPHA    |
                           WINED3DPBLENDCAPS_INVDESTCOLOR    |
                           WINED3DPBLENDCAPS_INVSRCALPHA     |
                           WINED3DPBLENDCAPS_INVSRCCOLOR     |
                           WINED3DPBLENDCAPS_ONE             |
                           WINED3DPBLENDCAPS_SRCALPHA        |
                           WINED3DPBLENDCAPS_SRCCOLOR        |
                           WINED3DPBLENDCAPS_ZERO;
5745 5746 5747

    if (gl_info->supported[ARB_BLEND_FUNC_EXTENDED])
        caps->DestBlendCaps |= WINED3DPBLENDCAPS_SRCALPHASAT;
5748

5749 5750
    if (gl_info->supported[EXT_BLEND_COLOR])
    {
5751 5752
        caps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
        caps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
5753 5754 5755
    }


5756
    caps->AlphaCmpCaps  = WINED3DPCMPCAPS_ALWAYS       |
5757 5758 5759 5760 5761 5762 5763 5764
                          WINED3DPCMPCAPS_EQUAL        |
                          WINED3DPCMPCAPS_GREATER      |
                          WINED3DPCMPCAPS_GREATEREQUAL |
                          WINED3DPCMPCAPS_LESS         |
                          WINED3DPCMPCAPS_LESSEQUAL    |
                          WINED3DPCMPCAPS_NEVER        |
                          WINED3DPCMPCAPS_NOTEQUAL;

5765
    caps->ShadeCaps      = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
5766 5767 5768 5769 5770 5771 5772 5773
                           WINED3DPSHADECAPS_COLORGOURAUDRGB    |
                           WINED3DPSHADECAPS_ALPHAFLATBLEND     |
                           WINED3DPSHADECAPS_ALPHAGOURAUDBLEND  |
                           WINED3DPSHADECAPS_COLORFLATRGB       |
                           WINED3DPSHADECAPS_FOGFLAT            |
                           WINED3DPSHADECAPS_FOGGOURAUD         |
                           WINED3DPSHADECAPS_SPECULARFLATRGB;

5774
    caps->TextureCaps   = WINED3DPTEXTURECAPS_ALPHA              |
5775
                          WINED3DPTEXTURECAPS_ALPHAPALETTE       |
5776
                          WINED3DPTEXTURECAPS_TRANSPARENCY       |
5777 5778 5779 5780
                          WINED3DPTEXTURECAPS_BORDER             |
                          WINED3DPTEXTURECAPS_MIPMAP             |
                          WINED3DPTEXTURECAPS_PROJECTED          |
                          WINED3DPTEXTURECAPS_PERSPECTIVE;
5781

5782 5783
    if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
    {
5784 5785 5786
        caps->TextureCaps |= WINED3DPTEXTURECAPS_POW2;
        if (gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] || gl_info->supported[ARB_TEXTURE_RECTANGLE])
            caps->TextureCaps |= WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
5787
    }
5788

5789 5790
    if (gl_info->supported[EXT_TEXTURE3D])
    {
5791
        caps->TextureCaps  |=  WINED3DPTEXTURECAPS_VOLUMEMAP      |
5792 5793 5794
                               WINED3DPTEXTURECAPS_MIPVOLUMEMAP;
        if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
        {
5795
            caps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
5796
        }
5797 5798
    }

5799 5800
    if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
    {
5801
        caps->TextureCaps  |= WINED3DPTEXTURECAPS_CUBEMAP     |
5802 5803 5804
                              WINED3DPTEXTURECAPS_MIPCUBEMAP;
        if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
        {
5805
            caps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP_POW2;
5806
        }
5807 5808
    }

5809
    caps->TextureFilterCaps =  WINED3DPTFILTERCAPS_MAGFLINEAR       |
5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820
                               WINED3DPTFILTERCAPS_MAGFPOINT        |
                               WINED3DPTFILTERCAPS_MINFLINEAR       |
                               WINED3DPTFILTERCAPS_MINFPOINT        |
                               WINED3DPTFILTERCAPS_MIPFLINEAR       |
                               WINED3DPTFILTERCAPS_MIPFPOINT        |
                               WINED3DPTFILTERCAPS_LINEAR           |
                               WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
                               WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
                               WINED3DPTFILTERCAPS_MIPLINEAR        |
                               WINED3DPTFILTERCAPS_MIPNEAREST       |
                               WINED3DPTFILTERCAPS_NEAREST;
5821

5822
    if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC])
5823
    {
5824
        caps->TextureFilterCaps  |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
5825
                                    WINED3DPTFILTERCAPS_MINFANISOTROPIC;
5826 5827
    }

5828 5829
    if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
    {
5830
        caps->CubeTextureFilterCaps =  WINED3DPTFILTERCAPS_MAGFLINEAR       |
5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841
                                       WINED3DPTFILTERCAPS_MAGFPOINT        |
                                       WINED3DPTFILTERCAPS_MINFLINEAR       |
                                       WINED3DPTFILTERCAPS_MINFPOINT        |
                                       WINED3DPTFILTERCAPS_MIPFLINEAR       |
                                       WINED3DPTFILTERCAPS_MIPFPOINT        |
                                       WINED3DPTFILTERCAPS_LINEAR           |
                                       WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
                                       WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
                                       WINED3DPTFILTERCAPS_MIPLINEAR        |
                                       WINED3DPTFILTERCAPS_MIPNEAREST       |
                                       WINED3DPTFILTERCAPS_NEAREST;
5842

5843
        if (gl_info->supported[ARB_TEXTURE_FILTER_ANISOTROPIC])
5844
        {
5845
            caps->CubeTextureFilterCaps  |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
5846 5847
                                            WINED3DPTFILTERCAPS_MINFANISOTROPIC;
        }
5848 5849 5850 5851 5852
    }
    else
    {
        caps->CubeTextureFilterCaps = 0;
    }
5853

5854 5855
    if (gl_info->supported[EXT_TEXTURE3D])
    {
5856
        caps->VolumeTextureFilterCaps  = WINED3DPTFILTERCAPS_MAGFLINEAR       |
5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867
                                         WINED3DPTFILTERCAPS_MAGFPOINT        |
                                         WINED3DPTFILTERCAPS_MINFLINEAR       |
                                         WINED3DPTFILTERCAPS_MINFPOINT        |
                                         WINED3DPTFILTERCAPS_MIPFLINEAR       |
                                         WINED3DPTFILTERCAPS_MIPFPOINT        |
                                         WINED3DPTFILTERCAPS_LINEAR           |
                                         WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
                                         WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
                                         WINED3DPTFILTERCAPS_MIPLINEAR        |
                                         WINED3DPTFILTERCAPS_MIPNEAREST       |
                                         WINED3DPTFILTERCAPS_NEAREST;
5868 5869 5870 5871 5872
    }
    else
    {
        caps->VolumeTextureFilterCaps = 0;
    }
5873

5874
    caps->TextureAddressCaps  =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
5875 5876
                                 WINED3DPTADDRESSCAPS_CLAMP  |
                                 WINED3DPTADDRESSCAPS_WRAP;
5877

5878 5879
    if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
    {
5880
        caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
5881
    }
5882 5883
    if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
    {
5884
        caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
5885
    }
5886
    if (gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE])
5887
    {
5888
        caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
5889 5890
    }

5891 5892
    if (gl_info->supported[EXT_TEXTURE3D])
    {
5893
        caps->VolumeTextureAddressCaps =   WINED3DPTADDRESSCAPS_INDEPENDENTUV |
5894 5895
                                           WINED3DPTADDRESSCAPS_CLAMP  |
                                           WINED3DPTADDRESSCAPS_WRAP;
5896 5897
        if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
        {
5898
            caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
5899
        }
5900 5901
        if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
        {
5902
            caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
5903
        }
5904
        if (gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE])
5905
        {
5906
            caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
5907
        }
5908 5909 5910 5911 5912
    }
    else
    {
        caps->VolumeTextureAddressCaps = 0;
    }
5913

5914
    caps->LineCaps  = WINED3DLINECAPS_TEXTURE       |
5915 5916 5917 5918 5919 5920 5921
                      WINED3DLINECAPS_ZTEST         |
                      WINED3DLINECAPS_BLEND         |
                      WINED3DLINECAPS_ALPHACMP      |
                      WINED3DLINECAPS_FOG;
    /* WINED3DLINECAPS_ANTIALIAS is not supported on Windows, and dx and gl seem to have a different
     * idea how generating the smoothing alpha values works; the result is different
     */
5922

5923 5924
    caps->MaxTextureWidth = gl_info->limits.texture_size;
    caps->MaxTextureHeight = gl_info->limits.texture_size;
5925

5926
    if (gl_info->supported[EXT_TEXTURE3D])
5927
        caps->MaxVolumeExtent = gl_info->limits.texture3d_size;
5928
    else
5929
        caps->MaxVolumeExtent = 0;
5930

5931 5932 5933
    caps->MaxTextureRepeat = 32768;
    caps->MaxTextureAspectRatio = gl_info->limits.texture_size;
    caps->MaxVertexW = 1.0f;
5934

5935 5936 5937 5938
    caps->GuardBandLeft = 0.0f;
    caps->GuardBandTop = 0.0f;
    caps->GuardBandRight = 0.0f;
    caps->GuardBandBottom = 0.0f;
5939

5940
    caps->ExtentsAdjust = 0.0f;
5941

5942
    caps->StencilCaps   = WINED3DSTENCILCAPS_DECRSAT |
5943 5944 5945 5946 5947
                          WINED3DSTENCILCAPS_INCRSAT |
                          WINED3DSTENCILCAPS_INVERT  |
                          WINED3DSTENCILCAPS_KEEP    |
                          WINED3DSTENCILCAPS_REPLACE |
                          WINED3DSTENCILCAPS_ZERO;
5948 5949
    if (gl_info->supported[EXT_STENCIL_WRAP])
    {
5950
        caps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
5951
                              WINED3DSTENCILCAPS_INCR;
5952
    }
5953 5954
    if (gl_info->supported[WINED3D_GL_VERSION_2_0] || gl_info->supported[EXT_STENCIL_TWO_SIDE]
            || gl_info->supported[ATI_SEPARATE_STENCIL])
5955
    {
5956
        caps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
5957
    }
5958

5959 5960
    caps->MaxAnisotropy = gl_info->limits.anisotropy;
    caps->MaxPointSize = gl_info->limits.pointsize_max;
5961

5962 5963
    caps->MaxPrimitiveCount   = 0x555555; /* Taken from an AMD Radeon HD 5700 (Evergreen) GPU. */
    caps->MaxVertexIndex      = 0xffffff; /* Taken from an AMD Radeon HD 5700 (Evergreen) GPU. */
5964 5965
    caps->MaxStreams          = MAX_STREAMS;
    caps->MaxStreamStride     = 1024;
5966

5967
    /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
5968 5969 5970 5971 5972 5973
    caps->DevCaps2                          = WINED3DDEVCAPS2_STREAMOFFSET |
                                              WINED3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET;
    caps->MaxNpatchTessellationLevel        = 0;
    caps->MasterAdapterOrdinal              = 0;
    caps->AdapterOrdinalInGroup             = 0;
    caps->NumberOfAdaptersInGroup           = 1;
5974

5975
    caps->NumSimultaneousRTs = gl_info->limits.buffers;
5976

5977
    caps->StretchRectFilterCaps               = WINED3DPTFILTERCAPS_MINFPOINT  |
5978 5979 5980
                                                WINED3DPTFILTERCAPS_MAGFPOINT  |
                                                WINED3DPTFILTERCAPS_MINFLINEAR |
                                                WINED3DPTFILTERCAPS_MAGFLINEAR;
5981
    caps->VertexTextureFilterCaps             = 0;
5982

5983
    adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
5984
    adapter->fragment_pipe->get_caps(&adapter->gl_info, &fragment_caps);
5985
    adapter->vertex_pipe->vp_get_caps(&adapter->gl_info, &vertex_caps);
5986

5987
    /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
5988
    caps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps;
5989

5990 5991
    caps->VertexShaderVersion = shader_caps.vs_version;
    caps->MaxVertexShaderConst = shader_caps.vs_uniform_count;
5992

5993 5994
    caps->PixelShaderVersion = shader_caps.ps_version;
    caps->PixelShader1xMaxValue = shader_caps.ps_1x_max_value;
5995

5996 5997 5998
    caps->TextureOpCaps                    = fragment_caps.TextureOpCaps;
    caps->MaxTextureBlendStages            = fragment_caps.MaxTextureBlendStages;
    caps->MaxSimultaneousTextures          = fragment_caps.MaxSimultaneousTextures;
5999

6000 6001 6002 6003 6004 6005 6006 6007
    caps->MaxUserClipPlanes                = vertex_caps.max_user_clip_planes;
    caps->MaxActiveLights                  = vertex_caps.max_active_lights;
    caps->MaxVertexBlendMatrices           = vertex_caps.max_vertex_blend_matrices;
    caps->MaxVertexBlendMatrixIndex        = vertex_caps.max_vertex_blend_matrix_index;
    caps->VertexProcessingCaps             = vertex_caps.vertex_processing_caps;
    caps->FVFCaps                          = vertex_caps.fvf_caps;
    caps->RasterCaps                      |= vertex_caps.raster_caps;

6008 6009 6010 6011
    /* The following caps are shader specific, but they are things we cannot detect, or which
     * are the same among all shader models. So to avoid code duplication set the shader version
     * specific, but otherwise constant caps here
     */
6012
    if (caps->VertexShaderVersion >= 3)
6013 6014 6015 6016 6017
    {
        /* Where possible set the caps based on OpenGL extensions and if they
         * aren't set (in case of software rendering) use the VS 3.0 from
         * MSDN or else if there's OpenGL spec use a hardcoded value minimum
         * VS3.0 value. */
6018
        caps->VS20Caps.caps = WINED3DVS20CAPS_PREDICATION;
6019
        /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
6020 6021
        caps->VS20Caps.dynamic_flow_control_depth = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH;
        caps->VS20Caps.temp_count = max(32, adapter->gl_info.limits.arb_vs_temps);
6022
        /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
6023
        caps->VS20Caps.static_flow_control_depth = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH;
6024 6025 6026

        caps->MaxVShaderInstructionsExecuted    = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
        caps->MaxVertexShader30InstructionSlots = max(512, adapter->gl_info.limits.arb_vs_instructions);
6027
        caps->VertexTextureFilterCaps = WINED3DPTFILTERCAPS_MINFPOINT | WINED3DPTFILTERCAPS_MAGFPOINT;
6028
    }
6029
    else if (caps->VertexShaderVersion == 2)
6030
    {
6031 6032 6033 6034
        caps->VS20Caps.caps = 0;
        caps->VS20Caps.dynamic_flow_control_depth = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
        caps->VS20Caps.temp_count = max(12, adapter->gl_info.limits.arb_vs_temps);
        caps->VS20Caps.static_flow_control_depth = 1;
6035 6036 6037 6038 6039 6040

        caps->MaxVShaderInstructionsExecuted    = 65535;
        caps->MaxVertexShader30InstructionSlots = 0;
    }
    else
    { /* VS 1.x */
6041 6042 6043 6044
        caps->VS20Caps.caps = 0;
        caps->VS20Caps.dynamic_flow_control_depth = 0;
        caps->VS20Caps.temp_count = 0;
        caps->VS20Caps.static_flow_control_depth = 0;
6045 6046 6047 6048 6049

        caps->MaxVShaderInstructionsExecuted    = 0;
        caps->MaxVertexShader30InstructionSlots = 0;
    }

6050
    if (caps->PixelShaderVersion >= 3)
6051 6052 6053 6054 6055 6056 6057 6058 6059
    {
        /* Where possible set the caps based on OpenGL extensions and if they
         * aren't set (in case of software rendering) use the PS 3.0 from
         * MSDN or else if there's OpenGL spec use a hardcoded value minimum
         * PS 3.0 value. */

        /* Caps is more or less undocumented on MSDN but it appears to be
         * used for PS20Caps based on results from R9600/FX5900/Geforce6800
         * cards from Windows */
6060
        caps->PS20Caps.caps = WINED3DPS20CAPS_ARBITRARYSWIZZLE |
6061 6062 6063 6064
                WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
                WINED3DPS20CAPS_PREDICATION          |
                WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
                WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
6065
        /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
6066 6067
        caps->PS20Caps.dynamic_flow_control_depth = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH;
        caps->PS20Caps.temp_count = max(32, adapter->gl_info.limits.arb_ps_temps);
6068
        /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
6069
        caps->PS20Caps.static_flow_control_depth = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH;
6070
        /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
6071
        caps->PS20Caps.instruction_slot_count = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS;
6072 6073 6074

        caps->MaxPShaderInstructionsExecuted = 65535;
        caps->MaxPixelShader30InstructionSlots = max(WINED3DMIN30SHADERINSTRUCTIONS,
6075 6076
                adapter->gl_info.limits.arb_ps_instructions);
    }
6077
    else if(caps->PixelShaderVersion == 2)
6078
    {
6079
        /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
6080 6081 6082 6083
        caps->PS20Caps.caps = 0;
        caps->PS20Caps.dynamic_flow_control_depth = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
        caps->PS20Caps.temp_count = max(12, adapter->gl_info.limits.arb_ps_temps);
        caps->PS20Caps.static_flow_control_depth = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minimum: 1 */
6084
        /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
6085
        caps->PS20Caps.instruction_slot_count = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS;
6086 6087 6088 6089 6090 6091

        caps->MaxPShaderInstructionsExecuted    = 512; /* Minimum value, a GeforceFX uses 1024 */
        caps->MaxPixelShader30InstructionSlots  = 0;
    }
    else /* PS 1.x */
    {
6092 6093 6094 6095 6096
        caps->PS20Caps.caps = 0;
        caps->PS20Caps.dynamic_flow_control_depth = 0;
        caps->PS20Caps.temp_count = 0;
        caps->PS20Caps.static_flow_control_depth = 0;
        caps->PS20Caps.instruction_slot_count = 0;
6097 6098 6099 6100 6101

        caps->MaxPShaderInstructionsExecuted    = 0;
        caps->MaxPixelShader30InstructionSlots  = 0;
    }

6102
    if (caps->VertexShaderVersion >= 2)
6103
    {
6104 6105 6106 6107 6108 6109 6110
        /* OpenGL supports all the formats below, perhaps not always
         * without conversion, but it supports them.
         * Further GLSL doesn't seem to have an official unsigned type so
         * don't advertise it yet as I'm not sure how we handle it.
         * We might need to add some clamping in the shader engine to
         * support it.
         * TODO: WINED3DDTCAPS_USHORT2N, WINED3DDTCAPS_USHORT4N, WINED3DDTCAPS_UDEC3, WINED3DDTCAPS_DEC3N */
6111 6112 6113 6114
        caps->DeclTypes = WINED3DDTCAPS_UBYTE4    |
                          WINED3DDTCAPS_UBYTE4N   |
                          WINED3DDTCAPS_SHORT2N   |
                          WINED3DDTCAPS_SHORT4N;
6115 6116
        if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
        {
6117 6118
            caps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 |
                               WINED3DDTCAPS_FLOAT16_4;
6119
        }
6120 6121 6122 6123 6124
    }
    else
    {
        caps->DeclTypes = 0;
    }
6125

6126 6127 6128 6129 6130 6131 6132 6133 6134 6135
    /* Set DirectDraw helper Caps */
    ckey_caps =                         WINEDDCKEYCAPS_DESTBLT              |
                                        WINEDDCKEYCAPS_SRCBLT;
    fx_caps =                           WINEDDFXCAPS_BLTALPHA               |
                                        WINEDDFXCAPS_BLTMIRRORLEFTRIGHT     |
                                        WINEDDFXCAPS_BLTMIRRORUPDOWN        |
                                        WINEDDFXCAPS_BLTROTATION90          |
                                        WINEDDFXCAPS_BLTSHRINKX             |
                                        WINEDDFXCAPS_BLTSHRINKXN            |
                                        WINEDDFXCAPS_BLTSHRINKY             |
6136
                                        WINEDDFXCAPS_BLTSHRINKYN            |
6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148
                                        WINEDDFXCAPS_BLTSTRETCHX            |
                                        WINEDDFXCAPS_BLTSTRETCHXN           |
                                        WINEDDFXCAPS_BLTSTRETCHY            |
                                        WINEDDFXCAPS_BLTSTRETCHYN;
    blit_caps =                         WINEDDCAPS_BLT                      |
                                        WINEDDCAPS_BLTCOLORFILL             |
                                        WINEDDCAPS_BLTDEPTHFILL             |
                                        WINEDDCAPS_BLTSTRETCH               |
                                        WINEDDCAPS_CANBLTSYSMEM             |
                                        WINEDDCAPS_CANCLIP                  |
                                        WINEDDCAPS_CANCLIPSTRETCHED         |
                                        WINEDDCAPS_COLORKEY                 |
6149
                                        WINEDDCAPS_COLORKEYHWASSIST;
6150 6151

    /* Fill the ddraw caps structure */
6152
    caps->ddraw_caps.caps =             WINEDDCAPS_GDI                      |
6153
                                        WINEDDCAPS_PALETTE                  |
6154
                                        blit_caps;
6155 6156 6157 6158
    caps->ddraw_caps.caps2 =            WINEDDCAPS2_CERTIFIED               |
                                        WINEDDCAPS2_NOPAGELOCKREQUIRED      |
                                        WINEDDCAPS2_PRIMARYGAMMA            |
                                        WINEDDCAPS2_WIDESURFACES            |
6159
                                        WINEDDCAPS2_CANRENDERWINDOWED;
6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172
    caps->ddraw_caps.color_key_caps = ckey_caps;
    caps->ddraw_caps.fx_caps = fx_caps;
    caps->ddraw_caps.svb_caps = blit_caps;
    caps->ddraw_caps.svb_color_key_caps = ckey_caps;
    caps->ddraw_caps.svb_fx_caps = fx_caps;
    caps->ddraw_caps.vsb_caps = blit_caps;
    caps->ddraw_caps.vsb_color_key_caps = ckey_caps;
    caps->ddraw_caps.vsb_fx_caps = fx_caps;
    caps->ddraw_caps.ssb_caps = blit_caps;
    caps->ddraw_caps.ssb_color_key_caps = ckey_caps;
    caps->ddraw_caps.ssb_fx_caps = fx_caps;

    caps->ddraw_caps.dds_caps =         WINEDDSCAPS_ALPHA                   |
6173 6174 6175 6176 6177 6178 6179 6180
                                        WINEDDSCAPS_BACKBUFFER              |
                                        WINEDDSCAPS_FLIP                    |
                                        WINEDDSCAPS_FRONTBUFFER             |
                                        WINEDDSCAPS_OFFSCREENPLAIN          |
                                        WINEDDSCAPS_PALETTE                 |
                                        WINEDDSCAPS_PRIMARYSURFACE          |
                                        WINEDDSCAPS_SYSTEMMEMORY            |
                                        WINEDDSCAPS_VIDEOMEMORY             |
6181 6182
                                        WINEDDSCAPS_VISIBLE;

6183
    if (!(wined3d->flags & WINED3D_NO3D))
6184
    {
6185
        caps->ddraw_caps.dds_caps |=    WINEDDSCAPS_3DDEVICE                |
6186 6187 6188
                                        WINEDDSCAPS_MIPMAP                  |
                                        WINEDDSCAPS_TEXTURE                 |
                                        WINEDDSCAPS_ZBUFFER;
6189
        caps->ddraw_caps.caps |=        WINEDDCAPS_3D;
6190 6191
    }

6192 6193
    caps->shader_double_precision = d3d_info->shader_double_precision;

6194
    return WINED3D_OK;
6195 6196
}

6197
HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, enum wined3d_device_type device_type,
6198 6199
        HWND focus_window, DWORD flags, BYTE surface_alignment, struct wined3d_device_parent *device_parent,
        struct wined3d_device **device)
6200
{
6201
    struct wined3d_device *object;
6202
    HRESULT hr;
6203

Andrey Gusev's avatar
Andrey Gusev committed
6204 6205
    TRACE("wined3d %p, adapter_idx %u, device_type %#x, focus_window %p, flags %#x, surface_alignment %u, device_parent %p, device %p.\n",
            wined3d, adapter_idx, device_type, focus_window, flags, surface_alignment, device_parent, device);
6206

6207
    /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
6208
     * number and create a device without a 3D adapter for 2D only operation. */
6209
    if (wined3d->adapter_count && adapter_idx >= wined3d->adapter_count)
6210
        return WINED3DERR_INVALIDCALL;
6211

6212
    if (!(object = heap_alloc_zero(sizeof(*object))))
6213
        return E_OUTOFMEMORY;
6214

6215 6216
    hr = device_init(object, wined3d, adapter_idx, device_type,
            focus_window, flags, surface_alignment, device_parent);
6217 6218 6219
    if (FAILED(hr))
    {
        WARN("Failed to initialize device, hr %#x.\n", hr);
6220
        heap_free(object);
6221 6222
        return hr;
    }
6223

6224
    TRACE("Created device %p.\n", object);
6225
    *device = object;
6226

6227
    device_parent->ops->wined3d_device_created(device_parent, *device);
6228

6229 6230
    return WINED3D_OK;
}
6231

6232 6233
static void WINE_GLAPI invalid_func(const void *data)
{
6234
    ERR("Invalid vertex attribute function called.\n");
6235 6236 6237
    DebugBreak();
}

6238 6239
static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data)
{
6240
    ERR("Invalid texcoord function called.\n");
6241 6242 6243
    DebugBreak();
}

6244 6245 6246 6247 6248 6249
static void WINE_GLAPI invalid_generic_attrib_func(GLuint idx, const void *data)
{
    ERR("Invalid attribute function called.\n");
    DebugBreak();
}

6250 6251 6252
/* Helper functions for providing vertex data to OpenGL. The arrays are
 * initialised based on the extension detection and are used in
 * draw_primitive_immediate_mode(). */
6253 6254 6255
static void WINE_GLAPI position_d3dcolor(const void *data)
{
    DWORD pos = *((const DWORD *)data);
6256

6257
    FIXME("Add a test for fixed function position from d3dcolor type.\n");
6258 6259 6260 6261
    context_get_current()->gl_info->gl_ops.gl.p_glVertex4s(D3DCOLOR_B_R(pos),
            D3DCOLOR_B_G(pos),
            D3DCOLOR_B_B(pos),
            D3DCOLOR_B_A(pos));
6262
}
6263 6264 6265 6266

static void WINE_GLAPI position_float4(const void *data)
{
    const GLfloat *pos = data;
6267

6268
    if (pos[3] != 0.0f && pos[3] != 1.0f)
6269
    {
6270
        float w = 1.0f / pos[3];
6271

6272
        context_get_current()->gl_info->gl_ops.gl.p_glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w);
6273
    }
6274 6275
    else
    {
6276
        context_get_current()->gl_info->gl_ops.gl.p_glVertex3fv(pos);
6277
    }
6278 6279
}

6280 6281 6282
static void WINE_GLAPI diffuse_d3dcolor(const void *data)
{
    DWORD diffuseColor = *((const DWORD *)data);
6283

6284 6285 6286 6287
    context_get_current()->gl_info->gl_ops.gl.p_glColor4ub(D3DCOLOR_B_R(diffuseColor),
            D3DCOLOR_B_G(diffuseColor),
            D3DCOLOR_B_B(diffuseColor),
            D3DCOLOR_B_A(diffuseColor));
6288 6289
}

6290 6291 6292
static void WINE_GLAPI specular_d3dcolor(const void *data)
{
    DWORD specularColor = *((const DWORD *)data);
6293 6294 6295 6296 6297 6298
    GLubyte d[] =
    {
        D3DCOLOR_B_R(specularColor),
        D3DCOLOR_B_G(specularColor),
        D3DCOLOR_B_B(specularColor)
    };
6299

6300
    context_get_current()->gl_info->gl_ops.ext.p_glSecondaryColor3ubvEXT(d);
6301
}
6302 6303 6304

static void WINE_GLAPI warn_no_specular_func(const void *data)
{
6305
    WARN("GL_EXT_secondary_color not supported.\n");
6306 6307
}

6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348
static void WINE_GLAPI generic_d3dcolor(GLuint idx, const void *data)
{
    DWORD color = *((const DWORD *)data);

    context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib4Nub(idx,
            D3DCOLOR_B_R(color), D3DCOLOR_B_G(color),
            D3DCOLOR_B_B(color), D3DCOLOR_B_A(color));
}

static void WINE_GLAPI generic_short2n(GLuint idx, const void *data)
{
    const GLshort s[] = {((const GLshort *)data)[0], ((const GLshort *)data)[1], 0, 1};

    context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib4Nsv(idx, s);
}

static void WINE_GLAPI generic_ushort2n(GLuint idx, const void *data)
{
    const GLushort s[] = {((const GLushort *)data)[0], ((const GLushort *)data)[1], 0, 1};

    context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib4Nusv(idx, s);
}

static void WINE_GLAPI generic_float16_2(GLuint idx, const void *data)
{
    float x = float_16_to_32(((const unsigned short *)data) + 0);
    float y = float_16_to_32(((const unsigned short *)data) + 1);

    context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib2f(idx, x, y);
}

static void WINE_GLAPI generic_float16_4(GLuint idx, const void *data)
{
    float x = float_16_to_32(((const unsigned short *)data) + 0);
    float y = float_16_to_32(((const unsigned short *)data) + 1);
    float z = float_16_to_32(((const unsigned short *)data) + 2);
    float w = float_16_to_32(((const unsigned short *)data) + 3);

    context_get_current()->gl_info->gl_ops.ext.p_glVertexAttrib4f(idx, x, y, z, w);
}

6349
static void wined3d_adapter_init_ffp_attrib_ops(struct wined3d_adapter *adapter)
6350
{
6351
    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
6352 6353
    struct wined3d_d3d_info *d3d_info = &adapter->d3d_info;
    struct wined3d_ffp_attrib_ops *ops = &d3d_info->ffp_attrib_ops;
6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364
    unsigned int i;

    for (i = 0; i < WINED3D_FFP_EMIT_COUNT; ++i)
    {
        ops->position[i] = invalid_func;
        ops->diffuse[i]  = invalid_func;
        ops->specular[i] = invalid_func;
        ops->normal[i]   = invalid_func;
        ops->texcoord[i] = invalid_texcoord_func;
        ops->generic[i]  = invalid_generic_attrib_func;
    }
6365

6366
    ops->position[WINED3D_FFP_EMIT_FLOAT3]    = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glVertex3fv;
6367
    if (!d3d_info->xyzrhw)
6368
        ops->position[WINED3D_FFP_EMIT_FLOAT4]    = position_float4;
6369
    else
6370 6371 6372
        ops->position[WINED3D_FFP_EMIT_FLOAT4]    = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glVertex4fv;
    ops->position[WINED3D_FFP_EMIT_D3DCOLOR]  = position_d3dcolor;
    ops->position[WINED3D_FFP_EMIT_SHORT4]    = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glVertex2sv;
6373

6374 6375 6376 6377 6378 6379 6380 6381
    ops->diffuse[WINED3D_FFP_EMIT_FLOAT3]     = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor3fv;
    ops->diffuse[WINED3D_FFP_EMIT_FLOAT4]     = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4fv;
    ops->diffuse[WINED3D_FFP_EMIT_D3DCOLOR]   = diffuse_d3dcolor;
    ops->diffuse[WINED3D_FFP_EMIT_UBYTE4N]    = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4ubv;
    ops->diffuse[WINED3D_FFP_EMIT_SHORT4N]    = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4sv;
    ops->diffuse[WINED3D_FFP_EMIT_USHORT4N]   = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glColor4usv;

    /* No 4 component entry points here. */
6382
    if (gl_info->supported[EXT_SECONDARY_COLOR])
6383
        ops->specular[WINED3D_FFP_EMIT_FLOAT3]    = (wined3d_ffp_attrib_func)GL_EXTCALL(glSecondaryColor3fvEXT);
6384
    else
6385
        ops->specular[WINED3D_FFP_EMIT_FLOAT3]    = warn_no_specular_func;
6386
    if (gl_info->supported[EXT_SECONDARY_COLOR])
6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404
        ops->specular[WINED3D_FFP_EMIT_D3DCOLOR]  = specular_d3dcolor;
    else
        ops->specular[WINED3D_FFP_EMIT_D3DCOLOR]  = warn_no_specular_func;

    /* Only 3 component entry points here. Test how others behave. Float4
     * normals are used by one of our tests, trying to pass it to the pixel
     * shader, which fails on Windows. */
    ops->normal[WINED3D_FFP_EMIT_FLOAT3]      = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glNormal3fv;
    /* Just ignore the 4th value. */
    ops->normal[WINED3D_FFP_EMIT_FLOAT4]      = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glNormal3fv;

    ops->texcoord[WINED3D_FFP_EMIT_FLOAT1]    = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord1fvARB;
    ops->texcoord[WINED3D_FFP_EMIT_FLOAT2]    = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord2fvARB;
    ops->texcoord[WINED3D_FFP_EMIT_FLOAT3]    = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord3fvARB;
    ops->texcoord[WINED3D_FFP_EMIT_FLOAT4]    = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord4fvARB;
    ops->texcoord[WINED3D_FFP_EMIT_SHORT2]    = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord2svARB;
    ops->texcoord[WINED3D_FFP_EMIT_SHORT4]    = (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord4svARB;
    if (gl_info->supported[NV_HALF_FLOAT])
6405
    {
6406 6407 6408 6409 6410
        /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT. */
        ops->texcoord[WINED3D_FFP_EMIT_FLOAT16_2] =
                (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord2hvNV;
        ops->texcoord[WINED3D_FFP_EMIT_FLOAT16_4] =
                (wined3d_ffp_texcoord_func)gl_info->gl_ops.ext.p_glMultiTexCoord4hvNV;
6411
    }
6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441

    ops->generic[WINED3D_FFP_EMIT_FLOAT1]     = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib1fv;
    ops->generic[WINED3D_FFP_EMIT_FLOAT2]     = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib2fv;
    ops->generic[WINED3D_FFP_EMIT_FLOAT3]     = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib3fv;
    ops->generic[WINED3D_FFP_EMIT_FLOAT4]     = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4fv;
    if (gl_info->supported[ARB_VERTEX_ARRAY_BGRA])
        ops->generic[WINED3D_FFP_EMIT_D3DCOLOR] = generic_d3dcolor;
    else
        ops->generic[WINED3D_FFP_EMIT_D3DCOLOR] =
                (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nubv;
    ops->generic[WINED3D_FFP_EMIT_UBYTE4]     = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4ubv;
    ops->generic[WINED3D_FFP_EMIT_SHORT2]     = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib2sv;
    ops->generic[WINED3D_FFP_EMIT_SHORT4]     = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4sv;
    ops->generic[WINED3D_FFP_EMIT_UBYTE4N]    = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nubv;
    ops->generic[WINED3D_FFP_EMIT_SHORT2N]    = generic_short2n;
    ops->generic[WINED3D_FFP_EMIT_SHORT4N]    = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nsv;
    ops->generic[WINED3D_FFP_EMIT_USHORT2N]   = generic_ushort2n;
    ops->generic[WINED3D_FFP_EMIT_USHORT4N]   = (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4Nusv;
    if (gl_info->supported[NV_HALF_FLOAT] && gl_info->supported[NV_VERTEX_PROGRAM])
    {
        ops->generic[WINED3D_FFP_EMIT_FLOAT16_2] =
                (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib2hvNV;
        ops->generic[WINED3D_FFP_EMIT_FLOAT16_4] =
                (wined3d_generic_attrib_func)gl_info->gl_ops.ext.p_glVertexAttrib4hvNV;
    }
    else
    {
        ops->generic[WINED3D_FFP_EMIT_FLOAT16_2] = generic_float16_2;
        ops->generic[WINED3D_FFP_EMIT_FLOAT16_4] = generic_float16_4;
    }
6442 6443
}

6444 6445 6446
static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc)
{
    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
6447
    int i;
6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459

    if (gl_info->supported[WGL_ARB_PIXEL_FORMAT])
    {
        UINT attrib_count = 0;
        GLint cfg_count;
        int attribs[11];
        int values[11];
        int attribute;

        attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
        GL_EXTCALL(wglGetPixelFormatAttribivARB(dc, 0, 0, 1, &attribute, &cfg_count));

6460
        adapter->cfgs = heap_calloc(cfg_count, sizeof(*adapter->cfgs));
6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524
        attribs[attrib_count++] = WGL_RED_BITS_ARB;
        attribs[attrib_count++] = WGL_GREEN_BITS_ARB;
        attribs[attrib_count++] = WGL_BLUE_BITS_ARB;
        attribs[attrib_count++] = WGL_ALPHA_BITS_ARB;
        attribs[attrib_count++] = WGL_COLOR_BITS_ARB;
        attribs[attrib_count++] = WGL_DEPTH_BITS_ARB;
        attribs[attrib_count++] = WGL_STENCIL_BITS_ARB;
        attribs[attrib_count++] = WGL_DRAW_TO_WINDOW_ARB;
        attribs[attrib_count++] = WGL_PIXEL_TYPE_ARB;
        attribs[attrib_count++] = WGL_DOUBLE_BUFFER_ARB;
        attribs[attrib_count++] = WGL_AUX_BUFFERS_ARB;

        for (i = 0, adapter->cfg_count = 0; i < cfg_count; ++i)
        {
            struct wined3d_pixel_format *cfg = &adapter->cfgs[adapter->cfg_count];
            int format_id = i + 1;

            if (!GL_EXTCALL(wglGetPixelFormatAttribivARB(dc, format_id, 0, attrib_count, attribs, values)))
                continue;

            cfg->iPixelFormat = format_id;
            cfg->redSize = values[0];
            cfg->greenSize = values[1];
            cfg->blueSize = values[2];
            cfg->alphaSize = values[3];
            cfg->colorSize = values[4];
            cfg->depthSize = values[5];
            cfg->stencilSize = values[6];
            cfg->windowDrawable = values[7];
            cfg->iPixelType = values[8];
            cfg->doubleBuffer = values[9];
            cfg->auxBuffers = values[10];

            cfg->numSamples = 0;
            /* Check multisample support. */
            if (gl_info->supported[ARB_MULTISAMPLE])
            {
                int attribs[2] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
                int values[2];

                if (GL_EXTCALL(wglGetPixelFormatAttribivARB(dc, format_id, 0, 2, attribs, values)))
                {
                    /* values[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether
                     * multisampling is supported. values[1] = number of
                     * multisample buffers. */
                    if (values[0])
                        cfg->numSamples = values[1];
                }
            }

            TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
                    "depth=%d, stencil=%d, samples=%d, windowDrawable=%d\n",
                    cfg->iPixelFormat, cfg->iPixelType, cfg->doubleBuffer,
                    cfg->redSize, cfg->greenSize, cfg->blueSize, cfg->alphaSize,
                    cfg->depthSize, cfg->stencilSize, cfg->numSamples, cfg->windowDrawable);

            ++adapter->cfg_count;
        }
    }
    else
    {
        int cfg_count;

        cfg_count = DescribePixelFormat(dc, 0, 0, 0);
6525
        adapter->cfgs = heap_calloc(cfg_count, sizeof(*adapter->cfgs));
6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570

        for (i = 0, adapter->cfg_count = 0; i < cfg_count; ++i)
        {
            struct wined3d_pixel_format *cfg = &adapter->cfgs[adapter->cfg_count];
            PIXELFORMATDESCRIPTOR pfd;
            int format_id = i + 1;

            if (!DescribePixelFormat(dc, format_id, sizeof(pfd), &pfd))
                continue;

            /* We only want HW acceleration using an OpenGL ICD driver.
             * PFD_GENERIC_FORMAT = slow opengl 1.1 gdi software rendering.
             * PFD_GENERIC_ACCELERATED = partial hw acceleration using a MCD
             * driver (e.g. 3dfx minigl). */
            if (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED))
            {
                TRACE("Skipping format %d because it isn't ICD accelerated.\n", format_id);
                continue;
            }

            cfg->iPixelFormat = format_id;
            cfg->redSize = pfd.cRedBits;
            cfg->greenSize = pfd.cGreenBits;
            cfg->blueSize = pfd.cBlueBits;
            cfg->alphaSize = pfd.cAlphaBits;
            cfg->colorSize = pfd.cColorBits;
            cfg->depthSize = pfd.cDepthBits;
            cfg->stencilSize = pfd.cStencilBits;
            cfg->windowDrawable = (pfd.dwFlags & PFD_DRAW_TO_WINDOW) ? 1 : 0;
            cfg->iPixelType = (pfd.iPixelType == PFD_TYPE_RGBA) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB;
            cfg->doubleBuffer = (pfd.dwFlags & PFD_DOUBLEBUFFER) ? 1 : 0;
            cfg->auxBuffers = pfd.cAuxBuffers;
            cfg->numSamples = 0;

            TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, "
                    "depth=%d, stencil=%d, windowDrawable=%d\n",
                    cfg->iPixelFormat, cfg->iPixelType, cfg->doubleBuffer,
                    cfg->redSize, cfg->greenSize, cfg->blueSize, cfg->alphaSize,
                    cfg->depthSize, cfg->stencilSize, cfg->windowDrawable);

            ++adapter->cfg_count;
        }
    }
}

6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586
static DWORD get_max_gl_version(const struct wined3d_gl_info *gl_info, DWORD flags)
{
    const char *gl_vendor, *gl_renderer;

    if (wined3d_settings.explicit_gl_version || (flags & WINED3D_PIXEL_CENTER_INTEGER))
        return wined3d_settings.max_gl_version;

    gl_vendor = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_VENDOR);
    gl_renderer = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_RENDERER);
    if (!gl_vendor || !gl_renderer
            || wined3d_guess_card_vendor(gl_vendor, gl_renderer) == HW_VENDOR_NVIDIA)
        return wined3d_settings.max_gl_version;

    return MAKEDWORD_VERSION(4, 4);
}

6587
static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal, DWORD wined3d_creation_flags)
6588
{
6589 6590
    static const DWORD supported_gl_versions[] =
    {
6591
        MAKEDWORD_VERSION(4, 4),
6592 6593 6594
        MAKEDWORD_VERSION(3, 2),
        MAKEDWORD_VERSION(1, 0),
    };
6595
    struct wined3d_gl_info *gl_info = &adapter->gl_info;
6596
    struct wined3d_caps_gl_ctx caps_gl_ctx = {0};
6597
    unsigned int i;
6598
    DISPLAY_DEVICEW display_device;
6599
    DWORD max_gl_version;
6600

6601
    TRACE("adapter %p, ordinal %u.\n", adapter, ordinal);
6602

6603
    adapter->ordinal = ordinal;
6604

6605
/* Dynamically load all GL core functions */
6606
#ifdef USE_WIN32_OPENGL
6607 6608
    {
        HMODULE mod_gl = GetModuleHandleA("opengl32.dll");
6609
#define USE_GL_FUNC(f) gl_info->gl_ops.gl.p_##f = (void *)GetProcAddress(mod_gl, #f);
6610
        ALL_WGL_FUNCS
6611
#undef USE_GL_FUNC
6612
        gl_info->gl_ops.wgl.p_wglSwapBuffers = (void *)GetProcAddress(mod_gl, "wglSwapBuffers");
6613
        gl_info->gl_ops.wgl.p_wglGetPixelFormat = (void *)GetProcAddress(mod_gl, "wglGetPixelFormat");
6614
    }
6615
#else
6616
    /* To bypass the opengl32 thunks retrieve functions from the WGL driver instead of opengl32 */
6617 6618
    {
        HDC hdc = GetDC( 0 );
6619
        const struct opengl_funcs *wgl_driver = __wine_get_wgl_driver( hdc, WINE_WGL_DRIVER_VERSION );
6620
        ReleaseDC( 0, hdc );
6621
        if (!wgl_driver || wgl_driver == (void *)-1) return FALSE;
6622
        gl_info->gl_ops.wgl = wgl_driver->wgl;
6623
        gl_info->gl_ops.gl = wgl_driver->gl;
6624
    }
6625
#endif
6626

6627 6628
    glEnableWINE = gl_info->gl_ops.gl.p_glEnable;
    glDisableWINE = gl_info->gl_ops.gl.p_glDisable;
6629

6630
    if (!AllocateLocallyUniqueId(&adapter->luid))
6631
    {
6632 6633 6634 6635 6636
        ERR("Failed to set adapter LUID (%#x).\n", GetLastError());
        return FALSE;
    }
    TRACE("Allocated LUID %08x:%08x for adapter %p.\n",
            adapter->luid.HighPart, adapter->luid.LowPart, adapter);
6637

6638
    if (!wined3d_caps_gl_ctx_create(adapter, &caps_gl_ctx))
6639 6640 6641 6642
    {
        ERR("Failed to get a GL context for adapter %p.\n", adapter);
        return FALSE;
    }
6643

6644
    max_gl_version = get_max_gl_version(gl_info, wined3d_creation_flags);
6645 6646
    for (i = 0; i < ARRAY_SIZE(supported_gl_versions); ++i)
    {
6647
        if (supported_gl_versions[i] <= max_gl_version)
6648 6649 6650
            break;
    }
    if (i == ARRAY_SIZE(supported_gl_versions))
6651
    {
6652
        ERR_(winediag)("Requested invalid GL version %u.%u.\n",
6653
                max_gl_version >> 16, max_gl_version & 0xffff);
6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665
        i = ARRAY_SIZE(supported_gl_versions) - 1;
    }

    for (; i < ARRAY_SIZE(supported_gl_versions); ++i)
    {
        gl_info->selected_gl_version = supported_gl_versions[i];

        if (wined3d_caps_gl_ctx_create_attribs(&caps_gl_ctx, gl_info))
            break;

        WARN("Couldn't create an OpenGL %u.%u context, trying fallback to a lower version.\n",
                supported_gl_versions[i] >> 16, supported_gl_versions[i] & 0xffff);
6666
    }
6667

6668
    if (!wined3d_adapter_init_gl_caps(adapter, &caps_gl_ctx, wined3d_creation_flags))
6669 6670
    {
        ERR("Failed to initialize GL caps for adapter %p.\n", adapter);
6671
        wined3d_caps_gl_ctx_destroy(&caps_gl_ctx);
6672 6673
        return FALSE;
    }
6674

6675 6676 6677 6678
    if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER)
        ERR_(winediag)("You are using the backbuffer for offscreen rendering. "
                "This is unsupported, and will be removed in a future version.\n");

6679
    wined3d_adapter_init_fb_cfgs(adapter, caps_gl_ctx.dc);
6680 6681 6682 6683 6684
    /* We haven't found any suitable formats. This should only happen in
     * case of GDI software rendering, which is pretty useless anyway. */
    if (!adapter->cfg_count)
    {
        WARN("No suitable pixel formats found.\n");
6685
        wined3d_caps_gl_ctx_destroy(&caps_gl_ctx);
6686
        heap_free(adapter->cfgs);
6687 6688
        return FALSE;
    }
6689

6690
    if (!wined3d_adapter_init_format_info(adapter, &caps_gl_ctx))
6691 6692
    {
        ERR("Failed to initialize GL format info.\n");
6693
        wined3d_caps_gl_ctx_destroy(&caps_gl_ctx);
6694
        heap_free(adapter->cfgs);
6695 6696
        return FALSE;
    }
6697

6698 6699 6700
    adapter->vram_bytes = adapter->driver_info.vram_bytes;
    adapter->vram_bytes_used = 0;
    TRACE("Emulating 0x%s bytes of video ram.\n", wine_dbgstr_longlong(adapter->vram_bytes));
6701

6702 6703 6704 6705
    display_device.cb = sizeof(display_device);
    EnumDisplayDevicesW(NULL, ordinal, &display_device, 0);
    TRACE("DeviceName: %s\n", debugstr_w(display_device.DeviceName));
    strcpyW(adapter->DeviceName, display_device.DeviceName);
6706

6707
    wined3d_caps_gl_ctx_destroy(&caps_gl_ctx);
6708

6709
    wined3d_adapter_init_ffp_attrib_ops(adapter);
6710 6711

    return TRUE;
6712
}
6713

6714
static BOOL wined3d_adapter_init_nogl(struct wined3d_adapter *adapter, UINT ordinal)
6715
{
6716 6717
    DISPLAY_DEVICEW display_device;

6718 6719
    memset(adapter, 0, sizeof(*adapter));
    adapter->ordinal = ordinal;
6720

6721 6722
    adapter->driver_info.name = "Display";
    adapter->driver_info.description = "WineD3D DirectDraw Emulation";
6723
    if (wined3d_settings.emulated_textureram)
6724
        adapter->vram_bytes = wined3d_settings.emulated_textureram;
6725
    else
6726
        adapter->vram_bytes = 128 * 1024 * 1024;
6727

6728 6729
    if (!wined3d_adapter_init_format_info(adapter, NULL))
        return FALSE;
6730

6731
    adapter->vertex_pipe = &none_vertex_pipe;
6732 6733
    adapter->fragment_pipe = &none_fragment_pipe;
    adapter->shader_backend = &none_shader_backend;
6734 6735 6736 6737 6738

    display_device.cb = sizeof(display_device);
    EnumDisplayDevicesW(NULL, ordinal, &display_device, 0);
    TRACE("DeviceName: %s\n", debugstr_w(display_device.DeviceName));
    strcpyW(adapter->DeviceName, display_device.DeviceName);
6739 6740

    return TRUE;
6741 6742
}

6743 6744 6745 6746 6747 6748
static void STDMETHODCALLTYPE wined3d_null_wined3d_object_destroyed(void *parent) {}

const struct wined3d_parent_ops wined3d_null_parent_ops =
{
    wined3d_null_wined3d_object_destroyed,
};
6749

6750
HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags)
6751
{
6752 6753
    BOOL ret;

6754
    wined3d->ref = 1;
6755
    wined3d->flags = flags;
6756

6757 6758
    TRACE("Initializing adapters.\n");

6759
    if (flags & WINED3D_NO3D)
6760 6761 6762 6763
        ret = wined3d_adapter_init_nogl(&wined3d->adapters[0], 0);
    else
        ret = wined3d_adapter_init(&wined3d->adapters[0], 0, flags);
    if (!ret)
6764
    {
6765
        WARN("Failed to initialize adapter.\n");
6766
        return E_FAIL;
6767
    }
6768
    wined3d->adapter_count = 1;
6769 6770 6771

    return WINED3D_OK;
}