directx.c 322 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_blend_func_extended",          ARB_BLEND_FUNC_EXTENDED       },
113
    {"GL_ARB_clear_buffer_object",          ARB_CLEAR_BUFFER_OBJECT       },
114
    {"GL_ARB_clear_texture",                ARB_CLEAR_TEXTURE             },
115
    {"GL_ARB_clip_control",                 ARB_CLIP_CONTROL              },
116
    {"GL_ARB_color_buffer_float",           ARB_COLOR_BUFFER_FLOAT        },
117
    {"GL_ARB_compute_shader",               ARB_COMPUTE_SHADER            },
118
    {"GL_ARB_copy_buffer",                  ARB_COPY_BUFFER               },
119
    {"GL_ARB_debug_output",                 ARB_DEBUG_OUTPUT              },
120 121
    {"GL_ARB_depth_buffer_float",           ARB_DEPTH_BUFFER_FLOAT        },
    {"GL_ARB_depth_texture",                ARB_DEPTH_TEXTURE             },
122
    {"GL_ARB_derivative_control",           ARB_DERIVATIVE_CONTROL        },
123 124
    {"GL_ARB_draw_buffers",                 ARB_DRAW_BUFFERS              },
    {"GL_ARB_draw_elements_base_vertex",    ARB_DRAW_ELEMENTS_BASE_VERTEX },
125
    {"GL_ARB_draw_instanced",               ARB_DRAW_INSTANCED            },
126
    {"GL_ARB_ES2_compatibility",            ARB_ES2_COMPATIBILITY         },
127
    {"GL_ARB_ES3_compatibility",            ARB_ES3_COMPATIBILITY         },
128
    {"GL_ARB_explicit_attrib_location",     ARB_EXPLICIT_ATTRIB_LOCATION  },
129
    {"GL_ARB_fragment_coord_conventions",   ARB_FRAGMENT_COORD_CONVENTIONS},
130
    {"GL_ARB_fragment_layer_viewport",      ARB_FRAGMENT_LAYER_VIEWPORT   },
131 132 133
    {"GL_ARB_fragment_program",             ARB_FRAGMENT_PROGRAM          },
    {"GL_ARB_fragment_shader",              ARB_FRAGMENT_SHADER           },
    {"GL_ARB_framebuffer_object",           ARB_FRAMEBUFFER_OBJECT        },
134
    {"GL_ARB_framebuffer_sRGB",             ARB_FRAMEBUFFER_SRGB          },
135
    {"GL_ARB_geometry_shader4",             ARB_GEOMETRY_SHADER4          },
136
    {"GL_ARB_gpu_shader5",                  ARB_GPU_SHADER5               },
137 138
    {"GL_ARB_half_float_pixel",             ARB_HALF_FLOAT_PIXEL          },
    {"GL_ARB_half_float_vertex",            ARB_HALF_FLOAT_VERTEX         },
139 140 141
    {"GL_ARB_instanced_arrays",             ARB_INSTANCED_ARRAYS          },
    {"GL_ARB_internalformat_query",         ARB_INTERNALFORMAT_QUERY      },
    {"GL_ARB_internalformat_query2",        ARB_INTERNALFORMAT_QUERY2     },
142 143
    {"GL_ARB_map_buffer_alignment",         ARB_MAP_BUFFER_ALIGNMENT      },
    {"GL_ARB_map_buffer_range",             ARB_MAP_BUFFER_RANGE          },
144
    {"GL_ARB_multisample",                  ARB_MULTISAMPLE               },
145 146
    {"GL_ARB_multitexture",                 ARB_MULTITEXTURE              },
    {"GL_ARB_occlusion_query",              ARB_OCCLUSION_QUERY           },
147
    {"GL_ARB_pipeline_statistics_query",    ARB_PIPELINE_STATISTICS_QUERY },
148 149 150 151
    {"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          },
152
    {"GL_ARB_sampler_objects",              ARB_SAMPLER_OBJECTS           },
153
    {"GL_ARB_seamless_cube_map",            ARB_SEAMLESS_CUBE_MAP         },
154
    {"GL_ARB_shader_atomic_counters",       ARB_SHADER_ATOMIC_COUNTERS    },
155
    {"GL_ARB_shader_bit_encoding",          ARB_SHADER_BIT_ENCODING       },
156
    {"GL_ARB_shader_image_load_store",      ARB_SHADER_IMAGE_LOAD_STORE   },
157
    {"GL_ARB_shader_image_size",            ARB_SHADER_IMAGE_SIZE         },
158
    {"GL_ARB_shader_storage_buffer_object", ARB_SHADER_STORAGE_BUFFER_OBJECT},
159 160
    {"GL_ARB_shader_texture_lod",           ARB_SHADER_TEXTURE_LOD        },
    {"GL_ARB_shading_language_100",         ARB_SHADING_LANGUAGE_100      },
161
    {"GL_ARB_shading_language_420pack",     ARB_SHADING_LANGUAGE_420PACK  },
162
    {"GL_ARB_shading_language_packing",     ARB_SHADING_LANGUAGE_PACKING  },
163
    {"GL_ARB_shadow",                       ARB_SHADOW                    },
164
    {"GL_ARB_stencil_texturing",            ARB_STENCIL_TEXTURING         },
165
    {"GL_ARB_sync",                         ARB_SYNC                      },
166
    {"GL_ARB_tessellation_shader",          ARB_TESSELLATION_SHADER       },
167
    {"GL_ARB_texture_border_clamp",         ARB_TEXTURE_BORDER_CLAMP      },
168
    {"GL_ARB_texture_buffer_object",        ARB_TEXTURE_BUFFER_OBJECT     },
169
    {"GL_ARB_texture_buffer_range",         ARB_TEXTURE_BUFFER_RANGE      },
170
    {"GL_ARB_texture_compression",          ARB_TEXTURE_COMPRESSION       },
171
    {"GL_ARB_texture_compression_bptc",     ARB_TEXTURE_COMPRESSION_BPTC  },
172 173
    {"GL_ARB_texture_compression_rgtc",     ARB_TEXTURE_COMPRESSION_RGTC  },
    {"GL_ARB_texture_cube_map",             ARB_TEXTURE_CUBE_MAP          },
174
    {"GL_ARB_texture_cube_map_array",       ARB_TEXTURE_CUBE_MAP_ARRAY    },
175 176 177
    {"GL_ARB_texture_env_combine",          ARB_TEXTURE_ENV_COMBINE       },
    {"GL_ARB_texture_env_dot3",             ARB_TEXTURE_ENV_DOT3          },
    {"GL_ARB_texture_float",                ARB_TEXTURE_FLOAT             },
178
    {"GL_ARB_texture_gather",               ARB_TEXTURE_GATHER            },
179
    {"GL_ARB_texture_mirrored_repeat",      ARB_TEXTURE_MIRRORED_REPEAT   },
180
    {"GL_ARB_texture_mirror_clamp_to_edge", ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE},
181
    {"GL_ARB_texture_non_power_of_two",     ARB_TEXTURE_NON_POWER_OF_TWO  },
182
    {"GL_ARB_texture_query_levels",         ARB_TEXTURE_QUERY_LEVELS      },
183 184
    {"GL_ARB_texture_rectangle",            ARB_TEXTURE_RECTANGLE         },
    {"GL_ARB_texture_rg",                   ARB_TEXTURE_RG                },
185
    {"GL_ARB_texture_rgb10_a2ui",           ARB_TEXTURE_RGB10_A2UI        },
186
    {"GL_ARB_texture_storage",              ARB_TEXTURE_STORAGE           },
187
    {"GL_ARB_texture_swizzle",              ARB_TEXTURE_SWIZZLE           },
188
    {"GL_ARB_texture_view",                 ARB_TEXTURE_VIEW              },
189
    {"GL_ARB_timer_query",                  ARB_TIMER_QUERY               },
190
    {"GL_ARB_transform_feedback2",          ARB_TRANSFORM_FEEDBACK2       },
191
    {"GL_ARB_transform_feedback3",          ARB_TRANSFORM_FEEDBACK3       },
192
    {"GL_ARB_uniform_buffer_object",        ARB_UNIFORM_BUFFER_OBJECT     },
193 194 195 196 197
    {"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             },
198
    {"GL_ARB_vertex_type_2_10_10_10_rev",   ARB_VERTEX_TYPE_2_10_10_10_REV},
199
    {"GL_ARB_viewport_array",               ARB_VIEWPORT_ARRAY            },
200 201

    /* ATI */
202 203 204 205 206
    {"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       },
207 208

    /* EXT */
209 210 211 212 213 214 215 216 217 218 219 220 221 222
    {"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      },
223
    {"GL_EXT_packed_float",                 EXT_PACKED_FLOAT              },
224 225 226 227 228 229
    {"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                 },
230
    {"GL_EXT_texture_array",                EXT_TEXTURE_ARRAY             },
231 232 233 234 235
    {"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          },
    {"GL_EXT_texture_filter_anisotropic",   EXT_TEXTURE_FILTER_ANISOTROPIC},
236
    {"GL_EXT_texture_integer",              EXT_TEXTURE_INTEGER           },
237
    {"GL_EXT_texture_lod_bias",             EXT_TEXTURE_LOD_BIAS          },
238
    {"GL_EXT_texture_mirror_clamp",         EXT_TEXTURE_MIRROR_CLAMP      },
239
    {"GL_EXT_texture_shared_exponent",      EXT_TEXTURE_SHARED_EXPONENT   },
240
    {"GL_EXT_texture_snorm",                EXT_TEXTURE_SNORM             },
241 242 243
    {"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         },
244 245

    /* NV */
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
    {"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            },
265 266

    /* SGI */
267
    {"GL_SGIS_generate_mipmap",             SGIS_GENERATE_MIPMAP          },
268 269
};

270 271
static const struct wined3d_extension_map wgl_extension_map[] =
{
272 273 274
    {"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},
275
    {"WGL_WINE_query_renderer",             WGL_WINE_QUERY_RENDERER          },
276 277
};

278 279 280 281
/**********************************************************
 * Utility functions follow
 **********************************************************/

282
const struct min_lookup minMipLookup[] =
283
{
284
    /* NONE         POINT                       LINEAR */
285
    {{GL_NEAREST,   GL_NEAREST,                 GL_NEAREST}},               /* NONE */
286 287
    {{GL_NEAREST,   GL_NEAREST_MIPMAP_NEAREST,  GL_NEAREST_MIPMAP_LINEAR}}, /* POINT*/
    {{GL_LINEAR,    GL_LINEAR_MIPMAP_NEAREST,   GL_LINEAR_MIPMAP_LINEAR}},  /* LINEAR */
288
};
289

290 291
const GLenum magLookup[] =
{
292 293
    /* NONE     POINT       LINEAR */
    GL_NEAREST, GL_NEAREST, GL_LINEAR,
294 295
};

296
static void wined3d_caps_gl_ctx_destroy(const struct wined3d_caps_gl_ctx *ctx)
297
{
298 299
    const struct wined3d_gl_info *gl_info = ctx->gl_info;

300
    TRACE("Destroying caps GL context.\n");
301

302 303 304 305 306 307 308 309 310
    /* 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));
    }

311
    if (!wglMakeCurrent(NULL, NULL))
312
        ERR("Failed to disable caps GL context.\n");
313

314
    if (!wglDeleteContext(ctx->gl_ctx))
315 316 317 318 319
    {
        DWORD err = GetLastError();
        ERR("wglDeleteContext(%p) failed, last error %#x.\n", ctx->gl_ctx, err);
    }

320
    wined3d_release_dc(ctx->wnd, ctx->dc);
321
    DestroyWindow(ctx->wnd);
322

323
    if (ctx->restore_gl_ctx && !wglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx))
324
        ERR("Failed to restore previous GL context.\n");
325 326
}

327 328
static BOOL wined3d_caps_gl_ctx_create_attribs(struct wined3d_caps_gl_ctx *caps_gl_ctx,
        struct wined3d_gl_info *gl_info)
329 330 331 332
{
    HGLRC new_ctx;

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

335
    if (!(new_ctx = context_create_wgl_attribs(gl_info, caps_gl_ctx->dc, NULL)))
336 337
    {
        gl_info->p_wglCreateContextAttribsARB = NULL;
338
        return FALSE;
339 340
    }

341
    if (!wglMakeCurrent(caps_gl_ctx->dc, new_ctx))
342 343 344 345 346
    {
        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;
347
        return TRUE;
348 349
    }

350
    if (!wglDeleteContext(caps_gl_ctx->gl_ctx))
351
        ERR("Failed to delete old context, last error %#x.\n", GetLastError());
352
    caps_gl_ctx->gl_ctx = new_ctx;
353 354

    return TRUE;
355 356
}

357
static BOOL wined3d_caps_gl_ctx_create(struct wined3d_adapter *adapter, struct wined3d_caps_gl_ctx *ctx)
358
{
359 360
    PIXELFORMATDESCRIPTOR pfd;
    int iPixelFormat;
361

362
    TRACE("getting context...\n");
363

364 365
    ctx->restore_dc = wglGetCurrentDC();
    ctx->restore_gl_ctx = wglGetCurrentContext();
366

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

376 377
    ctx->dc = GetDC(ctx->wnd);
    if (!ctx->dc)
378
    {
379
        ERR("Failed to get a DC.\n");
380 381
        goto fail;
    }
382

383 384 385 386 387 388 389 390 391
    /* 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;

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

    /* Create a GL context. */
402
    if (!(ctx->gl_ctx = wglCreateContext(ctx->dc)))
403
    {
404
        WARN("Failed to create default context for capabilities initialization.\n");
405 406
        goto fail;
    }
407

408
    /* Make it the current GL context. */
409
    if (!wglMakeCurrent(ctx->dc, ctx->gl_ctx))
410
    {
411
        ERR("Failed to make caps GL context current.\n");
412
        goto fail;
413
    }
414

415
    ctx->gl_info = &adapter->gl_info;
416
    return TRUE;
417 418

fail:
419
    if (ctx->gl_ctx) wglDeleteContext(ctx->gl_ctx);
420 421 422 423 424
    ctx->gl_ctx = NULL;
    if (ctx->dc) ReleaseDC(ctx->wnd, ctx->dc);
    ctx->dc = NULL;
    if (ctx->wnd) DestroyWindow(ctx->wnd);
    ctx->wnd = NULL;
425
    if (ctx->restore_gl_ctx && !wglMakeCurrent(ctx->restore_dc, ctx->restore_gl_ctx))
426
        ERR("Failed to restore previous GL context.\n");
427

428
    return FALSE;
429 430
}

431
/* Adjust the amount of used texture memory */
432
UINT64 adapter_adjust_memory(struct wined3d_adapter *adapter, INT64 amount)
433
{
434 435 436 437 438
    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;
439
}
440

441 442
static void wined3d_adapter_cleanup(struct wined3d_adapter *adapter)
{
443
    HeapFree(GetProcessHeap(), 0, adapter->gl_info.formats);
444 445 446
    HeapFree(GetProcessHeap(), 0, adapter->cfgs);
}

447
ULONG CDECL wined3d_incref(struct wined3d *wined3d)
448
{
449
    ULONG refcount = InterlockedIncrement(&wined3d->ref);
450

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

453
    return refcount;
454 455
}

456 457 458 459 460
ULONG CDECL wined3d_decref(struct wined3d *wined3d)
{
    ULONG refcount = InterlockedDecrement(&wined3d->ref);

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

462
    if (!refcount)
463
    {
464 465
        unsigned int i;

466
        for (i = 0; i < wined3d->adapter_count; ++i)
467
        {
468
            wined3d_adapter_cleanup(&wined3d->adapters[i]);
469
        }
470
        HeapFree(GetProcessHeap(), 0, wined3d);
471
    }
472

473
    return refcount;
474 475
}

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

490
    while (gl_info->gl_ops.gl.p_glGetError());
491 492 493 494 495 496 497
    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));
498
    if (gl_info->gl_ops.gl.p_glGetError())
499
    {
500
        TRACE("OpenGL implementation does not allow indirect addressing offsets > 63\n");
501
        TRACE("error: %s\n", debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
502 503 504 505 506
        ret = TRUE;
    } else TRACE("OpenGL implementation allows offsets > 63\n");

    GL_EXTCALL(glBindProgramARB(GL_VERTEX_PROGRAM_ARB, 0));
    GL_EXTCALL(glDeleteProgramsARB(1, &prog));
507
    checkGLcall("ARB vp offset limit test cleanup");
508 509 510 511

    return ret;
}

512 513 514
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)
515
{
516 517 518 519
    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;
520 521
    return FALSE;
}
522

523 524 525
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)
526
{
527
    if (card_vendor == HW_VENDOR_NVIDIA)
528
    {
529 530 531
        if (device == CARD_NVIDIA_GEFORCEFX_5200 ||
            device == CARD_NVIDIA_GEFORCEFX_5600 ||
            device == CARD_NVIDIA_GEFORCEFX_5800)
532 533 534
        {
            return TRUE;
        }
535
    }
536 537
    return FALSE;
}
538

539 540 541
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)
542 543 544 545 546 547 548 549 550 551 552
{
    /* 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
553 554 555 556
     * DirectDraw, not OpenGL.
     *
     * This test has been moved into wined3d_guess_gl_vendor()
     */
557
    return gl_vendor == GL_VENDOR_APPLE;
558
}
559

560
/* Context activation is done by the caller. */
561
static void test_pbo_functionality(struct wined3d_gl_info *gl_info)
562 563 564 565 566 567 568 569 570 571 572 573 574
{
    /* 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[] =
575
    {
576 577 578 579 580 581
        0x00000000, 0x000000ff, 0x0000ff00, 0x40ff0000,
        0x80ffffff, 0x40ffff00, 0x00ff00ff, 0x0000ffff,
        0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x000000ff,
        0x80ff00ff, 0x0000ffff, 0x00ff00ff, 0x40ff00ff
    };
    unsigned int check[sizeof(pattern) / sizeof(pattern[0])];
582

583 584
    /* No PBO -> No point in testing them. */
    if (!gl_info->supported[ARB_PIXEL_BUFFER_OBJECT]) return;
585

586 587 588
    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);
589

590 591
    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);
592
    checkGLcall("Specifying the PBO test texture");
593

594 595 596
    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));
597
    checkGLcall("Specifying the PBO test pbo");
598

599
    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);
600
    checkGLcall("Loading the PBO test texture");
601

602
    GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
603

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

606
    memset(check, 0, sizeof(check));
607
    gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, check);
608
    checkGLcall("Reading back the PBO test texture");
609

610
    gl_info->gl_ops.gl.p_glDeleteTextures(1, &texture);
611
    GL_EXTCALL(glDeleteBuffers(1, &pbo));
612
    checkGLcall("PBO test cleanup");
613

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

626 627 628
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)
629
{
630
    return (card_vendor == HW_VENDOR_INTEL) && (gl_vendor == GL_VENDOR_APPLE);
631
}
632

633 634 635
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)
636
{
637
    if (gl_vendor != GL_VENDOR_APPLE) return FALSE;
638 639
    if (card_vendor != HW_VENDOR_AMD) return FALSE;
    if (device == CARD_AMD_RADEON_X1600) return FALSE;
640 641
    return TRUE;
}
642

643 644 645
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)
646 647 648 649
{
    /* 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
650
     * varyings and we subtract one in dx9 shaders it's not going to hurt us because the dx9 limit is
651 652 653
     * hardcoded
     *
     * dx10 cards usually have 64 varyings */
654
    return gl_info->limits.glsl_varyings > 44;
655
}
656

657 658 659
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)
660
{
661
    return !match_dx10_capable(gl_info, ctx, gl_renderer, gl_vendor, card_vendor, device);
662 663
}

664
/* A GL context is provided by the caller */
665 666 667
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)
668 669 670 671
{
    GLenum error;
    DWORD data[16];

672 673
    if (!gl_info->supported[EXT_SECONDARY_COLOR])
        return FALSE;
674

675
    while (gl_info->gl_ops.gl.p_glGetError());
676
    GL_EXTCALL(glSecondaryColorPointerEXT)(4, GL_UNSIGNED_BYTE, 4, data);
677
    error = gl_info->gl_ops.gl.p_glGetError();
678

679
    if (error == GL_NO_ERROR)
680 681 682 683 684 685 686 687 688 689 690 691
    {
        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;
    }
}

692
/* A GL context is provided by the caller */
693 694 695
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)
696 697 698 699
{
    GLuint prog;
    BOOL ret = FALSE;
    GLint pos;
700
    static const char testcode[] =
701 702 703 704 705 706
        "!!ARBvp1.0\n"
        "OPTION NV_vertex_program2;\n"
        "MOV result.clip[0], 0.0;\n"
        "MOV result.position, 0.0;\n"
        "END\n";

707
    if (!gl_info->supported[NV_VERTEX_PROGRAM2_OPTION]) return FALSE;
708

709
    while (gl_info->gl_ops.gl.p_glGetError());
710 711 712 713

    GL_EXTCALL(glGenProgramsARB(1, &prog));
    if(!prog)
    {
714
        ERR("Failed to create the NVvp clip test program\n");
715 716 717 718 719
        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));
720
    gl_info->gl_ops.gl.p_glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
721 722 723
    if(pos != -1)
    {
        WARN("GL_NV_vertex_program2_option result.clip[] test failed\n");
724
        TRACE("error: %s\n", debugstr_a((const char *)gl_info->gl_ops.gl.p_glGetString(GL_PROGRAM_ERROR_STRING_ARB)));
725
        ret = TRUE;
726
        while (gl_info->gl_ops.gl.p_glGetError());
727 728 729 730 731 732 733 734 735 736
    }
    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;
}

737
/* Context activation is done by the caller. */
738 739 740
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)
741 742 743 744 745 746 747 748 749
{
    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));

750 751 752 753 754
    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);
755 756 757 758 759 760 761 762 763 764 765 766
    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));
767
    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);
768 769
    checkGLcall("glTexSubImage2D");

770 771
    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);
772 773
    checkGLcall("glClear");

774
    gl_info->gl_ops.gl.p_glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, data);
775 776 777 778
    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);
779
    gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, 0);
780 781 782
    checkGLcall("glBindTexture");

    gl_info->fbo_ops.glDeleteFramebuffers(1, &fbo);
783
    gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
784 785 786 787 788
    checkGLcall("glDeleteTextures");

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

789
/* Context activation is done by the caller. */
790 791 792
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)
793 794 795 796 797 798
{
    /* 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;

799 800 801
    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);
802 803
    checkGLcall("glTexImage2D");

804
    gl_info->gl_ops.gl.p_glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &size);
805 806 807
    checkGLcall("glGetTexLevelParameteriv");
    TRACE("Real color depth is %d\n", size);

808
    gl_info->gl_ops.gl.p_glBindTexture(GL_TEXTURE_2D, 0);
809
    checkGLcall("glBindTexture");
810
    gl_info->gl_ops.gl.p_glDeleteTextures(1, &tex);
811 812 813 814 815
    checkGLcall("glDeleteTextures");

    return size < 16;
}

816 817 818
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)
819 820 821 822
{
    return gl_vendor == GL_VENDOR_FGLRX;
}

823 824 825
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)
826 827 828 829 830 831
{
    if (card_vendor != HW_VENDOR_AMD) return FALSE;
    if (device == CARD_AMD_RADEON_8500) return TRUE;
    return FALSE;
}

832 833 834
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)
835 836 837 838 839 840 841
{
    DWORD data[4];
    GLuint tex, fbo;
    GLenum status;
    float color[4] = {0.0f, 1.0f, 0.0f, 0.0f};
    GLuint prog;
    GLint err_pos;
842
    static const char program_code[] =
843 844 845 846 847 848 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
        "!!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;
}

928 929 930 931 932 933 934 935 936 937 938
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);
}

939
static void quirk_apple_glsl_constants(struct wined3d_gl_info *gl_info)
940 941 942 943
{
    /* 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. */
944
    TRACE("Reserving 12 GLSL constants for compiler private use.\n");
945 946 947
    gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12);
}

948
static void quirk_amd_dx9(struct wined3d_gl_info *gl_info)
949 950 951 952
{
    /* 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
953
     * extension and use GL_ARB_texture_rectangle instead, but texture_rectangle is inconvenient
954 955 956 957 958 959 960
     * 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. */
961 962 963 964
    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;
965
        gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] = TRUE;
966
    }
967 968
}

969
static void quirk_no_np2(struct wined3d_gl_info *gl_info)
970 971 972 973 974 975 976 977 978 979
{
    /*  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
980
     *  software-emulated extension and re-enable ARB_tex_rect (which was previously disabled
981
     *  in wined3d_adapter_init_gl_caps).
982 983 984 985 986 987 988 989
     *  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;
}

990
static void quirk_texcoord_w(struct wined3d_gl_info *gl_info)
991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008
{
    /* 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;
}

1009
static void quirk_clip_varying(struct wined3d_gl_info *gl_info)
1010 1011 1012 1013
{
    gl_info->quirks |= WINED3D_QUIRK_GLSL_CLIP_VARYING;
}

1014
static void quirk_allows_specular_alpha(struct wined3d_gl_info *gl_info)
1015 1016 1017 1018
{
    gl_info->quirks |= WINED3D_QUIRK_ALLOWS_SPECULAR_ALPHA;
}

1019 1020 1021 1022 1023
static void quirk_disable_nvvp_clip(struct wined3d_gl_info *gl_info)
{
    gl_info->quirks |= WINED3D_QUIRK_NV_CLIP_BROKEN;
}

1024 1025 1026 1027 1028
static void quirk_fbo_tex_update(struct wined3d_gl_info *gl_info)
{
    gl_info->quirks |= WINED3D_QUIRK_FBO_TEX_UPDATE;
}

1029 1030 1031 1032 1033
static void quirk_broken_rgba16(struct wined3d_gl_info *gl_info)
{
    gl_info->quirks |= WINED3D_QUIRK_BROKEN_RGBA16;
}

1034 1035 1036 1037 1038
static void quirk_infolog_spam(struct wined3d_gl_info *gl_info)
{
    gl_info->quirks |= WINED3D_QUIRK_INFO_LOG_SPAM;
}

1039
static void quirk_limited_tex_filtering(struct wined3d_gl_info *gl_info)
1040
{
1041 1042 1043 1044 1045 1046
    /* 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;
1047 1048
}

1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061
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);
}

1062 1063 1064 1065 1066
static void quirk_broken_arb_fog(struct wined3d_gl_info *gl_info)
{
    gl_info->quirks |= WINED3D_QUIRK_BROKEN_ARB_FOG;
}

1067 1068 1069 1070 1071 1072 1073 1074 1075
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;
    }
}

1076 1077
struct driver_quirk
{
1078 1079 1080
    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);
1081
    void (*apply)(struct wined3d_gl_info *gl_info);
1082 1083 1084
    const char *description;
};

1085
static const struct driver_quirk quirk_table[] =
1086 1087
{
    {
1088 1089
        match_amd_r300_to_500,
        quirk_amd_dx9,
1090
        "AMD normalized texrect quirk"
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115
    },
    {
        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"
1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130
    },
    {
        /* 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"
1131
    },
1132 1133 1134 1135 1136
    {
        match_broken_nv_clip,
        quirk_disable_nvvp_clip,
        "Apple NV_vertex_program clip bug quirk"
    },
1137 1138 1139 1140 1141
    {
        match_fbo_tex_update,
        quirk_fbo_tex_update,
        "FBO rebind for attachment updates"
    },
1142 1143 1144 1145 1146
    {
        match_broken_rgba16,
        quirk_broken_rgba16,
        "True RGBA16 is not available"
    },
1147 1148 1149 1150 1151
    {
        match_fglrx,
        quirk_infolog_spam,
        "Not printing GLSL infolog"
    },
1152
    {
1153 1154 1155
        match_not_dx10_capable,
        quirk_limited_tex_filtering,
        "Texture filtering, blending and VTF support is limited"
1156
    },
1157 1158 1159 1160 1161
    {
        match_r200,
        quirk_r200_constants,
        "r200 vertex shader constants"
    },
1162 1163 1164 1165 1166
    {
        match_broken_arb_fog,
        quirk_broken_arb_fog,
        "ARBfp fogstart == fogend workaround"
    },
1167 1168 1169 1170 1171
    {
        match_broken_viewport_subpixel_bits,
        quirk_broken_viewport_subpixel_bits,
        "Nvidia viewport subpixel bits bug"
    },
1172 1173 1174 1175 1176 1177
};

/* 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.
 *
1178 1179 1180 1181 1182 1183 1184 1185 1186
 * 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
 *
1187 1188
 * "y" is the maximum Direct3D version the driver supports.
 * y  -> d3d version mapping:
1189 1190 1191 1192 1193
 * 11 -> d3d6
 * 12 -> d3d7
 * 13 -> d3d8
 * 14 -> d3d9
 * 15 -> d3d10
1194 1195
 * 16 -> d3d10.1
 * 17 -> d3d11
1196
 *
1197
 * "z" is the subversion number.
1198
 *
1199
 * "w" is the vendor specific driver build number.
1200
 */
1201

1202
struct driver_version_information
1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214
{
    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[] =
{
1215
    /* AMD
1216
     * - Radeon HD2x00 (R600) and up supported by current drivers.
1217 1218 1219
     * - 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 */
1220 1221 1222
    {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},
1223
    {DRIVER_AMD_R600,           DRIVER_MODEL_NT5X,  "ati2dvag.dll", 17, 10, 1280},
1224
    {DRIVER_AMD_R300,           DRIVER_MODEL_NT6X,  "atiumdag.dll", 14, 10, 741 },
1225
    {DRIVER_AMD_R600,           DRIVER_MODEL_NT6X,  "atiumdag.dll", 17, 10, 1280},
1226
    {DRIVER_AMD_RX,             DRIVER_MODEL_NT6X,  "aticfx32.dll", 17, 10, 1474},
1227

1228 1229 1230 1231 1232 1233 1234 1235 1236 1237
    /* 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},
1238
    {DRIVER_INTEL_HD4000,       DRIVER_MODEL_NT6X,  "igdumdim32.dll", 19, 15, 4352},
1239

1240
    /* Nvidia
1241 1242
     * - 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
1243 1244 1245 1246 1247 1248 1249
     * - 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},
1250 1251 1252 1253
    {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},
1254 1255 1256

    /* VMware */
    {DRIVER_VMWARE,             DRIVER_MODEL_NT5X,  "vm3dum.dll",   14, 1,  1134},
1257 1258 1259
};

struct gpu_description
1260
{
1261
    WORD vendor;                    /* reported PCI card vendor ID  */
1262 1263
    WORD card;                      /* reported PCI card device ID  */
    const char *description;        /* Description of the card e.g. NVIDIA RIVA TNT */
1264
    enum wined3d_display_driver driver;
1265
    unsigned int vidmem;
1266 1267
};

1268 1269
/* 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. */
1270
static const struct gpu_description gpu_description_table[] =
1271
{
1272
    /* Nvidia cards */
1273
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_RIVA_128,           "NVIDIA RIVA 128",                  DRIVER_NVIDIA_TNT,       4   },
1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291
    {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 },
1292
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8200,       "NVIDIA GeForce 8200",              DRIVER_NVIDIA_GEFORCE8,  512 },
1293 1294
    {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 },
1295
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_8500GT,     "NVIDIA GeForce 8500 GT",           DRIVER_NVIDIA_GEFORCE8,  256 },
1296 1297 1298 1299 1300 1301 1302 1303 1304
    {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 },
1305
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9600GT,     "NVIDIA GeForce 9600 GT",           DRIVER_NVIDIA_GEFORCE8,  512 },
1306
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_9700MGT,    "NVIDIA GeForce 9700M GT",          DRIVER_NVIDIA_GEFORCE8,  512 },
1307 1308 1309 1310
    {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 },
1311
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTS250,     "NVIDIA GeForce GTS 250",           DRIVER_NVIDIA_GEFORCE8,  1024},
1312 1313 1314 1315 1316 1317 1318 1319 1320
    {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},
1321
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_410M,       "NVIDIA GeForce 410M",              DRIVER_NVIDIA_GEFORCE8,  512},
1322
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT420,      "NVIDIA GeForce GT 420",            DRIVER_NVIDIA_GEFORCE8,  2048},
1323
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT425M,     "NVIDIA GeForce GT 425M",           DRIVER_NVIDIA_GEFORCE8,  1024},
1324 1325 1326 1327 1328 1329 1330 1331 1332
    {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},
1333
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT525M,     "NVIDIA GeForce GT 525M",           DRIVER_NVIDIA_GEFORCE8,  1024},
1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352
    {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},
    {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},
1353
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX675MX,   "NVIDIA GeForce GTX 675MX",         DRIVER_NVIDIA_GEFORCE8,  4096},
1354
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX680,     "NVIDIA GeForce GTX 680",           DRIVER_NVIDIA_GEFORCE8,  2048},
1355
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX690,     "NVIDIA GeForce GTX 690",           DRIVER_NVIDIA_GEFORCE8,  2048},
1356
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT730,      "NVIDIA GeForce GT 730",            DRIVER_NVIDIA_GEFORCE8,  2048},
1357
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT730M,     "NVIDIA GeForce GT 730M",           DRIVER_NVIDIA_GEFORCE8,  1024},
1358
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT740M,     "NVIDIA GeForce GT 740M",           DRIVER_NVIDIA_GEFORCE8,  2048},
1359
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GT750M,     "NVIDIA GeForce GT 750M",           DRIVER_NVIDIA_GEFORCE8,  1024},
1360 1361
    {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},
1362 1363
    {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},
1364 1365 1366 1367 1368
    {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},
1369 1370 1371 1372
    {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},
1373
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_820M,       "NVIDIA GeForce 820M",              DRIVER_NVIDIA_GEFORCE8,  2048},
1374
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_830M,       "NVIDIA GeForce 830M",              DRIVER_NVIDIA_GEFORCE8,  2048},
1375
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_840M,       "NVIDIA GeForce 840M",              DRIVER_NVIDIA_GEFORCE8,  2048},
1376
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_845M,       "NVIDIA GeForce 845M",              DRIVER_NVIDIA_GEFORCE8,  2048},
1377
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX850M,    "NVIDIA GeForce GTX 850M",          DRIVER_NVIDIA_GEFORCE8,  2048},
1378
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX860M,    "NVIDIA GeForce GTX 860M",          DRIVER_NVIDIA_GEFORCE8,  2048},
1379
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX870M,    "NVIDIA GeForce GTX 870M",          DRIVER_NVIDIA_GEFORCE8,  3072},
1380
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX880M,    "NVIDIA GeForce GTX 880M",          DRIVER_NVIDIA_GEFORCE8,  4096},
1381
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_940M,       "NVIDIA GeForce 940M",              DRIVER_NVIDIA_GEFORCE8,  4096},
1382 1383 1384 1385
    {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},
1386
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX970,     "NVIDIA GeForce GTX 970",           DRIVER_NVIDIA_GEFORCE8,  4096},
1387
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX970M,    "NVIDIA GeForce GTX 970M",          DRIVER_NVIDIA_GEFORCE8,  3072},
1388
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX980,     "NVIDIA GeForce GTX 980",           DRIVER_NVIDIA_GEFORCE8,  4096},
1389
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX980TI,   "NVIDIA GeForce GTX 980 Ti",        DRIVER_NVIDIA_GEFORCE8,  6144},
1390
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX1050,    "NVIDIA GeForce GTX 1050",          DRIVER_NVIDIA_GEFORCE8,  2048},
1391 1392 1393
    {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},
1394
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_GEFORCE_GTX1080TI,  "NVIDIA GeForce GTX 1080 Ti",       DRIVER_NVIDIA_GEFORCE8,  11264},
1395
    {HW_VENDOR_NVIDIA,     CARD_NVIDIA_TITANX_PASCAL,      "NVIDIA TITAN X (Pascal)",          DRIVER_NVIDIA_GEFORCE8,  12288},
1396

1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408
    /* 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 },
1409
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD3850,         "ATI Radeon HD 3850 AGP",           DRIVER_AMD_R600,         512 },
1410
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD4200M,        "ATI Mobility Radeon HD 4200",      DRIVER_AMD_R600,         256 },
1411 1412 1413 1414 1415 1416 1417 1418 1419
    {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},
1420 1421
    {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},
1422
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6410D,        "AMD Radeon HD 6410D",              DRIVER_AMD_R600,         1024},
1423
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6480G,        "AMD Radeon HD 6480G",              DRIVER_AMD_R600,         512 },
1424
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6550D,        "AMD Radeon HD 6550D",              DRIVER_AMD_R600,         1024},
1425
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6600,         "AMD Radeon HD 6600 Series",        DRIVER_AMD_R600,         1024},
1426
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6600M,        "AMD Radeon HD 6600M Series",       DRIVER_AMD_R600,         512 },
1427
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD6700,         "AMD Radeon HD 6700 Series",        DRIVER_AMD_R600,         1024},
1428 1429
    {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},
1430
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD7660D,        "AMD Radeon HD 7660D",              DRIVER_AMD_R600,         2048},
1431 1432
    {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},
1433
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_HD7900,         "AMD Radeon HD 7900 Series",        DRIVER_AMD_R600,         2048},
1434 1435 1436 1437 1438
    {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},
1439 1440
    {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},
1441
    {HW_VENDOR_AMD,        CARD_AMD_RADEON_R9_FURY,        "AMD Radeon (TM) R9 Fury Series",   DRIVER_AMD_RX,           4096},
1442 1443
    {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},
1444 1445 1446 1447

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

1448
    /* Intel cards */
1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474
    {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},
1475 1476 1477 1478 1479 1480 1481 1482
    {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},
1483
    {HW_VENDOR_INTEL,      CARD_INTEL_HWD,                 "Intel(R) HD Graphics 4600",                                 DRIVER_INTEL_HD4000,  1536},
1484
    {HW_VENDOR_INTEL,      CARD_INTEL_HWM,                 "Intel(R) HD Graphics 4600",                                 DRIVER_INTEL_HD4000,  1536},
1485 1486 1487 1488 1489 1490 1491 1492 1493
    {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},
1494 1495 1496 1497 1498
    {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},
1499
    {HW_VENDOR_INTEL,      CARD_INTEL_IP6200,              "Intel(R) Iris(TM) Pro Graphics 6200",                       DRIVER_INTEL_HD4000,  2048},
1500
    {HW_VENDOR_INTEL,      CARD_INTEL_IPP6300,             "Intel(R) Iris(TM) Pro Graphics P6300",                      DRIVER_INTEL_HD4000,  2048},
1501 1502 1503 1504 1505 1506
    {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},
1507 1508
    {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},
1509 1510 1511 1512 1513 1514 1515 1516 1517
    {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},
1518 1519
};

1520 1521 1522 1523 1524 1525 1526 1527 1528 1529
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);
    for (i = 0; i < (sizeof(driver_version_table) / sizeof(driver_version_table[0])); i++)
    {
        const struct driver_version_information *entry = &driver_version_table[i];

1530 1531
        if (entry->driver == driver && (driver_model == DRIVER_MODEL_GENERIC
                || entry->driver_model == driver_model))
1532
        {
1533 1534
            TRACE("Found driver \"%s\", version %u, subversion %u, build %u.\n",
                    entry->driver_name, entry->version, entry->subversion, entry->build);
1535 1536 1537 1538 1539 1540
            return entry;
        }
    }
    return NULL;
}

1541 1542 1543 1544 1545 1546 1547 1548 1549 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;

    for (i = 0; i < (sizeof(gpu_description_table) / sizeof(*gpu_description_table)); ++i)
    {
        if (vendor == gpu_description_table[i].vendor && device == gpu_description_table[i].card)
            return &gpu_description_table[i];
    }

    return NULL;
}

1555
static const struct gpu_description *query_gpu_description(const struct wined3d_gl_info *gl_info, UINT64 *vram_bytes)
1556
{
1557 1558 1559 1560
    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;
1561

1562
    if (gl_info->supported[WGL_WINE_QUERY_RENDERER])
1563
    {
1564
        GLuint value;
1565

1566 1567 1568 1569 1570 1571 1572 1573 1574
        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));
    }
1575

1576 1577 1578 1579 1580
    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);
    }
1581

1582 1583 1584
    if (wined3d_settings.pci_device_id != PCI_DEVICE_NONE)
    {
        device = wined3d_settings.pci_device_id;
1585
        TRACE("Overriding device PCI ID with 0x%04x.\n", device);
1586
    }
1587

1588 1589 1590 1591 1592
    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));
1593 1594
    }

1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610
    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;
1611

1612 1613 1614 1615 1616 1617
    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;
1618
        driver_model = DRIVER_MODEL_NT5X;
1619 1620 1621 1622 1623 1624 1625
    }
    else
    {
        TRACE("OS version %u.%u.\n", os_version.dwMajorVersion, os_version.dwMinorVersion);
        switch (os_version.dwMajorVersion)
        {
            case 4:
1626 1627 1628
                /* 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.
                 */
1629
                driver_os_version = 4;
1630
                driver_model = DRIVER_MODEL_WIN9X;
1631 1632 1633 1634
                break;

            case 5:
                driver_os_version = 6;
1635
                driver_model = DRIVER_MODEL_NT5X;
1636 1637 1638 1639 1640 1641
                break;

            case 6:
                if (os_version.dwMinorVersion == 0)
                {
                    driver_os_version = 7;
1642
                    driver_model = DRIVER_MODEL_NT6X;
1643
                }
1644 1645 1646 1647 1648
                else if (os_version.dwMinorVersion == 1)
                {
                    driver_os_version = 8;
                    driver_model = DRIVER_MODEL_NT6X;
                }
1649 1650
                else
                {
1651
                    if (os_version.dwMinorVersion > 2)
1652
                    {
1653
                        FIXME("Unhandled OS version %u.%u, reporting Win 8.\n",
1654 1655
                                os_version.dwMajorVersion, os_version.dwMinorVersion);
                    }
1656
                    driver_os_version = 9;
1657
                    driver_model = DRIVER_MODEL_NT6X;
1658 1659 1660
                }
                break;

1661 1662 1663 1664 1665
            case 10:
                driver_os_version = 10;
                driver_model = DRIVER_MODEL_NT6X;
                break;

1666 1667 1668 1669
            default:
                FIXME("Unhandled OS version %u.%u, reporting 2000/XP.\n",
                        os_version.dwMajorVersion, os_version.dwMinorVersion);
                driver_os_version = 6;
1670
                driver_model = DRIVER_MODEL_NT5X;
1671 1672 1673 1674
                break;
        }
    }

1675 1676 1677 1678 1679
    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;
1680

1681 1682 1683 1684 1685
    /**
     * 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.
     */
1686
    if (driver_model < DRIVER_MODEL_NT6X && driver_info->vram_bytes > LONG_MAX)
1687 1688 1689 1690 1691
    {
        TRACE("Limiting amount of video memory to %#lx bytes for OS version older than Vista.\n", LONG_MAX);
        driver_info->vram_bytes = LONG_MAX;
    }

1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704
    /* 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.
     */
1705
    if ((version_info = get_driver_version_info(driver, driver_model))
1706
            || (version_info = get_driver_version_info(driver, DRIVER_MODEL_GENERIC)))
1707 1708 1709 1710 1711 1712 1713
    {
        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
    {
1714
        ERR("No driver version info found for device %04x:%04x, driver model %#x.\n",
1715
                driver_info->vendor, driver_info->device, driver_model);
1716 1717 1718
        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 */
1719 1720
    }

1721
    TRACE("Reporting (fake) driver version 0x%08x-0x%08x.\n",
1722 1723 1724
            driver_info->version_high, driver_info->version_low);
}

1725
/* Context activation is done by the caller. */
1726 1727 1728
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)
1729 1730 1731 1732 1733
{
    unsigned int i;

    for (i = 0; i < (sizeof(quirk_table) / sizeof(*quirk_table)); ++i)
    {
1734
        if (!quirk_table[i].match(gl_info, ctx, gl_renderer, gl_vendor, card_vendor, device)) continue;
1735
        TRACE("Applying driver quirk \"%s\".\n", quirk_table[i].description);
1736 1737 1738 1739 1740 1741 1742
        quirk_table[i].apply(gl_info);
    }

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

1743 1744 1745 1746 1747 1748
static DWORD wined3d_parse_gl_version(const char *gl_version)
{
    const char *ptr = gl_version;
    int major, minor;

    major = atoi(ptr);
1749 1750
    if (major <= 0)
        ERR("Invalid OpenGL major version %d.\n", major);
1751 1752

    while (isdigit(*ptr)) ++ptr;
1753 1754
    if (*ptr++ != '.')
        ERR("Invalid OpenGL version string %s.\n", debugstr_a(gl_version));
1755 1756 1757

    minor = atoi(ptr);

1758
    TRACE("Found OpenGL version %d.%d.\n", major, minor);
1759 1760 1761 1762

    return MAKEDWORD_VERSION(major, minor);
}

1763
static enum wined3d_gl_vendor wined3d_guess_gl_vendor(const struct wined3d_gl_info *gl_info,
1764
        const char *gl_vendor_string, const char *gl_renderer, const char *gl_version)
1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776
{
    /* 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. */
1777
    if (gl_info->supported[APPLE_FENCE] && gl_info->supported[APPLE_YCBCR_422])
1778 1779 1780 1781 1782 1783
        return GL_VENDOR_APPLE;

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

    if (strstr(gl_vendor_string, "ATI"))
1784
        return GL_VENDOR_FGLRX;
1785 1786

    if (strstr(gl_vendor_string, "Mesa")
1787
            || strstr(gl_vendor_string, "X.Org")
1788
            || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
1789 1790 1791
            || strstr(gl_vendor_string, "DRI R300 Project")
            || strstr(gl_vendor_string, "Tungsten Graphics, Inc")
            || strstr(gl_vendor_string, "VMware, Inc.")
1792
            || strstr(gl_vendor_string, "Intel")
1793
            || strstr(gl_renderer, "Mesa")
1794
            || strstr(gl_renderer, "Gallium")
1795 1796
            || strstr(gl_renderer, "Intel")
            || strstr(gl_version, "Mesa"))
1797 1798
        return GL_VENDOR_MESA;

1799
    FIXME("Received unrecognized GL_VENDOR %s. Returning GL_VENDOR_UNKNOWN.\n",
1800
            debugstr_a(gl_vendor_string));
1801

1802
    return GL_VENDOR_UNKNOWN;
1803 1804
}

1805
static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_string, const char *gl_renderer)
1806
{
1807
    if (strstr(gl_vendor_string, "NVIDIA")
1808
            || strstr(gl_vendor_string, "Nouveau")
1809
            || strstr(gl_vendor_string, "nouveau"))
1810
        return HW_VENDOR_NVIDIA;
1811

1812
    if (strstr(gl_vendor_string, "ATI")
1813
            || strstr(gl_vendor_string, "Advanced Micro Devices, Inc.")
1814
            || strstr(gl_vendor_string, "X.Org R300 Project")
1815
            || strstr(gl_renderer, "AMD")
1816 1817 1818 1819 1820
            || strstr(gl_renderer, "R100")
            || strstr(gl_renderer, "R200")
            || strstr(gl_renderer, "R300")
            || strstr(gl_renderer, "R600")
            || strstr(gl_renderer, "R700"))
1821
        return HW_VENDOR_AMD;
1822

1823
    if (strstr(gl_vendor_string, "Intel(R)")
1824 1825
            /* Intel switched from Intel(R) to Intel® recently, so just match Intel. */
            || strstr(gl_renderer, "Intel")
1826
            || strstr(gl_renderer, "i915")
1827 1828
            || strstr(gl_vendor_string, "Intel Inc."))
        return HW_VENDOR_INTEL;
1829

1830 1831 1832
    if (strstr(gl_renderer, "SVGA3D"))
        return HW_VENDOR_VMWARE;

1833
    if (strstr(gl_vendor_string, "Mesa")
1834
            || strstr(gl_vendor_string, "Brian Paul")
1835 1836
            || strstr(gl_vendor_string, "Tungsten Graphics, Inc")
            || strstr(gl_vendor_string, "VMware, Inc."))
1837
        return HW_VENDOR_SOFTWARE;
1838

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

1841
    return HW_VENDOR_NVIDIA;
1842 1843
}

1844
static enum wined3d_d3d_level d3d_level_from_caps(const struct shader_caps *shader_caps, const struct fragment_caps *fragment_caps, DWORD glsl_version)
1845
{
1846
    if (shader_caps->vs_version >= 5)
1847
        return WINED3D_D3D_LEVEL_11;
1848
    if (shader_caps->vs_version == 4)
1849
        return WINED3D_D3D_LEVEL_10;
1850
    if (shader_caps->vs_version == 3)
1851
    {
1852 1853 1854 1855
        /* 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;
1856
        if (glsl_version >= MAKEDWORD_VERSION(1, 30))
1857 1858 1859
            return WINED3D_D3D_LEVEL_10;
        return WINED3D_D3D_LEVEL_9_SM3;
    }
1860
    if (shader_caps->vs_version == 2)
1861
        return WINED3D_D3D_LEVEL_9_SM2;
1862
    if (shader_caps->vs_version == 1)
1863 1864
        return WINED3D_D3D_LEVEL_8;

1865
    if (fragment_caps->TextureOpCaps & WINED3DTEXOPCAPS_DOTPRODUCT3)
1866
        return WINED3D_D3D_LEVEL_7;
1867
    if (fragment_caps->MaxSimultaneousTextures > 1)
1868 1869 1870
        return WINED3D_D3D_LEVEL_6;

    return WINED3D_D3D_LEVEL_5;
1871
}
1872

1873
static const struct wined3d_renderer_table
1874
{
1875 1876
    const char *renderer;
    enum wined3d_pci_device id;
1877
}
1878 1879 1880
cards_nvidia_binary[] =
{
    /* Direct 3D 11 */
1881
    {"TITAN X (Pascal)",            CARD_NVIDIA_TITANX_PASCAL},     /* GeForce 1000 - highend */
1882
    {"GTX 1080 Ti",                 CARD_NVIDIA_GEFORCE_GTX1080TI}, /* GeForce 1000 - highend */
1883 1884 1885
    {"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 */
1886
    {"GTX 1050",                    CARD_NVIDIA_GEFORCE_GTX1050},   /* GeForce 1000 - midend */
1887
    {"GTX 980 Ti",                  CARD_NVIDIA_GEFORCE_GTX980TI},  /* GeForce 900 - highend */
1888
    {"GTX 980",                     CARD_NVIDIA_GEFORCE_GTX980},    /* GeForce 900 - highend */
1889
    {"GTX 970M",                    CARD_NVIDIA_GEFORCE_GTX970M},   /* GeForce 900 - highend mobile*/
1890
    {"GTX 970",                     CARD_NVIDIA_GEFORCE_GTX970},    /* GeForce 900 - highend */
1891
    {"GTX TITAN X",                 CARD_NVIDIA_GEFORCE_GTXTITANX}, /* Geforce 900 - highend */
1892 1893 1894 1895
    {"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 */
1896
    {"GeForce 940M",                CARD_NVIDIA_GEFORCE_940M},      /* GeForce 900 - midend mobile */
1897
    {"GTX 880M",                    CARD_NVIDIA_GEFORCE_GTX880M},   /* GeForce 800 - mobile */
1898
    {"GTX 870M",                    CARD_NVIDIA_GEFORCE_GTX870M},   /* GeForce 800 - mobile */
1899
    {"GTX 860M",                    CARD_NVIDIA_GEFORCE_GTX860M},   /* GeForce 800 - mobile */
1900
    {"GTX 850M",                    CARD_NVIDIA_GEFORCE_GTX850M},   /* GeForce 800 - mobile */
1901
    {"GeForce 845M",                CARD_NVIDIA_GEFORCE_845M},      /* GeForce 800 - mobile */
1902
    {"GeForce 840M",                CARD_NVIDIA_GEFORCE_840M},      /* GeForce 800 - mobile */
1903
    {"GeForce 830M",                CARD_NVIDIA_GEFORCE_830M},      /* GeForce 800 - mobile */
1904
    {"GeForce 820M",                CARD_NVIDIA_GEFORCE_820M},      /* GeForce 800 - mobile */
1905
    {"GTX 780 Ti",                  CARD_NVIDIA_GEFORCE_GTX780TI},  /* Geforce 700 - highend */
1906 1907 1908
    {"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 */
1909 1910 1911 1912
    {"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 */
1913
    {"GTX 760 Ti",                  CARD_NVIDIA_GEFORCE_GTX760TI},  /* Geforce 700 - midend high */
1914 1915 1916
    {"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 */
1917
    {"GT 750M",                     CARD_NVIDIA_GEFORCE_GT750M},    /* Geforce 700 - midend mobile */
1918
    {"GT 740M",                     CARD_NVIDIA_GEFORCE_GT740M},    /* Geforce 700 - midend mobile */
1919
    {"GT 730M",                     CARD_NVIDIA_GEFORCE_GT730M},    /* Geforce 700 - midend mobile */
1920
    {"GT 730",                      CARD_NVIDIA_GEFORCE_GT730},     /* Geforce 700 - lowend */
1921
    {"GTX 690",                     CARD_NVIDIA_GEFORCE_GTX690},    /* Geforce 600 - highend */
1922
    {"GTX 680",                     CARD_NVIDIA_GEFORCE_GTX680},    /* Geforce 600 - highend */
1923
    {"GTX 675MX",                   CARD_NVIDIA_GEFORCE_GTX675MX},  /* Geforce 600 - highend */
1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942
    {"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 */
    {"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 */
1943
    {"GT 525M",                     CARD_NVIDIA_GEFORCE_GT525M},    /* Geforce 500 - lowend mobile */
1944 1945 1946 1947 1948 1949 1950 1951 1952 1953
    {"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 */
1954
    {"GT 425M",                     CARD_NVIDIA_GEFORCE_GT425M},    /* Geforce 400 - lowend mobile */
1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969
    {"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 */
1970
    {"GTS 250",                     CARD_NVIDIA_GEFORCE_GTS250},    /* Geforce 200 - midend */
1971 1972 1973 1974 1975 1976 1977 1978
    {"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 */
1979
    {"9700M GT",                    CARD_NVIDIA_GEFORCE_9700MGT},   /* Geforce 9 - midend */
1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996
    {"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 */
1997
    {"8500",                        CARD_NVIDIA_GEFORCE_8500GT},    /* Geforce 8 - mid-lowend */
1998 1999
    {"8400",                        CARD_NVIDIA_GEFORCE_8400GS},    /* Geforce 8 - mid-lowend */
    {"8300",                        CARD_NVIDIA_GEFORCE_8300GS},    /* Geforce 8 - lowend */
2000 2001
    {"8200",                        CARD_NVIDIA_GEFORCE_8200},      /* Geforce 8 - lowend */
    {"8100",                        CARD_NVIDIA_GEFORCE_8200},      /* Geforce 8 - lowend */
2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 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
    /* 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[] =
{
2048
    {"RX 480",                      CARD_AMD_RADEON_RX_480},
2049
    {"RX 460",                      CARD_AMD_RADEON_RX_460},
2050
    {"R9 Fury Series",              CARD_AMD_RADEON_R9_FURY},
2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068
    /* 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},
2069
    {"HD 6480G",                    CARD_AMD_RADEON_HD6480G},
2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 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
    {"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[] =
{
2140
    /* Skylake */
2141 2142
    {"Iris Pro Graphics P580",      CARD_INTEL_IPP580_1},
    {"Skylake",                     CARD_INTEL_HD520_1},
2143
    /* Broadwell */
2144
    {"Iris Pro P6300",              CARD_INTEL_IPP6300},
2145
    {"Iris Pro 6200",               CARD_INTEL_IP6200},
2146 2147
    {"Iris 6100",                   CARD_INTEL_I6100},
    {"Iris(TM) Graphics 6100",      CARD_INTEL_I6100},  /* MacOS */
2148
    /* Haswell */
2149 2150
    {"Iris Pro 5200",               CARD_INTEL_IP5200_1},
    {"Iris 5100",                   CARD_INTEL_I5100_1},
2151
    {"Haswell Mobile",              CARD_INTEL_HWM},
2152
    {"Iris OpenGL Engine",          CARD_INTEL_HWM},    /* MacOS */
2153 2154 2155 2156
    /* Ivybridge */
    {"Ivybridge Server",            CARD_INTEL_IVBS},
    {"Ivybridge Mobile",            CARD_INTEL_IVBM},
    {"Ivybridge Desktop",           CARD_INTEL_IVBD},
2157
    {"HD Graphics 4000",            CARD_INTEL_IVBD},   /* MacOS */
2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 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
    /* 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
 * drivers: R700, RV790, R680, RV535, RV516, R410, RS485, RV360, RV351.
 *
 * These are returned but not handled: RC410, RV380. */
cards_amd_mesa[] =
{
2206 2207 2208
    /* Polaris 10/11 */
    {"POLARIS10",                   CARD_AMD_RADEON_RX_480},
    {"POLARIS11",                   CARD_AMD_RADEON_RX_460},
2209
    /* Volcanic Islands */
2210
    {"FIJI",                        CARD_AMD_RADEON_R9_FURY},
2211
    {"TONGA",                       CARD_AMD_RADEON_R9_285},
2212
    /* Sea Islands */
2213
    {"HAWAII",                      CARD_AMD_RADEON_R9_290},
2214 2215 2216
    {"KAVERI",                      CARD_AMD_RADEON_R7    },
    {"KABINI",                      CARD_AMD_RADEON_R3    },
    {"BONAIRE",                     CARD_AMD_RADEON_HD8770},
2217
    /* Southern Islands */
2218 2219
    {"OLAND",                       CARD_AMD_RADEON_HD8670},
    {"HAINAN",                      CARD_AMD_RADEON_HD8600M},
2220 2221 2222 2223
    {"TAHITI",                      CARD_AMD_RADEON_HD7900},
    {"PITCAIRN",                    CARD_AMD_RADEON_HD7800},
    {"CAPE VERDE",                  CARD_AMD_RADEON_HD7700},
    /* Northern Islands */
2224
    {"ARUBA",                       CARD_AMD_RADEON_HD7660D},
2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250
    {"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},
2251
    {"RV670",                       CARD_AMD_RADEON_HD3850},
2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 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},
    /* R300 */
    {"R360",                        CARD_AMD_RADEON_9500},
    {"R350",                        CARD_AMD_RADEON_9500},
    {"R300",                        CARD_AMD_RADEON_9500},
    {"RV370",                       CARD_AMD_RADEON_9500},
    {"RV360",                       CARD_AMD_RADEON_9500},
    {"RV351",                       CARD_AMD_RADEON_9500},
    {"RV350",                       CARD_AMD_RADEON_9500},
},
cards_nvidia_mesa[] =
{
    /* Maxwell */
2293
    {"NV124",                       CARD_NVIDIA_GEFORCE_GTX970},
2294
    {"NV120",                       CARD_NVIDIA_GEFORCE_GTX980TI},
2295
    {"NV118",                       CARD_NVIDIA_GEFORCE_840M},
2296 2297
    {"NV117",                       CARD_NVIDIA_GEFORCE_GTX750},
    /* Kepler */
2298
    {"NV108",                       CARD_NVIDIA_GEFORCE_GT740M},
2299 2300 2301
    {"NVF1",                        CARD_NVIDIA_GEFORCE_GTX780TI},
    {"NVF0",                        CARD_NVIDIA_GEFORCE_GTX780},
    {"NVE6",                        CARD_NVIDIA_GEFORCE_GTX770M},
2302
    {"NVE4",                        CARD_NVIDIA_GEFORCE_GTX680},    /* 690 / 675MX / 760TI */
2303 2304
    /* Fermi */
    {"NVD9",                        CARD_NVIDIA_GEFORCE_GT520},
2305
    {"NVD7",                        CARD_NVIDIA_GEFORCE_820M},
2306 2307 2308 2309 2310 2311 2312 2313 2314 2315
    {"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},
2316
    {"NVAA",                        CARD_NVIDIA_GEFORCE_8200},      /* 8100 */
2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 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
    {"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[] =
2371
{
2372 2373
    {"SVGA3D",                      CARD_VMWARE_SVGA3D},
};
2374

2375 2376 2377 2378
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 */
2379 2380
    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 */
2381
}
2382 2383
amd_gl_vendor_table[] =
{
2384 2385 2386
    {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)},
2387
},
2388 2389
nvidia_gl_vendor_table[] =
{
2390 2391 2392
    {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)},
2393
},
2394
vmware_gl_vendor_table[] =
2395
{
2396
    {GL_VENDOR_MESA,    "VMware driver",                    cards_vmware,           ARRAY_SIZE(cards_vmware)},
2397 2398 2399
},
intel_gl_vendor_table[] =
{
2400 2401
    {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)},
2402
};
2403

2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428
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[] =
{
2429 2430 2431
    CARD_INTEL_845G,                /* D3D5 */
    CARD_INTEL_845G,                /* D3D6 */
    CARD_INTEL_845G,                /* D3D7 */
2432 2433
    CARD_INTEL_915G,                /* D3D8 */
    CARD_INTEL_915G,                /* D3D9_SM2 */
2434
    CARD_INTEL_945G,                /* D3D9_SM3 */
2435 2436 2437 2438 2439 2440
    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);
2441 2442

static enum wined3d_pci_device select_card_handler(const struct gl_vendor_selection *table,
2443
        unsigned int table_size, enum wined3d_gl_vendor gl_vendor, const char *gl_renderer)
2444
{
2445
    unsigned int i, j;
2446 2447 2448 2449 2450 2451 2452

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

        TRACE("Applying card selector \"%s\".\n", table[i].description);
2453 2454 2455 2456 2457 2458 2459

        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;
2460
    }
2461
    FIXME("Couldn't find a suitable card selector for GL vendor %04x (using GL_RENDERER %s)\n",
2462 2463 2464 2465 2466 2467
            gl_vendor, debugstr_a(gl_renderer));

    return PCI_DEVICE_NONE;
}

static const struct
2468 2469 2470
{
    enum wined3d_pci_vendor card_vendor;
    const char *description;        /* Description of the card selector i.e. Apple OS/X Intel */
2471 2472
    const struct gl_vendor_selection *gl_vendor_selection;
    unsigned int gl_vendor_count;
2473
    const enum wined3d_pci_device *card_fallback; /* An array with D3D_LEVEL_COUNT elements */
2474 2475 2476
}
card_vendor_table[] =
{
2477 2478
    {HW_VENDOR_AMD,         "AMD",      amd_gl_vendor_table,
            sizeof(amd_gl_vendor_table) / sizeof(*amd_gl_vendor_table),
2479
            card_fallback_amd},
2480 2481
    {HW_VENDOR_NVIDIA,      "Nvidia",   nvidia_gl_vendor_table,
            sizeof(nvidia_gl_vendor_table) / sizeof(*nvidia_gl_vendor_table),
2482
            card_fallback_nvidia},
2483 2484
    {HW_VENDOR_VMWARE,      "VMware",   vmware_gl_vendor_table,
            sizeof(vmware_gl_vendor_table) / sizeof(*vmware_gl_vendor_table),
2485
            card_fallback_amd},
2486 2487
    {HW_VENDOR_INTEL,       "Intel",    intel_gl_vendor_table,
            sizeof(intel_gl_vendor_table) / sizeof(*intel_gl_vendor_table),
2488
            card_fallback_intel},
2489 2490 2491
};


2492 2493
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)
2494
{
2495
    /* A Direct3D device object contains the PCI id (vendor + device) of the
2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529
     * 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
2530
     * the renderer string to distinguish between different models from that
2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544
     * 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. */

2545
    unsigned int i;
2546
    enum wined3d_d3d_level d3d_level = d3d_level_from_caps(shader_caps, fragment_caps, glsl_version);
2547
    enum wined3d_pci_device device;
2548

2549
    for (i = 0; i < (sizeof(card_vendor_table) / sizeof(*card_vendor_table)); ++i)
2550
    {
2551
        if (card_vendor_table[i].card_vendor != *card_vendor)
2552
            continue;
2553 2554 2555

        TRACE("Applying card selector \"%s\".\n", card_vendor_table[i].description);
        device = select_card_handler(card_vendor_table[i].gl_vendor_selection,
2556
                card_vendor_table[i].gl_vendor_count, *gl_vendor, gl_renderer);
2557 2558 2559 2560
        if (device != PCI_DEVICE_NONE)
            return device;

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

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

2567
    /* Default to generic Nvidia hardware based on the supported OpenGL extensions. */
2568
    *card_vendor = HW_VENDOR_NVIDIA;
2569
    return card_fallback_nvidia[d3d_level];
2570 2571
}

2572 2573 2574
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)
{
2575
    if (shader_backend_ops == &glsl_shader_backend && gl_info->supported[ARB_VERTEX_SHADER])
2576 2577 2578 2579
        return &glsl_vertex_pipe;
    return &ffp_vertex_pipe;
}

2580 2581
static const struct fragment_pipeline *select_fragment_implementation(const struct wined3d_gl_info *gl_info,
        const struct wined3d_shader_backend_ops *shader_backend_ops)
2582
{
2583
    if (shader_backend_ops == &glsl_shader_backend && gl_info->supported[ARB_FRAGMENT_SHADER])
2584
        return &glsl_fragment_pipe;
2585
    if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
2586
        return &arbfp_fragment_pipeline;
2587
    if (gl_info->supported[ATI_FRAGMENT_SHADER])
2588 2589 2590 2591 2592 2593
        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;
2594 2595
}

2596
static const struct wined3d_shader_backend_ops *select_shader_backend(const struct wined3d_gl_info *gl_info)
2597
{
2598
    BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
2599

2600
    if (glsl && gl_info->supported[ARB_VERTEX_SHADER] && gl_info->supported[ARB_FRAGMENT_SHADER])
2601
        return &glsl_shader_backend;
2602 2603 2604
    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]))
2605 2606 2607
        return &glsl_shader_backend;
    if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
        return &arb_program_shader_backend;
2608 2609 2610
    return &none_shader_backend;
}

2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629
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;

2630
        TRACE("- %s.\n", debugstr_an(start, len));
2631 2632 2633 2634 2635 2636

        for (i = 0; i < entry_count; ++i)
        {
            if (len == strlen(map[i].extension_string)
                    && !memcmp(start, map[i].extension_string, len))
            {
2637
                TRACE(" FOUND: %s support.\n", map[i].extension_string);
2638 2639 2640 2641 2642 2643 2644
                gl_info->supported[map[i].extension] = TRUE;
                break;
            }
        }
    }
}

2645 2646 2647 2648 2649 2650 2651
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;

2652
    gl_info->gl_ops.gl.p_glGetIntegerv(GL_NUM_EXTENSIONS, &extensions_count);
2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668
    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;
            }
        }
    }
}

2669
static void load_gl_funcs(struct wined3d_gl_info *gl_info)
2670
{
2671
#define USE_GL_FUNC(pfn) gl_info->gl_ops.ext.p_##pfn = (void *)wglGetProcAddress(#pfn);
2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686
    /* 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)
    /* GL_ARB_blend_func_extended */
    USE_GL_FUNC(glBindFragDataLocationIndexed)
    USE_GL_FUNC(glGetFragDataIndex)
2687 2688 2689
    /* GL_ARB_clear_buffer_object */
    USE_GL_FUNC(glClearBufferData)
    USE_GL_FUNC(glClearBufferSubData)
2690 2691 2692
    /* GL_ARB_clear_texture */
    USE_GL_FUNC(glClearTexImage)
    USE_GL_FUNC(glClearTexSubImage)
2693 2694
    /* GL_ARB_clip_control */
    USE_GL_FUNC(glClipControl)
2695 2696
    /* GL_ARB_color_buffer_float */
    USE_GL_FUNC(glClampColorARB)
2697 2698 2699
    /* GL_ARB_compute_shader */
    USE_GL_FUNC(glDispatchCompute)
    USE_GL_FUNC(glDispatchComputeIndirect)
2700 2701
    /* GL_ARB_copy_buffer */
    USE_GL_FUNC(glCopyBufferSubData)
2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716
    /* 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)
    /* GL_ARB_draw_instanced */
    USE_GL_FUNC(glDrawArraysInstancedARB)
    USE_GL_FUNC(glDrawElementsInstancedARB)
2717 2718 2719 2720 2721 2722
    /* GL_ARB_ES2_compatibility */
    USE_GL_FUNC(glReleaseShaderCompiler)
    USE_GL_FUNC(glShaderBinary)
    USE_GL_FUNC(glGetShaderPrecisionFormat)
    USE_GL_FUNC(glDepthRangef)
    USE_GL_FUNC(glClearDepthf)
2723 2724 2725 2726 2727 2728 2729 2730
    /* 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)
2731
    USE_GL_FUNC(glFramebufferTexture)
2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 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
    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)
2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802
    /* 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)
2803 2804
    /* GL_ARB_shader_atomic_counters */
    USE_GL_FUNC(glGetActiveAtomicCounterBufferiv)
2805 2806 2807
    /* GL_ARB_shader_image_load_store */
    USE_GL_FUNC(glBindImageTexture)
    USE_GL_FUNC(glMemoryBarrier)
2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849
    /* 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)
2850 2851
    /* GL_ARB_shader_storage_buffer_object */
    USE_GL_FUNC(glShaderStorageBlockBinding)
2852 2853 2854 2855 2856 2857 2858 2859
    /* 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)
2860 2861 2862
    /* GL_ARB_tessellation_shader */
    USE_GL_FUNC(glPatchParameteri)
    USE_GL_FUNC(glPatchParameterfv)
2863 2864
    /* GL_ARB_texture_buffer_object */
    USE_GL_FUNC(glTexBufferARB)
2865 2866
    /* GL_ARB_texture_buffer_range */
    USE_GL_FUNC(glTexBufferRange)
2867 2868 2869 2870 2871 2872
    /* GL_ARB_texture_compression */
    USE_GL_FUNC(glCompressedTexImage2DARB)
    USE_GL_FUNC(glCompressedTexImage3DARB)
    USE_GL_FUNC(glCompressedTexSubImage2DARB)
    USE_GL_FUNC(glCompressedTexSubImage3DARB)
    USE_GL_FUNC(glGetCompressedTexImageARB)
2873 2874 2875 2876
    /* GL_ARB_texture_storage */
    USE_GL_FUNC(glTexStorage1D)
    USE_GL_FUNC(glTexStorage2D)
    USE_GL_FUNC(glTexStorage3D)
2877 2878
    /* GL_ARB_texture_view */
    USE_GL_FUNC(glTextureView)
2879 2880 2881
    /* GL_ARB_timer_query */
    USE_GL_FUNC(glQueryCounter)
    USE_GL_FUNC(glGetQueryObjectui64v)
2882 2883 2884 2885 2886 2887 2888 2889
    /* 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);
2890 2891 2892 2893 2894
    /* GL_ARB_transform_feedback3 */
    USE_GL_FUNC(glBeginQueryIndexed);
    USE_GL_FUNC(glDrawTransformFeedbackStream);
    USE_GL_FUNC(glEndQueryIndexed);
    USE_GL_FUNC(glGetQueryIndexediv);
2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 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
    /* 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)
2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986
    /* 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)
2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 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
    /* 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)
3177 3178 3179 3180
    USE_GL_FUNC(wglQueryCurrentRendererIntegerWINE)
    USE_GL_FUNC(wglQueryCurrentRendererStringWINE)
    USE_GL_FUNC(wglQueryRendererIntegerWINE)
    USE_GL_FUNC(wglQueryRendererStringWINE)
3181 3182
    USE_GL_FUNC(wglSetPixelFormatWINE)
    USE_GL_FUNC(wglSwapIntervalEXT)
3183 3184 3185

    /* Newer core functions */
    USE_GL_FUNC(glActiveTexture)            /* OpenGL 1.3 */
3186
    USE_GL_FUNC(glAttachShader)             /* OpenGL 2.0 */
3187
    USE_GL_FUNC(glBeginQuery)               /* OpenGL 1.5 */
3188
    USE_GL_FUNC(glBeginTransformFeedback)   /* OpenGL 3.0 */
3189
    USE_GL_FUNC(glBindAttribLocation)       /* OpenGL 2.0 */
3190
    USE_GL_FUNC(glBindBuffer)               /* OpenGL 1.5 */
3191
    USE_GL_FUNC(glBindFragDataLocation)     /* OpenGL 3.0 */
3192
    USE_GL_FUNC(glBindVertexArray)          /* OpenGL 3.0 */
3193 3194 3195 3196
    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 */
3197 3198
    USE_GL_FUNC(glBufferData)               /* OpenGL 1.5 */
    USE_GL_FUNC(glBufferSubData)            /* OpenGL 1.5 */
3199
    USE_GL_FUNC(glColorMaski)               /* OpenGL 3.0 */
3200
    USE_GL_FUNC(glCompileShader)            /* OpenGL 2.0 */
3201 3202 3203 3204
    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 */
3205 3206
    USE_GL_FUNC(glCreateProgram)            /* OpenGL 2.0 */
    USE_GL_FUNC(glCreateShader)             /* OpenGL 2.0 */
3207 3208 3209
    USE_GL_FUNC(glDebugMessageCallback)     /* OpenGL 4.3 */
    USE_GL_FUNC(glDebugMessageControl)      /* OpenGL 4.3 */
    USE_GL_FUNC(glDebugMessageInsert)       /* OpenGL 4.3 */
3210
    USE_GL_FUNC(glDeleteBuffers)            /* OpenGL 1.5 */
3211
    USE_GL_FUNC(glDeleteProgram)            /* OpenGL 2.0 */
3212
    USE_GL_FUNC(glDeleteQueries)            /* OpenGL 1.5 */
3213
    USE_GL_FUNC(glDeleteShader)             /* OpenGL 2.0 */
3214
    USE_GL_FUNC(glDeleteVertexArrays)       /* OpenGL 3.0 */
3215
    USE_GL_FUNC(glDetachShader)             /* OpenGL 2.0 */
3216
    USE_GL_FUNC(glDisablei)                 /* OpenGL 3.0 */
3217
    USE_GL_FUNC(glDisableVertexAttribArray) /* OpenGL 2.0 */
3218
    USE_GL_FUNC(glDrawArraysInstanced)      /* OpenGL 3.1 */
3219
    USE_GL_FUNC(glDrawBuffers)              /* OpenGL 2.0 */
3220
    USE_GL_FUNC(glDrawElementsInstanced)    /* OpenGL 3.1 */
3221
    USE_GL_FUNC(glEnablei)                  /* OpenGL 3.0 */
3222
    USE_GL_FUNC(glEnableVertexAttribArray)  /* OpenGL 2.0 */
3223
    USE_GL_FUNC(glEndQuery)                 /* OpenGL 1.5 */
3224
    USE_GL_FUNC(glEndTransformFeedback)     /* OpenGL 3.0 */
3225
    USE_GL_FUNC(glFramebufferTexture)       /* OpenGL 3.2 */
3226
    USE_GL_FUNC(glGenBuffers)               /* OpenGL 1.5 */
3227
    USE_GL_FUNC(glGenQueries)               /* OpenGL 1.5 */
3228
    USE_GL_FUNC(glGenVertexArrays)          /* OpenGL 3.0 */
3229 3230 3231
    USE_GL_FUNC(glGetActiveUniform)         /* OpenGL 2.0 */
    USE_GL_FUNC(glGetAttachedShaders)       /* OpenGL 2.0 */
    USE_GL_FUNC(glGetAttribLocation)        /* OpenGL 2.0 */
3232
    USE_GL_FUNC(glGetBooleani_v)            /* OpenGL 3.0 */
3233
    USE_GL_FUNC(glGetBufferSubData)         /* OpenGL 1.5 */
3234
    USE_GL_FUNC(glGetCompressedTexImage)    /* OpenGL 1.3 */
3235
    USE_GL_FUNC(glGetDebugMessageLog)       /* OpenGL 4.3 */
3236
    USE_GL_FUNC(glGetIntegeri_v)            /* OpenGL 3.0 */
3237 3238
    USE_GL_FUNC(glGetProgramInfoLog)        /* OpenGL 2.0 */
    USE_GL_FUNC(glGetProgramiv)             /* OpenGL 2.0 */
3239 3240
    USE_GL_FUNC(glGetQueryiv)               /* OpenGL 1.5 */
    USE_GL_FUNC(glGetQueryObjectuiv)        /* OpenGL 1.5 */
3241 3242 3243
    USE_GL_FUNC(glGetShaderInfoLog)         /* OpenGL 2.0 */
    USE_GL_FUNC(glGetShaderiv)              /* OpenGL 2.0 */
    USE_GL_FUNC(glGetShaderSource)          /* OpenGL 2.0 */
3244
    USE_GL_FUNC(glGetStringi)               /* OpenGL 3.0 */
3245 3246 3247
    USE_GL_FUNC(glGetUniformfv)             /* OpenGL 2.0 */
    USE_GL_FUNC(glGetUniformiv)             /* OpenGL 2.0 */
    USE_GL_FUNC(glGetUniformLocation)       /* OpenGL 2.0 */
3248
    USE_GL_FUNC(glIsEnabledi)               /* OpenGL 3.0 */
3249
    USE_GL_FUNC(glLinkProgram)              /* OpenGL 2.0 */
3250
    USE_GL_FUNC(glMapBuffer)                /* OpenGL 1.5 */
3251 3252
    USE_GL_FUNC(glPointParameteri)          /* OpenGL 1.4 */
    USE_GL_FUNC(glPointParameteriv)         /* OpenGL 1.4 */
3253
    USE_GL_FUNC(glShaderSource)             /* OpenGL 2.0 */
3254 3255
    USE_GL_FUNC(glStencilFuncSeparate)      /* OpenGL 2.0 */
    USE_GL_FUNC(glStencilOpSeparate)        /* OpenGL 2.0 */
3256
    USE_GL_FUNC(glTexBuffer)                /* OpenGL 3.1 */
3257 3258
    USE_GL_FUNC(glTexImage3D)               /* OpenGL 1.2 */
    USE_GL_FUNC(glTexSubImage3D)            /* OpenGL 1.2 */
3259
    USE_GL_FUNC(glTransformFeedbackVaryings)/* OpenGL 3.0 */
3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278
    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 */
3279
    USE_GL_FUNC(glUnmapBuffer)              /* OpenGL 1.5 */
3280 3281
    USE_GL_FUNC(glUseProgram)               /* OpenGL 2.0 */
    USE_GL_FUNC(glValidateProgram)          /* OpenGL 2.0 */
3282 3283 3284 3285 3286 3287 3288 3289 3290
    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 */
3291
    USE_GL_FUNC(glVertexAttrib4Nub)         /* OpenGL 2.0 */
3292 3293 3294 3295 3296
    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 */
3297
    USE_GL_FUNC(glVertexAttribIPointer)     /* OpenGL 3.0 */
3298
    USE_GL_FUNC(glVertexAttribPointer)      /* OpenGL 2.0 */
3299
#undef USE_GL_FUNC
3300 3301 3302 3303 3304 3305

#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
3306

3307
#define MAP_GL_FUNCTION(core_func, ext_func)                                          \
3308 3309 3310 3311 3312
        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)
3313 3314 3315 3316 3317 3318
#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)
3319 3320

    MAP_GL_FUNCTION(glActiveTexture, glActiveTextureARB);
3321
    MAP_GL_FUNCTION(glAttachShader, glAttachObjectARB);
3322
    MAP_GL_FUNCTION(glBeginQuery, glBeginQueryARB);
3323
    MAP_GL_FUNCTION(glBindAttribLocation, glBindAttribLocationARB);
3324
    MAP_GL_FUNCTION(glBindBuffer, glBindBufferARB);
3325
    MAP_GL_FUNCTION(glBindFragDataLocation, glBindFragDataLocationEXT);
3326 3327 3328 3329
    MAP_GL_FUNCTION(glBlendColor, glBlendColorEXT);
    MAP_GL_FUNCTION(glBlendEquation, glBlendEquationEXT);
    MAP_GL_FUNCTION(glBlendEquationSeparate, glBlendEquationSeparateEXT);
    MAP_GL_FUNCTION(glBlendFuncSeparate, glBlendFuncSeparateEXT);
3330 3331
    MAP_GL_FUNCTION(glBufferData, glBufferDataARB);
    MAP_GL_FUNCTION(glBufferSubData, glBufferSubDataARB);
3332
    MAP_GL_FUNCTION(glColorMaski, glColorMaskIndexedEXT);
3333
    MAP_GL_FUNCTION(glCompileShader, glCompileShaderARB);
3334 3335 3336 3337
    MAP_GL_FUNCTION(glCompressedTexImage2D, glCompressedTexImage2DARB);
    MAP_GL_FUNCTION(glCompressedTexImage3D, glCompressedTexImage3DARB);
    MAP_GL_FUNCTION(glCompressedTexSubImage2D, glCompressedTexSubImage2DARB);
    MAP_GL_FUNCTION(glCompressedTexSubImage3D, glCompressedTexSubImage3DARB);
3338 3339
    MAP_GL_FUNCTION(glCreateProgram, glCreateProgramObjectARB);
    MAP_GL_FUNCTION(glCreateShader, glCreateShaderObjectARB);
3340 3341 3342
    MAP_GL_FUNCTION(glDebugMessageCallback, glDebugMessageCallbackARB);
    MAP_GL_FUNCTION(glDebugMessageControl, glDebugMessageControlARB);
    MAP_GL_FUNCTION(glDebugMessageInsert, glDebugMessageInsertARB);
3343
    MAP_GL_FUNCTION(glDeleteBuffers, glDeleteBuffersARB);
3344
    MAP_GL_FUNCTION(glDeleteProgram, glDeleteObjectARB);
3345
    MAP_GL_FUNCTION(glDeleteQueries, glDeleteQueriesARB);
3346 3347
    MAP_GL_FUNCTION(glDeleteShader, glDeleteObjectARB);
    MAP_GL_FUNCTION(glDetachShader, glDetachObjectARB);
3348
    MAP_GL_FUNCTION(glDisablei, glDisableIndexedEXT);
3349
    MAP_GL_FUNCTION(glDisableVertexAttribArray, glDisableVertexAttribArrayARB);
3350
    MAP_GL_FUNCTION(glDrawArraysInstanced, glDrawArraysInstancedARB);
3351
    MAP_GL_FUNCTION(glDrawBuffers, glDrawBuffersARB);
3352
    MAP_GL_FUNCTION(glDrawElementsInstanced, glDrawElementsInstancedARB);
3353
    MAP_GL_FUNCTION(glEnablei, glEnableIndexedEXT);
3354
    MAP_GL_FUNCTION(glEnableVertexAttribArray, glEnableVertexAttribArrayARB);
3355
    MAP_GL_FUNCTION(glEndQuery, glEndQueryARB);
3356
    MAP_GL_FUNCTION(glFramebufferTexture, glFramebufferTextureARB);
3357
    MAP_GL_FUNCTION(glGenBuffers, glGenBuffersARB);
3358
    MAP_GL_FUNCTION(glGenQueries, glGenQueriesARB);
3359 3360 3361
    MAP_GL_FUNCTION(glGetActiveUniform, glGetActiveUniformARB);
    MAP_GL_FUNCTION(glGetAttachedShaders, glGetAttachedObjectsARB);
    MAP_GL_FUNCTION(glGetAttribLocation, glGetAttribLocationARB);
3362
    MAP_GL_FUNCTION(glGetBooleani_v, glGetBooleanIndexedvEXT);
3363
    MAP_GL_FUNCTION(glGetBufferSubData, glGetBufferSubDataARB);
3364
    MAP_GL_FUNCTION(glGetCompressedTexImage, glGetCompressedTexImageARB);
3365
    MAP_GL_FUNCTION(glGetDebugMessageLog, glGetDebugMessageLogARB);
3366
    MAP_GL_FUNCTION(glGetIntegeri_v, glGetIntegerIndexedvEXT);
3367 3368
    MAP_GL_FUNCTION(glGetProgramInfoLog, glGetInfoLogARB);
    MAP_GL_FUNCTION(glGetProgramiv, glGetObjectParameterivARB);
3369 3370
    MAP_GL_FUNCTION(glGetQueryiv, glGetQueryivARB);
    MAP_GL_FUNCTION(glGetQueryObjectuiv, glGetQueryObjectuivARB);
3371 3372 3373 3374 3375 3376
    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);
3377
    MAP_GL_FUNCTION(glIsEnabledi, glIsEnabledIndexedEXT);
3378
    MAP_GL_FUNCTION(glLinkProgram, glLinkProgramARB);
3379
    MAP_GL_FUNCTION(glMapBuffer, glMapBufferARB);
3380
    MAP_GL_FUNCTION_CAST(glShaderSource, glShaderSourceARB);
3381
    MAP_GL_FUNCTION(glTexBuffer, glTexBufferARB);
3382 3383
    MAP_GL_FUNCTION_CAST(glTexImage3D, glTexImage3DEXT);
    MAP_GL_FUNCTION(glTexSubImage3D, glTexSubImage3DEXT);
3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402
    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);
3403
    MAP_GL_FUNCTION(glUnmapBuffer, glUnmapBufferARB);
3404 3405
    MAP_GL_FUNCTION(glUseProgram, glUseProgramObjectARB);
    MAP_GL_FUNCTION(glValidateProgram, glValidateProgramARB);
3406 3407 3408 3409 3410 3411 3412 3413 3414
    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);
3415
    MAP_GL_FUNCTION(glVertexAttrib4Nub, glVertexAttrib4NubARB);
3416 3417 3418 3419 3420
    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);
3421
    MAP_GL_FUNCTION(glVertexAttribIPointer, glVertexAttribIPointerEXT);
3422
    MAP_GL_FUNCTION(glVertexAttribPointer, glVertexAttribPointerARB);
3423
#undef MAP_GL_FUNCTION
3424
#undef MAP_GL_FUNCTION_CAST
3425 3426
}

3427
static void wined3d_adapter_init_limits(struct wined3d_gl_info *gl_info)
3428
{
3429
    unsigned int i, sampler_count;
3430 3431
    GLfloat gl_floatv[2];
    GLint gl_max;
3432

3433
    gl_info->limits.blends = 1;
3434
    gl_info->limits.buffers = 1;
3435 3436
    gl_info->limits.textures = 0;
    gl_info->limits.texture_coords = 0;
3437
    for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i)
3438
    {
3439
        gl_info->limits.uniform_blocks[i] = 0;
3440 3441 3442 3443
        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];
3444
    gl_info->limits.graphics_samplers = gl_info->limits.combined_samplers;
3445
    gl_info->limits.vertex_attribs = 16;
3446
    gl_info->limits.texture_buffer_offset_alignment = 1;
3447 3448 3449 3450 3451 3452 3453 3454 3455 3456
    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;
3457

3458 3459
    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);
3460
    TRACE("Clip plane support - max planes %d.\n", gl_max);
3461

3462 3463 3464 3465 3466 3467
    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);
    }
3468

3469
    gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max);
3470
    gl_info->limits.texture_size = gl_max;
3471
    TRACE("Maximum texture size support - max texture size %d.\n", gl_max);
3472

3473 3474
    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);
3475 3476
    gl_info->limits.pointsize_min = gl_floatv[0];
    gl_info->limits.pointsize_max = gl_floatv[1];
3477
    TRACE("Maximum point size support - max point size %f.\n", gl_floatv[1]);
3478

3479 3480
    if (gl_info->supported[ARB_MAP_BUFFER_ALIGNMENT])
    {
3481
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MIN_MAP_BUFFER_ALIGNMENT, &gl_max);
3482
        TRACE("Minimum buffer map alignment: %d.\n", gl_max);
3483 3484 3485
    }
    else
    {
3486
        WARN_(d3d_perf)("Driver doesn't guarantee a minimum buffer map alignment.\n");
3487
    }
3488 3489
    if (gl_info->supported[NV_REGISTER_COMBINERS])
    {
3490
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &gl_max);
3491
        gl_info->limits.general_combiners = gl_max;
3492
        TRACE("Max general combiners: %d.\n", gl_max);
3493
    }
3494
    if (gl_info->supported[ARB_DRAW_BUFFERS] && wined3d_settings.offscreen_rendering_mode == ORM_FBO)
3495
    {
3496
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
3497
        gl_info->limits.buffers = gl_max;
3498
        TRACE("Max draw buffers: %u.\n", gl_max);
3499 3500 3501
    }
    if (gl_info->supported[ARB_MULTITEXTURE])
    {
3502 3503 3504 3505 3506
        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);
3507

3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520
            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])
3521
        {
3522
            gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &gl_max);
3523
            gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = gl_max;
3524
        }
3525 3526
        else
        {
3527
            gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL] = gl_info->limits.textures;
3528
        }
3529
        TRACE("Max fragment samplers: %d.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL]);
3530 3531 3532

        if (gl_info->supported[ARB_VERTEX_SHADER])
        {
3533 3534
            unsigned int vertex_sampler_count;

3535
            gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &gl_max);
3536
            vertex_sampler_count = gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX] = gl_max;
3537 3538 3539 3540
            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;
3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555

            /* 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. */
3556 3557
            if (vertex_sampler_count && gl_info->limits.combined_samplers < 12
                    && MAX_TEXTURES + vertex_sampler_count > gl_info->limits.combined_samplers)
3558 3559
            {
                FIXME("OpenGL implementation supports %u vertex samplers and %u total samplers.\n",
3560
                        vertex_sampler_count, gl_info->limits.combined_samplers);
3561
                FIXME("Expected vertex samplers + MAX_TEXTURES(=8) > combined_samplers.\n");
3562
                if (gl_info->limits.combined_samplers > MAX_TEXTURES)
3563
                    vertex_sampler_count = gl_info->limits.combined_samplers - MAX_TEXTURES;
3564
                else
3565 3566
                    vertex_sampler_count = 0;
                gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX] = vertex_sampler_count;
3567
            }
3568
        }
3569 3570
        else
        {
3571
            gl_info->limits.combined_samplers = gl_info->limits.samplers[WINED3D_SHADER_TYPE_PIXEL];
3572
        }
3573
        TRACE("Max vertex samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_VERTEX]);
3574
        TRACE("Max combined samplers: %u.\n", gl_info->limits.combined_samplers);
3575
        TRACE("Max vertex attributes: %u.\n", gl_info->limits.vertex_attribs);
3576
    }
3577 3578 3579 3580 3581 3582
    else
    {
        gl_info->limits.textures = 1;
        gl_info->limits.texture_coords = 1;
    }

3583
    if (gl_info->supported[ARB_VERTEX_BLEND])
3584
    {
3585
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
3586
        gl_info->limits.blends = gl_max;
3587
        TRACE("Max blends: %u.\n", gl_info->limits.blends);
3588 3589 3590
    }
    if (gl_info->supported[EXT_TEXTURE3D])
    {
3591
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
3592
        gl_info->limits.texture3d_size = gl_max;
3593
        TRACE("Max texture3D size: %d.\n", gl_info->limits.texture3d_size);
3594 3595 3596
    }
    if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
    {
3597
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
3598
        gl_info->limits.anisotropy = gl_max;
3599
        TRACE("Max anisotropy: %d.\n", gl_info->limits.anisotropy);
3600 3601 3602 3603
    }
    if (gl_info->supported[ARB_FRAGMENT_PROGRAM])
    {
        GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
3604
        gl_info->limits.arb_ps_float_constants = gl_max;
3605
        TRACE("Max ARB_FRAGMENT_PROGRAM float constants: %d.\n", gl_info->limits.arb_ps_float_constants);
3606
        GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
3607
        gl_info->limits.arb_ps_native_constants = gl_max;
3608
        TRACE("Max ARB_FRAGMENT_PROGRAM native float constants: %d.\n",
3609
                gl_info->limits.arb_ps_native_constants);
3610
        GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
3611
        gl_info->limits.arb_ps_temps = gl_max;
3612
        TRACE("Max ARB_FRAGMENT_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_ps_temps);
3613
        GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
3614
        gl_info->limits.arb_ps_instructions = gl_max;
3615
        TRACE("Max ARB_FRAGMENT_PROGRAM native instructions: %d.\n", gl_info->limits.arb_ps_instructions);
3616
        GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB, &gl_max));
3617
        gl_info->limits.arb_ps_local_constants = gl_max;
3618
        TRACE("Max ARB_FRAGMENT_PROGRAM local parameters: %d.\n", gl_info->limits.arb_ps_instructions);
3619 3620 3621 3622
    }
    if (gl_info->supported[ARB_VERTEX_PROGRAM])
    {
        GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
3623
        gl_info->limits.arb_vs_float_constants = gl_max;
3624
        TRACE("Max ARB_VERTEX_PROGRAM float constants: %d.\n", gl_info->limits.arb_vs_float_constants);
3625
        GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB, &gl_max));
3626
        gl_info->limits.arb_vs_native_constants = gl_max;
3627
        TRACE("Max ARB_VERTEX_PROGRAM native float constants: %d.\n",
3628
                gl_info->limits.arb_vs_native_constants);
3629
        GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB, &gl_max));
3630
        gl_info->limits.arb_vs_temps = gl_max;
3631
        TRACE("Max ARB_VERTEX_PROGRAM native temporaries: %d.\n", gl_info->limits.arb_vs_temps);
3632
        GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB, &gl_max));
3633
        gl_info->limits.arb_vs_instructions = gl_max;
3634
        TRACE("Max ARB_VERTEX_PROGRAM native instructions: %d.\n", gl_info->limits.arb_vs_instructions);
3635 3636 3637
    }
    if (gl_info->supported[ARB_VERTEX_SHADER])
    {
3638
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
3639
        gl_info->limits.glsl_vs_float_constants = gl_max / 4;
3640
        TRACE("Max ARB_VERTEX_SHADER float constants: %u.\n", gl_info->limits.glsl_vs_float_constants);
3641 3642 3643 3644

        if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT])
        {
            gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VERTEX_UNIFORM_BLOCKS, &gl_max);
3645 3646 3647
            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);
3648 3649
        }
    }
3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667
    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]);
    }
3668
    if (gl_info->supported[WINED3D_GL_VERSION_3_2] && gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT])
3669 3670
    {
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_GEOMETRY_UNIFORM_BLOCKS, &gl_max);
3671 3672 3673
        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);
3674
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &gl_max);
3675 3676
        gl_info->limits.samplers[WINED3D_SHADER_TYPE_GEOMETRY] = gl_max;
        TRACE("Max geometry samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_GEOMETRY]);
3677 3678 3679
    }
    if (gl_info->supported[ARB_FRAGMENT_SHADER])
    {
3680
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
3681
        gl_info->limits.glsl_ps_float_constants = gl_max / 4;
3682
        TRACE("Max ARB_FRAGMENT_SHADER float constants: %u.\n", gl_info->limits.glsl_ps_float_constants);
3683
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_VARYING_FLOATS_ARB, &gl_max);
3684
        gl_info->limits.glsl_varyings = gl_max;
3685
        TRACE("Max GLSL varyings: %u (%u 4 component varyings).\n", gl_max, gl_max / 4);
3686 3687 3688 3689

        if (gl_info->supported[ARB_UNIFORM_BUFFER_OBJECT])
        {
            gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &gl_max);
3690 3691 3692
            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);
3693 3694
        }
    }
3695 3696 3697 3698 3699 3700
    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);
3701
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS, &gl_max);
3702 3703
        gl_info->limits.samplers[WINED3D_SHADER_TYPE_COMPUTE] = gl_max;
        TRACE("Max compute samplers: %u.\n", gl_info->limits.samplers[WINED3D_SHADER_TYPE_COMPUTE]);
3704
    }
3705 3706 3707 3708 3709 3710
    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);
3711
    }
3712 3713 3714 3715 3716 3717
    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);
    }
3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734
    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;
        }
    }
3735 3736 3737 3738 3739
    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);
    }
3740 3741

    if (gl_info->supported[NV_LIGHT_MAX_EXPONENT])
3742
        gl_info->gl_ops.gl.p_glGetFloatv(GL_MAX_SHININESS_NV, &gl_info->limits.shininess);
3743 3744 3745
    else
        gl_info->limits.shininess = 128.0f;

3746
    if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT] || gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE])
3747
    {
3748
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_MAX_SAMPLES, &gl_max);
3749 3750
        gl_info->limits.samples = gl_max;
    }
3751

3752 3753 3754 3755 3756
    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];
3757 3758 3759 3760 3761 3762 3763
    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);
3764 3765
        for (i = 0; i < WINED3D_SHADER_TYPE_GRAPHICS_COUNT; ++i)
            gl_info->limits.samplers[i] = min(gl_info->limits.samplers[i], 16);
3766 3767 3768 3769 3770
    }

    /* 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;
3771 3772 3773
    sampler_count = 0;
    for (i = 0; i < WINED3D_SHADER_TYPE_COUNT; ++i)
        sampler_count += gl_info->limits.samplers[i];
3774 3775
    if (gl_info->limits.combined_samplers >= sampler_count)
        gl_info->limits.graphics_samplers -= gl_info->limits.samplers[WINED3D_SHADER_TYPE_COMPUTE];
3776
}
3777

3778
/* Context activation is done by the caller. */
3779 3780
static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter,
        struct wined3d_caps_gl_ctx *caps_gl_ctx, DWORD wined3d_creation_flags)
3781
{
3782 3783 3784 3785 3786 3787 3788 3789
    static const struct
    {
        enum wined3d_gl_extension extension;
        DWORD min_gl_version;
    }
    core_extensions[] =
    {
        {EXT_TEXTURE3D,                    MAKEDWORD_VERSION(1, 2)},
3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800
        {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)},
3801 3802
        {EXT_BLEND_MINMAX,                 MAKEDWORD_VERSION(1, 4)},
        {EXT_BLEND_SUBTRACT,               MAKEDWORD_VERSION(1, 4)},
3803
        {EXT_STENCIL_WRAP,                 MAKEDWORD_VERSION(1, 4)},
3804
        {NV_POINT_SPRITE,                  MAKEDWORD_VERSION(1, 4)},
3805 3806 3807 3808 3809
        {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)},
3810
        {ARB_TEXTURE_NON_POWER_OF_TWO,     MAKEDWORD_VERSION(2, 0)},
3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825
        {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)},
3826
        {EXT_PACKED_FLOAT,                 MAKEDWORD_VERSION(3, 0)},
3827
        {EXT_TEXTURE_ARRAY,                MAKEDWORD_VERSION(3, 0)},
3828
        {EXT_TEXTURE_INTEGER,              MAKEDWORD_VERSION(3, 0)},
3829
        {EXT_TEXTURE_SHARED_EXPONENT,      MAKEDWORD_VERSION(3, 0)},
3830 3831 3832 3833 3834 3835 3836 3837
        /* 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. */

3838
        {ARB_COPY_BUFFER,                  MAKEDWORD_VERSION(3, 1)},
3839
        {ARB_DRAW_INSTANCED,               MAKEDWORD_VERSION(3, 1)},
3840
        {ARB_TEXTURE_BUFFER_OBJECT,        MAKEDWORD_VERSION(3, 1)},
3841 3842 3843 3844 3845 3846 3847 3848
        {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. */
3849
        {ARB_FRAGMENT_COORD_CONVENTIONS,   MAKEDWORD_VERSION(3, 2)},
3850
        {ARB_PROVOKING_VERTEX,             MAKEDWORD_VERSION(3, 2)},
3851
        {ARB_SEAMLESS_CUBE_MAP,            MAKEDWORD_VERSION(3, 2)},
3852 3853 3854 3855
        {ARB_SYNC,                         MAKEDWORD_VERSION(3, 2)},
        {ARB_VERTEX_ARRAY_BGRA,            MAKEDWORD_VERSION(3, 2)},

        {ARB_BLEND_FUNC_EXTENDED,          MAKEDWORD_VERSION(3, 3)},
3856
        {ARB_EXPLICIT_ATTRIB_LOCATION,     MAKEDWORD_VERSION(3, 3)},
3857 3858 3859
        {ARB_INSTANCED_ARRAYS,             MAKEDWORD_VERSION(3, 3)},
        {ARB_SAMPLER_OBJECTS,              MAKEDWORD_VERSION(3, 3)},
        {ARB_SHADER_BIT_ENCODING,          MAKEDWORD_VERSION(3, 3)},
3860
        {ARB_TEXTURE_RGB10_A2UI,           MAKEDWORD_VERSION(3, 3)},
3861
        {ARB_TEXTURE_SWIZZLE,              MAKEDWORD_VERSION(3, 3)},
3862
        {ARB_TIMER_QUERY,                  MAKEDWORD_VERSION(3, 3)},
3863
        {ARB_VERTEX_TYPE_2_10_10_10_REV,   MAKEDWORD_VERSION(3, 3)},
3864

3865
        {ARB_GPU_SHADER5,                  MAKEDWORD_VERSION(4, 0)},
3866
        {ARB_TESSELLATION_SHADER,          MAKEDWORD_VERSION(4, 0)},
3867
        {ARB_TEXTURE_CUBE_MAP_ARRAY,       MAKEDWORD_VERSION(4, 0)},
3868
        {ARB_TEXTURE_GATHER,               MAKEDWORD_VERSION(4, 0)},
3869
        {ARB_TRANSFORM_FEEDBACK2,          MAKEDWORD_VERSION(4, 0)},
3870
        {ARB_TRANSFORM_FEEDBACK3,          MAKEDWORD_VERSION(4, 0)},
3871

3872
        {ARB_ES2_COMPATIBILITY,            MAKEDWORD_VERSION(4, 1)},
3873
        {ARB_VIEWPORT_ARRAY,               MAKEDWORD_VERSION(4, 1)},
3874

3875
        {ARB_INTERNALFORMAT_QUERY,         MAKEDWORD_VERSION(4, 2)},
3876
        {ARB_MAP_BUFFER_ALIGNMENT,         MAKEDWORD_VERSION(4, 2)},
3877
        {ARB_SHADER_ATOMIC_COUNTERS,       MAKEDWORD_VERSION(4, 2)},
3878
        {ARB_SHADER_IMAGE_LOAD_STORE,      MAKEDWORD_VERSION(4, 2)},
3879
        {ARB_SHADING_LANGUAGE_420PACK,     MAKEDWORD_VERSION(4, 2)},
3880
        {ARB_SHADING_LANGUAGE_PACKING,     MAKEDWORD_VERSION(4, 2)},
3881
        {ARB_TEXTURE_COMPRESSION_BPTC,     MAKEDWORD_VERSION(4, 2)},
3882
        {ARB_TEXTURE_STORAGE,              MAKEDWORD_VERSION(4, 2)},
3883

3884
        {ARB_CLEAR_BUFFER_OBJECT,          MAKEDWORD_VERSION(4, 3)},
3885
        {ARB_COMPUTE_SHADER,               MAKEDWORD_VERSION(4, 3)},
3886
        {ARB_DEBUG_OUTPUT,                 MAKEDWORD_VERSION(4, 3)},
3887
        {ARB_ES3_COMPATIBILITY,            MAKEDWORD_VERSION(4, 3)},
3888
        {ARB_FRAGMENT_LAYER_VIEWPORT,      MAKEDWORD_VERSION(4, 3)},
3889
        {ARB_INTERNALFORMAT_QUERY2,        MAKEDWORD_VERSION(4, 3)},
3890
        {ARB_SHADER_IMAGE_SIZE,            MAKEDWORD_VERSION(4, 3)},
3891
        {ARB_SHADER_STORAGE_BUFFER_OBJECT, MAKEDWORD_VERSION(4, 3)},
3892
        {ARB_STENCIL_TEXTURING,            MAKEDWORD_VERSION(4, 3)},
3893
        {ARB_TEXTURE_BUFFER_RANGE,         MAKEDWORD_VERSION(4, 3)},
3894
        {ARB_TEXTURE_QUERY_LEVELS,         MAKEDWORD_VERSION(4, 3)},
3895
        {ARB_TEXTURE_VIEW,                 MAKEDWORD_VERSION(4, 3)},
3896

3897 3898
        {ARB_CLEAR_TEXTURE,                MAKEDWORD_VERSION(4, 4)},

3899
        {ARB_CLIP_CONTROL,                 MAKEDWORD_VERSION(4, 5)},
3900
        {ARB_DERIVATIVE_CONTROL,           MAKEDWORD_VERSION(4, 5)},
3901
    };
3902 3903 3904
    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;
3905
    const struct gpu_description *gpu_description;
3906
    struct wined3d_vertex_caps vertex_caps;
3907
    struct fragment_caps fragment_caps;
3908
    struct shader_caps shader_caps;
3909 3910
    const char *WGL_Extensions = NULL;
    enum wined3d_gl_vendor gl_vendor;
3911
    DWORD gl_version, gl_ext_emul_mask;
3912
    UINT64 vram_bytes = 0;
3913
    HDC hdc;
3914
    unsigned int i, j;
3915
    GLint context_profile = 0;
3916

3917 3918
    TRACE("adapter %p.\n", adapter);

3919
    gl_renderer_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_RENDERER);
3920 3921 3922 3923 3924
    TRACE("GL_RENDERER: %s.\n", debugstr_a(gl_renderer_str));
    if (!gl_renderer_str)
    {
        ERR("Received a NULL GL_RENDERER.\n");
        return FALSE;
3925
    }
3926

3927
    gl_vendor_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_VENDOR);
3928 3929
    TRACE("GL_VENDOR: %s.\n", debugstr_a(gl_vendor_str));
    if (!gl_vendor_str)
3930
    {
3931 3932 3933 3934 3935
        ERR("Received a NULL GL_VENDOR.\n");
        return FALSE;
    }

    /* Parse the GL_VERSION field into major and minor information */
3936
    gl_version_str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_VERSION);
3937 3938 3939 3940 3941 3942 3943 3944
    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);

3945
    load_gl_funcs(gl_info);
3946 3947 3948 3949

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

3950 3951
    if (gl_version >= MAKEDWORD_VERSION(3, 2))
    {
3952
        gl_info->gl_ops.gl.p_glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &context_profile);
3953 3954 3955 3956 3957 3958 3959
        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;

3960
    TRACE("GL extensions reported:\n");
3961 3962 3963
    if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
    {
        const char *gl_extensions = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_EXTENSIONS);
3964

3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977
        if (!gl_extensions)
        {
            ERR("Received a NULL GL_EXTENSIONS.\n");
            return FALSE;
        }
        parse_extension_string(gl_info, gl_extensions, gl_extension_map,
                sizeof(gl_extension_map) / sizeof(*gl_extension_map));
    }
    else
    {
        enumerate_gl_extensions(gl_info, gl_extension_map,
                sizeof(gl_extension_map) / sizeof(*gl_extension_map));
    }
3978

3979
    hdc = wglGetCurrentDC();
3980 3981
    /* Not all GL drivers might offer WGL extensions e.g. VirtualBox. */
    if (GL_EXTCALL(wglGetExtensionsStringARB))
3982
        WGL_Extensions = (const char *)GL_EXTCALL(wglGetExtensionsStringARB(hdc));
3983 3984
    if (!WGL_Extensions)
        WARN("WGL extensions not supported.\n");
3985
    else
3986 3987 3988
        parse_extension_string(gl_info, WGL_Extensions, wgl_extension_map,
                sizeof(wgl_extension_map) / sizeof(*wgl_extension_map));

3989
    for (i = 0; i < ARRAY_SIZE(core_extensions); ++i)
3990
    {
3991 3992 3993 3994 3995 3996
        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;
3997

3998 3999 4000 4001 4002 4003 4004 4005 4006 4007
            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);
            }
        }
4008 4009
    }

4010 4011 4012 4013 4014
    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;
4015 4016
    if (gl_version >= MAKEDWORD_VERSION(3, 2))
        gl_info->supported[WINED3D_GL_VERSION_3_2] = TRUE;
4017

4018 4019 4020 4021 4022
    /* 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;

4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068
    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;
    }
4069 4070 4071 4072 4073
    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;
    }
4074 4075 4076 4077 4078
    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;
    }
4079 4080 4081 4082 4083
    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;
    }
4084 4085 4086 4087 4088 4089 4090 4091 4092
    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;
        }
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
    }
    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;
    }
4118 4119 4120 4121 4122
    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). */
4123
        TRACE("EXT_texture_sRGB_decode is not supported, disabling ARB_framebuffer_sRGB.\n");
4124 4125
        gl_info->supported[ARB_FRAMEBUFFER_SRGB] = FALSE;
    }
4126 4127 4128 4129
    if (gl_info->supported[ARB_OCCLUSION_QUERY])
    {
        GLint counter_bits;

4130
        GL_EXTCALL(glGetQueryiv(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &counter_bits));
4131 4132 4133 4134
        TRACE("Occlusion query counter has %d bits.\n", counter_bits);
        if (!counter_bits)
            gl_info->supported[ARB_OCCLUSION_QUERY] = FALSE;
    }
4135 4136 4137 4138
    if (gl_info->supported[ARB_TIMER_QUERY])
    {
        GLint counter_bits;

4139
        GL_EXTCALL(glGetQueryiv(GL_TIMESTAMP, GL_QUERY_COUNTER_BITS, &counter_bits));
4140 4141 4142 4143
        TRACE("Timestamp query counter has %d bits.\n", counter_bits);
        if (!counter_bits)
            gl_info->supported[ARB_TIMER_QUERY] = FALSE;
    }
4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159
    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;
    }
4160 4161 4162 4163 4164 4165
    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);
4166 4167 4168 4169 4170
        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;
        }
4171 4172 4173 4174 4175 4176 4177 4178 4179
    }
    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;
    }
4180 4181 4182 4183 4184 4185
    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;
    }
4186 4187 4188 4189 4190
    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;
    }
4191 4192 4193 4194 4195
    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;
    }
4196 4197 4198 4199 4200 4201
    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. */
        FIXME("Disabling APPLE_ycbcr_422 because of ARB_texture_storage.\n");
        gl_info->supported[APPLE_YCBCR_422] = FALSE;
    }
4202 4203 4204 4205 4206 4207 4208 4209

    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])
    {
4210
        const char *str = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_SHADING_LANGUAGE_VERSION_ARB);
4211 4212 4213 4214 4215 4216 4217
        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);
4218 4219
        if (gl_info->glsl_version >= MAKEDWORD_VERSION(1, 30))
            gl_info->supported[WINED3D_GLSL_130] = TRUE;
4220 4221
    }

4222
    checkGLcall("extension detection");
4223

4224
    adapter->shader_backend = select_shader_backend(gl_info);
4225
    adapter->vertex_pipe = select_vertex_implementation(gl_info, adapter->shader_backend);
4226
    adapter->fragment_pipe = select_fragment_implementation(gl_info, adapter->shader_backend);
4227

4228
    adapter->shader_backend->shader_get_caps(gl_info, &shader_caps);
4229
    adapter->d3d_info.vs_clipping = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_VS_CLIPPING;
4230
    adapter->d3d_info.limits.vs_version = shader_caps.vs_version;
4231
    adapter->d3d_info.limits.hs_version = shader_caps.hs_version;
4232
    adapter->d3d_info.limits.ds_version = shader_caps.ds_version;
4233 4234
    adapter->d3d_info.limits.gs_version = shader_caps.gs_version;
    adapter->d3d_info.limits.ps_version = shader_caps.ps_version;
4235
    adapter->d3d_info.limits.cs_version = shader_caps.cs_version;
4236 4237
    adapter->d3d_info.limits.vs_uniform_count = shader_caps.vs_uniform_count;
    adapter->d3d_info.limits.ps_uniform_count = shader_caps.ps_uniform_count;
4238
    adapter->d3d_info.limits.varying_count = shader_caps.varying_count;
4239
    adapter->d3d_info.shader_double_precision = shader_caps.wined3d_caps & WINED3D_SHADER_CAP_DOUBLE_PRECISION;
4240

4241 4242
    adapter->vertex_pipe->vp_get_caps(gl_info, &vertex_caps);
    adapter->d3d_info.xyzrhw = vertex_caps.xyzrhw;
4243
    adapter->d3d_info.ffp_generic_attributes = vertex_caps.ffp_generic_attributes;
4244
    adapter->d3d_info.limits.ffp_vertex_blend_matrices = vertex_caps.max_vertex_blend_matrices;
4245
    adapter->d3d_info.limits.active_light_count = vertex_caps.max_active_lights;
4246
    adapter->d3d_info.emulated_flatshading = vertex_caps.emulated_flatshading;
4247

4248
    adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
4249
    adapter->d3d_info.limits.ffp_blend_stages = fragment_caps.MaxTextureBlendStages;
4250
    adapter->d3d_info.limits.ffp_textures = fragment_caps.MaxSimultaneousTextures;
4251
    adapter->d3d_info.shader_color_key = fragment_caps.wined3d_caps & WINED3D_FRAGMENT_CAP_COLOR_KEY;
4252
    adapter->d3d_info.wined3d_creation_flags = wined3d_creation_flags;
4253
    TRACE("Max texture stages: %u.\n", adapter->d3d_info.limits.ffp_blend_stages);
4254

4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265
    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;
    }

4266 4267
    if (gl_info->supported[ARB_FRAMEBUFFER_OBJECT])
    {
4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282
        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;
4283
        gl_info->fbo_ops.glFramebufferTextureLayer = gl_info->gl_ops.ext.p_glFramebufferTextureLayer;
4284 4285 4286 4287 4288
        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;
4289
        gl_info->fbo_ops.glFramebufferTexture = gl_info->gl_ops.ext.p_glFramebufferTexture;
4290 4291 4292 4293 4294
    }
    else
    {
        if (gl_info->supported[EXT_FRAMEBUFFER_OBJECT])
        {
4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312
            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;
4313 4314 4315
        }
        else if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
        {
4316
            WARN_(d3d_perf)("Framebuffer objects not supported, falling back to backbuffer offscreen rendering mode.\n");
4317 4318
            wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
        }
4319 4320 4321

        if (gl_info->supported[ARB_GEOMETRY_SHADER4])
        {
4322
            gl_info->fbo_ops.glFramebufferTexture = gl_info->gl_ops.ext.p_glFramebufferTextureARB;
4323 4324
            gl_info->fbo_ops.glFramebufferTextureLayer = gl_info->gl_ops.ext.p_glFramebufferTextureLayerARB;
        }
4325 4326
        if (gl_info->supported[EXT_FRAMEBUFFER_BLIT])
        {
4327
            gl_info->fbo_ops.glBlitFramebuffer = gl_info->gl_ops.ext.p_glBlitFramebufferEXT;
4328 4329 4330
        }
        if (gl_info->supported[EXT_FRAMEBUFFER_MULTISAMPLE])
        {
4331 4332
            gl_info->fbo_ops.glRenderbufferStorageMultisample
                    = gl_info->gl_ops.ext.p_glRenderbufferStorageMultisampleEXT;
4333
        }
4334 4335
    }

4336 4337
    gl_info->wrap_lookup[WINED3D_TADDRESS_WRAP - WINED3D_TADDRESS_WRAP] = GL_REPEAT;
    gl_info->wrap_lookup[WINED3D_TADDRESS_MIRROR - WINED3D_TADDRESS_WRAP] =
4338
            gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT] ? GL_MIRRORED_REPEAT_ARB : GL_REPEAT;
4339 4340
    gl_info->wrap_lookup[WINED3D_TADDRESS_CLAMP - WINED3D_TADDRESS_WRAP] = GL_CLAMP_TO_EDGE;
    gl_info->wrap_lookup[WINED3D_TADDRESS_BORDER - WINED3D_TADDRESS_WRAP] =
4341
            gl_info->supported[ARB_TEXTURE_BORDER_CLAMP] ? GL_CLAMP_TO_BORDER_ARB : GL_REPEAT;
4342
    gl_info->wrap_lookup[WINED3D_TADDRESS_MIRROR_ONCE - WINED3D_TADDRESS_WRAP] =
4343
            gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE] ? GL_MIRROR_CLAMP_TO_EDGE : GL_REPEAT;
4344

4345 4346 4347 4348 4349 4350 4351 4352 4353
    if (!gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
    {
        GLuint vao;

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

4354
    gl_vendor = wined3d_guess_gl_vendor(gl_info, gl_vendor_str, gl_renderer_str, gl_version_str);
4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371
    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);
4372
            return FALSE;
4373 4374
        }
    }
4375 4376
    fixup_extensions(gl_info, caps_gl_ctx, gl_renderer_str, gl_vendor,
            gpu_description->vendor, gpu_description->card);
4377 4378
    init_driver_info(driver_info, gpu_description, vram_bytes);

4379 4380 4381 4382 4383 4384
    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);
4385

4386
    return TRUE;
4387 4388
}

4389 4390
UINT CDECL wined3d_get_adapter_count(const struct wined3d *wined3d)
{
4391
    TRACE("wined3d %p, reporting %u adapters.\n",
4392
            wined3d, wined3d->adapter_count);
4393

4394
    return wined3d->adapter_count;
4395 4396
}

4397
HRESULT CDECL wined3d_register_software_device(struct wined3d *wined3d, void *init_function)
4398
{
4399
    FIXME("wined3d %p, init_function %p stub!\n", wined3d, init_function);
4400

4401
    return WINED3D_OK;
4402 4403
}

4404 4405
HRESULT CDECL wined3d_get_output_desc(const struct wined3d *wined3d, unsigned int adapter_idx,
        struct wined3d_output_desc *desc)
4406
{
4407 4408 4409 4410 4411 4412 4413
    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);
4414

4415
    if (adapter_idx >= wined3d->adapter_count)
4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432
        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;
4433

4434
    return WINED3D_OK;
4435 4436
}

4437
/* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
4438 4439
     of the same bpp but different resolutions                                  */

4440
/* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
4441
UINT CDECL wined3d_get_adapter_mode_count(const struct wined3d *wined3d, UINT adapter_idx,
4442
        enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering)
4443
{
4444 4445 4446 4447 4448 4449 4450
    const struct wined3d_adapter *adapter;
    const struct wined3d_format *format;
    unsigned int i = 0;
    unsigned int j = 0;
    UINT format_bits;
    DEVMODEW mode;

4451 4452
    TRACE("wined3d %p, adapter_idx %u, format %s, scanline_ordering %#x.\n",
            wined3d, adapter_idx, debug_d3dformat(format_id), scanline_ordering);
4453

4454
    if (adapter_idx >= wined3d->adapter_count)
4455 4456
        return 0;

4457
    adapter = &wined3d->adapters[adapter_idx];
4458
    format = wined3d_get_format(&adapter->gl_info, format_id, WINED3DUSAGE_RENDERTARGET);
4459
    format_bits = format->byte_count * CHAR_BIT;
4460

4461 4462
    memset(&mode, 0, sizeof(mode));
    mode.dmSize = sizeof(mode);
4463

4464 4465
    while (EnumDisplaySettingsExW(adapter->DeviceName, j++, &mode, 0))
    {
4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476
        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;
        }

4477
        if (format_id == WINED3DFMT_UNKNOWN)
4478
        {
4479 4480 4481 4482 4483 4484
            /* This is for d3d8, do not enumerate P8 here. */
            if (mode.dmBitsPerPel == 32 || mode.dmBitsPerPel == 16) ++i;
        }
        else if (mode.dmBitsPerPel == format_bits)
        {
            ++i;
4485
        }
4486 4487
    }

4488 4489 4490
    TRACE("Returning %u matching modes (out of %u total) for adapter %u.\n", i, j, adapter_idx);

    return i;
4491 4492
}

4493
/* Note: dx9 supplies a format. Calls from d3d8 supply WINED3DFMT_UNKNOWN */
4494
HRESULT CDECL wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT adapter_idx,
4495 4496
        enum wined3d_format_id format_id, enum wined3d_scanline_ordering scanline_ordering,
        UINT mode_idx, struct wined3d_display_mode *mode)
4497
{
4498 4499 4500 4501 4502 4503 4504
    const struct wined3d_adapter *adapter;
    const struct wined3d_format *format;
    UINT format_bits;
    DEVMODEW m;
    UINT i = 0;
    int j = 0;

4505 4506
    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);
4507

4508
    if (!mode || adapter_idx >= wined3d->adapter_count)
4509
        return WINED3DERR_INVALIDCALL;
4510

4511
    adapter = &wined3d->adapters[adapter_idx];
4512
    format = wined3d_get_format(&adapter->gl_info, format_id, WINED3DUSAGE_RENDERTARGET);
4513
    format_bits = format->byte_count * CHAR_BIT;
4514

4515 4516
    memset(&m, 0, sizeof(m));
    m.dmSize = sizeof(m);
4517

4518 4519 4520
    while (i <= mode_idx)
    {
        if (!EnumDisplaySettingsExW(adapter->DeviceName, j++, &m, 0))
4521
        {
4522 4523
            WARN("Invalid mode_idx %u.\n", mode_idx);
            return WINED3DERR_INVALIDCALL;
4524 4525
        }

4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536
        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;
        }

4537
        if (format_id == WINED3DFMT_UNKNOWN)
4538 4539 4540 4541 4542 4543 4544 4545 4546
        {
            /* This is for d3d8, do not enumerate P8 here. */
            if (m.dmBitsPerPel == 32 || m.dmBitsPerPel == 16) ++i;
        }
        else if (m.dmBitsPerPel == format_bits)
        {
            ++i;
        }
    }
4547

4548 4549 4550 4551 4552
    mode->width = m.dmPelsWidth;
    mode->height = m.dmPelsHeight;
    mode->refresh_rate = DEFAULT_REFRESH_RATE;
    if (m.dmFields & DM_DISPLAYFREQUENCY)
        mode->refresh_rate = m.dmDisplayFrequency;
4553

4554 4555
    if (format_id == WINED3DFMT_UNKNOWN)
        mode->format_id = pixelformat_for_depth(m.dmBitsPerPel);
4556
    else
4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567
        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);
4568

4569
    return WINED3D_OK;
4570 4571
}

4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671
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;
    }

    if (!(modes = wined3d_calloc(mode_count, sizeof(*modes))))
        return E_OUTOFMEMORY;
    if (!(matching_modes = wined3d_calloc(mode_count, sizeof(*matching_modes))))
    {
        HeapFree(GetProcessHeap(), 0, modes);
        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])))
        {
            HeapFree(GetProcessHeap(), 0, matching_modes);
            HeapFree(GetProcessHeap(), 0, modes);
            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)))
        {
            HeapFree(GetProcessHeap(), 0, matching_modes);
            HeapFree(GetProcessHeap(), 0, modes);
            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];

    HeapFree(GetProcessHeap(), 0, matching_modes);
    HeapFree(GetProcessHeap(), 0, modes);

    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;
}

4672
HRESULT CDECL wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UINT adapter_idx,
4673
        struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation)
4674
{
4675
    const struct wined3d_adapter *adapter;
4676
    DEVMODEW m;
4677

4678 4679
    TRACE("wined3d %p, adapter_idx %u, display_mode %p, rotation %p.\n",
            wined3d, adapter_idx, mode, rotation);
4680

4681
    if (!mode || adapter_idx >= wined3d->adapter_count)
4682
        return WINED3DERR_INVALIDCALL;
4683

4684 4685
    adapter = &wined3d->adapters[adapter_idx];

4686 4687
    memset(&m, 0, sizeof(m));
    m.dmSize = sizeof(m);
4688

4689 4690 4691 4692 4693 4694 4695
    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);
4696

4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707
    /* 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;
    }
4708

4709 4710 4711 4712 4713 4714
    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;
4715

4716 4717 4718
    if (rotation)
    {
        switch (m.u1.s2.dmDisplayOrientation)
4719
        {
4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735
            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;
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);
4742
    return WINED3D_OK;
4743
}
4744

4745 4746 4747 4748
HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d,
        UINT adapter_idx, const struct wined3d_display_mode *mode)
{
    struct wined3d_adapter *adapter;
4749
    DEVMODEW new_mode, current_mode;
4750 4751
    RECT clip_rc;
    LONG ret;
4752
    enum wined3d_format_id new_format_id;
4753

4754
    TRACE("wined3d %p, adapter_idx %u, mode %p.\n", wined3d, adapter_idx, mode);
4755 4756 4757 4758 4759

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

4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770
    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);

4771
        format = wined3d_get_format(&adapter->gl_info, mode->format_id, WINED3DUSAGE_RENDERTARGET);
4772 4773 4774 4775 4776

        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;
4777

4778 4779 4780
        new_mode.dmDisplayFrequency = mode->refresh_rate;
        if (mode->refresh_rate)
            new_mode.dmFields |= DM_DISPLAYFREQUENCY;
4781

4782 4783 4784 4785 4786 4787 4788 4789 4790
        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
4791
    {
4792
        if (!EnumDisplaySettingsW(adapter->DeviceName, ENUM_REGISTRY_SETTINGS, &new_mode))
4793 4794 4795 4796 4797
        {
            ERR("Failed to read mode from registry.\n");
            return WINED3DERR_NOTAVAILABLE;
        }
        new_format_id = pixelformat_for_depth(new_mode.dmBitsPerPel);
4798 4799
    }

4800
    /* Only change the mode if necessary. */
4801
    if (!EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &current_mode))
4802
    {
4803
        ERR("Failed to get current display mode.\n");
4804
    }
4805 4806 4807 4808 4809 4810
    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
4811
            || !(new_mode.dmFields & DM_DISPLAYFLAGS)))
4812 4813
    {
        TRACE("Skipping redundant mode setting call.\n");
4814
        adapter->screen_format = new_format_id;
4815 4816 4817
        return WINED3D_OK;
    }

4818
    ret = ChangeDisplaySettingsExW(adapter->DeviceName, &new_mode, NULL, CDS_FULLSCREEN, NULL);
4819 4820
    if (ret != DISP_CHANGE_SUCCESSFUL)
    {
4821
        if (new_mode.dmFields & DM_DISPLAYFREQUENCY)
4822 4823
        {
            WARN("ChangeDisplaySettingsExW failed, trying without the refresh rate.\n");
4824 4825 4826
            new_mode.dmFields &= ~DM_DISPLAYFREQUENCY;
            new_mode.dmDisplayFrequency = 0;
            ret = ChangeDisplaySettingsExW(adapter->DeviceName, &new_mode, NULL, CDS_FULLSCREEN, NULL);
4827 4828 4829 4830 4831 4832
        }
        if (ret != DISP_CHANGE_SUCCESSFUL)
            return WINED3DERR_NOTAVAILABLE;
    }

    /* Store the new values. */
4833
    adapter->screen_format = new_format_id;
4834 4835

    /* And finally clip mouse to our screen. */
4836
    SetRect(&clip_rc, 0, 0, new_mode.dmPelsWidth, new_mode.dmPelsHeight);
4837 4838 4839 4840 4841
    ClipCursor(&clip_rc);

    return WINED3D_OK;
}

4842
/* NOTE: due to structure differences between dx8 and dx9 D3DADAPTER_IDENTIFIER,
4843
   and fields being inserted in the middle, a new structure is used in place    */
4844
HRESULT CDECL wined3d_get_adapter_identifier(const struct wined3d *wined3d,
4845
        UINT adapter_idx, DWORD flags, struct wined3d_adapter_identifier *identifier)
4846
{
4847
    const struct wined3d_adapter *adapter;
4848
    size_t len;
4849

4850
    TRACE("wined3d %p, adapter_idx %u, flags %#x, identifier %p.\n",
4851
            wined3d, adapter_idx, flags, identifier);
4852

4853
    if (adapter_idx >= wined3d->adapter_count)
4854
        return WINED3DERR_INVALIDCALL;
4855

4856
    adapter = &wined3d->adapters[adapter_idx];
4857

4858
    if (identifier->driver_size)
4859
    {
4860
        const char *name = adapter->driver_info.name;
4861 4862
        len = min(strlen(name), identifier->driver_size - 1);
        memcpy(identifier->driver, name, len);
4863
        memset(&identifier->driver[len], 0, identifier->driver_size - len);
4864 4865
    }

4866
    if (identifier->description_size)
4867
    {
4868
        const char *description = adapter->driver_info.description;
4869 4870
        len = min(strlen(description), identifier->description_size - 1);
        memcpy(identifier->description, description, len);
4871
        memset(&identifier->description[len], 0, identifier->description_size - len);
4872 4873 4874
    }

    /* Note that d3d8 doesn't supply a device name. */
4875
    if (identifier->device_name_size)
4876
    {
4877 4878
        if (!WideCharToMultiByte(CP_ACP, 0, adapter->DeviceName, -1, identifier->device_name,
                identifier->device_name_size, NULL, NULL))
4879
        {
4880
            ERR("Failed to convert device name, last error %#x.\n", GetLastError());
4881 4882 4883 4884
            return WINED3DERR_INVALIDCALL;
        }
    }

4885 4886 4887 4888 4889 4890 4891 4892 4893
    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));
4894
    identifier->video_memory = min(~(SIZE_T)0, adapter->vram_bytes);
4895

4896
    return WINED3D_OK;
4897 4898
}

4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945
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;
}

4946
static BOOL wined3d_check_pixel_format_color(const struct wined3d_gl_info *gl_info,
4947
        const struct wined3d_pixel_format *cfg, const struct wined3d_format *format)
4948
{
4949
    /* Float formats need FBOs. If FBOs are used this function isn't called */
4950 4951
    if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT)
        return FALSE;
4952

4953 4954 4955
    /* Probably a RGBA_float or color index mode. */
    if (cfg->iPixelType != WGL_TYPE_RGBA_ARB)
        return FALSE;
4956

4957 4958 4959 4960 4961
    if (cfg->redSize < format->red_size
            || cfg->greenSize < format->green_size
            || cfg->blueSize < format->blue_size
            || cfg->alphaSize < format->alpha_size)
        return FALSE;
4962

4963
    return TRUE;
4964 4965
}

4966
static BOOL wined3d_check_pixel_format_depth(const struct wined3d_gl_info *gl_info,
4967
        const struct wined3d_pixel_format *cfg, const struct wined3d_format *format)
4968
{
4969
    BOOL lockable = FALSE;
4970

4971
    /* Float formats need FBOs. If FBOs are used this function isn't called */
4972 4973
    if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_FLOAT)
        return FALSE;
4974

4975
    if ((format->id == WINED3DFMT_D16_LOCKABLE) || (format->id == WINED3DFMT_D32_FLOAT))
4976 4977
        lockable = TRUE;

4978
    /* On some modern cards like the Geforce8/9, GLX doesn't offer some
4979
     * depth/stencil formats which D3D9 reports. We can safely report
4980 4981 4982 4983
     * "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)))
4984 4985
        return FALSE;

4986
    /* Some cards like Intel i915 ones only offer D24S8 but lots of games also
4987 4988 4989 4990
     * 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)
4991 4992
        return FALSE;

4993
    return TRUE;
4994 4995
}

4996
HRESULT CDECL wined3d_check_depth_stencil_match(const struct wined3d *wined3d,
4997
        UINT adapter_idx, enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id,
4998
        enum wined3d_format_id render_target_format_id, enum wined3d_format_id depth_stencil_format_id)
4999
{
5000 5001
    const struct wined3d_format *rt_format;
    const struct wined3d_format *ds_format;
5002
    const struct wined3d_adapter *adapter;
5003

5004
    TRACE("wined3d %p, adapter_idx %u, device_type %s,\n"
5005 5006 5007
            "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));
5008

5009
    if (adapter_idx >= wined3d->adapter_count)
5010
        return WINED3DERR_INVALIDCALL;
5011

5012
    adapter = &wined3d->adapters[adapter_idx];
5013 5014
    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);
5015 5016
    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
    {
5017 5018
        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)))
5019
        {
5020
            TRACE("Formats match.\n");
5021 5022 5023 5024 5025
            return WINED3D_OK;
        }
    }
    else
    {
5026
        const struct wined3d_pixel_format *cfgs;
5027 5028 5029
        unsigned int cfg_count;
        unsigned int i;

5030
        cfgs = adapter->cfgs;
5031
        cfg_count = adapter->cfg_count;
5032
        for (i = 0; i < cfg_count; ++i)
5033
        {
5034 5035
            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))
5036
            {
5037
                TRACE("Formats match.\n");
5038
                return WINED3D_OK;
5039 5040
            }
        }
5041
    }
5042

5043
    TRACE("Unsupported format pair: %s and %s.\n",
5044 5045
            debug_d3dformat(render_target_format_id),
            debug_d3dformat(depth_stencil_format_id));
5046

5047
    return WINED3DERR_NOTAVAILABLE;
5048 5049
}

5050
HRESULT CDECL wined3d_check_device_multisample_type(const struct wined3d *wined3d, UINT adapter_idx,
5051
        enum wined3d_device_type device_type, enum wined3d_format_id surface_format_id, BOOL windowed,
5052
        enum wined3d_multisample_type multisample_type, DWORD *quality_levels)
5053
{
5054
    const struct wined3d_gl_info *gl_info = &wined3d->adapters[adapter_idx].gl_info;
5055
    const struct wined3d_format *format = wined3d_get_format(gl_info, surface_format_id, 0);
5056
    HRESULT hr = WINED3D_OK;
5057

5058
    TRACE("wined3d %p, adapter_idx %u, device_type %s, surface_format %s, "
5059 5060 5061
            "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);
5062

5063
    if (adapter_idx >= wined3d->adapter_count)
5064
        return WINED3DERR_INVALIDCALL;
5065 5066
    if (surface_format_id == WINED3DFMT_UNKNOWN)
        return WINED3DERR_INVALIDCALL;
5067
    if (multisample_type < WINED3D_MULTISAMPLE_NONE)
5068
        return WINED3DERR_INVALIDCALL;
5069 5070 5071 5072 5073
    if (multisample_type > WINED3D_MULTISAMPLE_16_SAMPLES)
    {
        FIXME("multisample_type %u not handled yet.\n", multisample_type);
        return WINED3DERR_NOTAVAILABLE;
    }
5074

5075 5076
    if (multisample_type && !(format->multisample_types & 1u << (multisample_type - 1)))
        hr = WINED3DERR_NOTAVAILABLE;
5077

5078
    if (SUCCEEDED(hr) || (multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE && format->multisample_types))
5079
    {
5080
        if (quality_levels)
5081 5082 5083 5084 5085 5086 5087
        {
            if (multisample_type == WINED3D_MULTISAMPLE_NON_MASKABLE)
                *quality_levels = wined3d_popcount(format->multisample_types);
            else
                *quality_levels = 1;
        }
        return WINED3D_OK;
5088 5089
    }

5090 5091
    TRACE("Returning not supported.\n");
    return hr;
5092 5093
}

5094
/* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
5095
static BOOL CheckDepthStencilCapability(const struct wined3d_adapter *adapter,
5096 5097
        const struct wined3d_format *display_format, const struct wined3d_format *ds_format,
        enum wined3d_gl_resource_type gl_type)
5098
{
5099
    /* Only allow depth/stencil formats */
5100
    if (!(ds_format->depth_size || ds_format->stencil_size)) return FALSE;
5101

5102 5103 5104 5105 5106
    /* 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:
5107
            TRACE("[FAILED] - not supported on windows.\n");
5108 5109 5110 5111 5112 5113
            return FALSE;

        default:
            break;
    }

5114 5115 5116
    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
    {
        /* With FBOs WGL limitations do not apply, but the format needs to be FBO attachable */
5117
        if (ds_format->flags[gl_type] & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))
5118
            return TRUE;
5119 5120
    }
    else
5121
    {
5122 5123
        unsigned int i;

5124
        /* Walk through all WGL pixel formats to find a match */
5125
        for (i = 0; i < adapter->cfg_count; ++i)
5126
        {
5127
            const struct wined3d_pixel_format *cfg = &adapter->cfgs[i];
5128 5129 5130
            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;
5131 5132 5133 5134 5135 5136
        }
    }

    return FALSE;
}

5137
/* Check the render target capabilities of a format */
5138
static BOOL CheckRenderTargetCapability(const struct wined3d_adapter *adapter,
5139 5140
        const struct wined3d_format *adapter_format, const struct wined3d_format *check_format,
        enum wined3d_gl_resource_type gl_type)
5141 5142
{
    /* Filter out non-RT formats */
5143
    if (!(check_format->flags[gl_type] & WINED3DFMT_FLAG_RENDERTARGET))
5144
        return FALSE;
5145 5146
    if (wined3d_settings.offscreen_rendering_mode == ORM_FBO)
        return TRUE;
5147 5148
    if (wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER)
    {
5149
        const struct wined3d_pixel_format *cfgs = adapter->cfgs;
5150
        unsigned int i;
5151

5152 5153 5154 5155 5156 5157
        /* 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)
5158 5159
        {
            TRACE("[FAILED]\n");
5160 5161 5162 5163 5164
            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) */
5165
        for (i = 0; i < adapter->cfg_count; ++i)
5166
        {
5167 5168
            if (cfgs[i].windowDrawable
                    && wined3d_check_pixel_format_color(&adapter->gl_info, &cfgs[i], check_format))
5169
            {
5170
                TRACE("Pixel format %d is compatible with format %s.\n",
5171
                        cfgs[i].iPixelFormat, debug_d3dformat(check_format->id));
5172 5173 5174
                return TRUE;
            }
        }
5175
    }
5176 5177 5178
    return FALSE;
}

5179
static BOOL wined3d_check_surface_capability(const struct wined3d_format *format, BOOL no3d)
5180
{
5181
    if (no3d)
5182
    {
5183
        switch (format->id)
5184
        {
5185
            case WINED3DFMT_B8G8R8_UNORM:
5186
                TRACE("[FAILED] - Not enumerated on Windows.\n");
5187
                return FALSE;
5188 5189 5190 5191 5192 5193 5194
            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:
5195
            case WINED3DFMT_A8_UNORM:
5196 5197
            case WINED3DFMT_B2G3R3A8_UNORM:
            case WINED3DFMT_B4G4R4X4_UNORM:
5198 5199
            case WINED3DFMT_R10G10B10A2_UNORM:
            case WINED3DFMT_R8G8B8A8_UNORM:
5200
            case WINED3DFMT_R8G8B8X8_UNORM:
5201
            case WINED3DFMT_R16G16_UNORM:
5202
            case WINED3DFMT_B10G10R10A2_UNORM:
5203
            case WINED3DFMT_R16G16B16A16_UNORM:
5204
            case WINED3DFMT_P8_UINT:
5205
                TRACE("[OK]\n");
5206 5207
                return TRUE;
            default:
5208
                TRACE("[FAILED] - Not available on GDI surfaces.\n");
5209 5210 5211 5212
                return FALSE;
        }
    }

5213
    if (format->glInternal)
5214
    {
5215
        TRACE("[OK]\n");
5216 5217 5218
        return TRUE;
    }

5219
    /* Reject other formats */
5220
    TRACE("[FAILED]\n");
5221 5222 5223
    return FALSE;
}

5224 5225 5226 5227 5228 5229 5230 5231
/* 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. */
5232
HRESULT CDECL wined3d_check_device_format(const struct wined3d *wined3d, UINT adapter_idx,
5233
        enum wined3d_device_type device_type, enum wined3d_format_id adapter_format_id, DWORD usage,
5234
        enum wined3d_resource_type resource_type, enum wined3d_format_id check_format_id)
5235
{
5236
    const struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx];
5237
    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
5238 5239 5240
    const struct wined3d_format *adapter_format = wined3d_get_format(gl_info, adapter_format_id,
            WINED3DUSAGE_RENDERTARGET);
    const struct wined3d_format *format = wined3d_get_format(gl_info, check_format_id, usage);
5241
    enum wined3d_gl_resource_type gl_type, gl_type_end;
5242 5243
    DWORD format_flags = 0;
    DWORD allowed_usage;
5244

5245
    TRACE("wined3d %p, adapter_idx %u, device_type %s, adapter_format %s, usage %s, %s, "
5246
            "resource_type %s, check_format %s.\n",
5247 5248
            wined3d, adapter_idx, debug_d3ddevicetype(device_type), debug_d3dformat(adapter_format_id),
            debug_d3dusage(usage), debug_d3dusagequery(usage), debug_d3dresourcetype(resource_type),
5249
            debug_d3dformat(check_format_id));
5250 5251

    if (adapter_idx >= wined3d->adapter_count)
5252
        return WINED3DERR_INVALIDCALL;
5253

5254 5255
    switch (resource_type)
    {
5256 5257 5258 5259 5260 5261 5262
        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;

5263
        case WINED3D_RTYPE_TEXTURE_2D:
5264 5265 5266
            allowed_usage = WINED3DUSAGE_DEPTHSTENCIL
                    | WINED3DUSAGE_RENDERTARGET
                    | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
5267 5268
            if (usage & WINED3DUSAGE_RENDERTARGET)
                allowed_usage |= WINED3DUSAGE_QUERY_SRGBWRITE;
5269 5270
            if (!(usage & WINED3DUSAGE_TEXTURE))
            {
5271
                if (!wined3d_check_surface_capability(format, wined3d->flags & WINED3D_NO3D))
5272 5273 5274 5275
                {
                    TRACE("[FAILED] - Not supported for plain surfaces.\n");
                    return WINED3DERR_NOTAVAILABLE;
                }
5276

5277
                gl_type = gl_type_end = WINED3D_GL_RES_TYPE_RB;
5278 5279 5280
                break;
            }
            allowed_usage |= WINED3DUSAGE_AUTOGENMIPMAP
5281
                    | WINED3DUSAGE_DYNAMIC
5282
                    | WINED3DUSAGE_LEGACY_CUBEMAP
5283
                    | WINED3DUSAGE_SOFTWAREPROCESSING
5284
                    | WINED3DUSAGE_TEXTURE
5285 5286 5287 5288 5289 5290
                    | WINED3DUSAGE_QUERY_FILTER
                    | WINED3DUSAGE_QUERY_LEGACYBUMPMAP
                    | WINED3DUSAGE_QUERY_SRGBREAD
                    | WINED3DUSAGE_QUERY_SRGBWRITE
                    | WINED3DUSAGE_QUERY_VERTEXTEXTURE
                    | WINED3DUSAGE_QUERY_WRAPANDMIP;
5291
            gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_2D;
5292 5293 5294
            if (usage & WINED3DUSAGE_LEGACY_CUBEMAP)
            {
                allowed_usage &= ~(WINED3DUSAGE_DEPTHSTENCIL | WINED3DUSAGE_QUERY_LEGACYBUMPMAP);
5295
                gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_CUBE;
5296 5297 5298 5299 5300 5301 5302 5303
            }
            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;
            }
5304
            break;
5305

5306
        case WINED3D_RTYPE_TEXTURE_3D:
5307 5308
            allowed_usage = WINED3DUSAGE_DYNAMIC
                    | WINED3DUSAGE_SOFTWAREPROCESSING
5309
                    | WINED3DUSAGE_TEXTURE
5310 5311 5312 5313 5314 5315
                    | WINED3DUSAGE_QUERY_FILTER
                    | WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING
                    | WINED3DUSAGE_QUERY_SRGBREAD
                    | WINED3DUSAGE_QUERY_SRGBWRITE
                    | WINED3DUSAGE_QUERY_VERTEXTEXTURE
                    | WINED3DUSAGE_QUERY_WRAPANDMIP;
5316
            gl_type = gl_type_end = WINED3D_GL_RES_TYPE_TEX_3D;
5317
            break;
5318

5319 5320 5321 5322
        default:
            FIXME("Unhandled resource type %s.\n", debug_d3dresourcetype(resource_type));
            return WINED3DERR_NOTAVAILABLE;
    }
5323

5324 5325 5326 5327 5328 5329
    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;
    }
5330

5331 5332
    if (usage & WINED3DUSAGE_TEXTURE)
        format_flags |= WINED3DFMT_FLAG_TEXTURE;
5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344
    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;
5345

5346 5347 5348 5349 5350
    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;
    }
5351

5352
    if ((usage & WINED3DUSAGE_AUTOGENMIPMAP) && !gl_info->supported[SGIS_GENERATE_MIPMAP])
5353
    {
5354 5355
        TRACE("No WINED3DUSAGE_AUTOGENMIPMAP support, returning WINED3DOK_NOAUTOGEN.\n");
        return WINED3DOK_NOAUTOGEN;
5356
    }
5357

5358
    for (; gl_type <= gl_type_end; ++gl_type)
5359
    {
5360 5361 5362 5363 5364 5365
        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;
        }
5366

5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385
        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;
        }
5386
    }
5387

5388
    return WINED3D_OK;
5389 5390
}

5391 5392 5393 5394
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;
5395
    unsigned int row_pitch, slice_pitch;
5396 5397 5398 5399 5400 5401 5402 5403

    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;
5404
    wined3d_format_calculate_pitch(wined3d_get_format(gl_info, format_id, 0),
5405 5406 5407
            1, width, 1, &row_pitch, &slice_pitch);

    return row_pitch;
5408 5409
}

5410
HRESULT CDECL wined3d_check_device_format_conversion(const struct wined3d *wined3d, UINT adapter_idx,
5411
        enum wined3d_device_type device_type, enum wined3d_format_id src_format, enum wined3d_format_id dst_format)
5412
{
5413 5414
    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),
5415
            debug_d3dformat(dst_format));
5416

5417
    return WINED3D_OK;
5418 5419
}

5420 5421 5422
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)
5423
{
5424
    BOOL present_conversion = wined3d->flags & WINED3D_PRESENT_CONVERSION;
5425

5426 5427
    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),
5428 5429
            debug_d3dformat(backbuffer_format), windowed);

5430
    if (adapter_idx >= wined3d->adapter_count)
5431 5432 5433 5434 5435 5436
        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.
5437
     * In windowed mode format conversion can occur and this depends on the driver. */
5438 5439 5440 5441 5442 5443 5444

    /* 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))
    {
5445
        TRACE("Format %s is not supported as display format.\n", debug_d3dformat(display_format));
5446 5447 5448
        return WINED3DERR_NOTAVAILABLE;
    }

5449
    if (!windowed)
5450
    {
5451 5452 5453
        /* 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))
5454
        {
5455
            TRACE("No available modes for display format %s.\n", debug_d3dformat(display_format));
5456 5457
            return WINED3DERR_NOTAVAILABLE;
        }
5458

5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472
        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. */
5473 5474
        if (backbuffer_format == WINED3DFMT_UNKNOWN)
            backbuffer_format = display_format;
5475

5476 5477
        if (FAILED(wined3d_check_device_format_conversion(wined3d, adapter_idx,
                device_type, backbuffer_format, display_format)))
5478
        {
5479 5480
            TRACE("Format conversion from %s to %s not supported.\n",
                    debug_d3dformat(backbuffer_format), debug_d3dformat(display_format));
5481 5482
            return WINED3DERR_NOTAVAILABLE;
        }
5483
    }
5484
    else
5485
    {
5486 5487 5488
        /* When format conversion from the back buffer format to the display
         * format is not allowed, only a limited number of combinations are
         * valid. */
5489

5490 5491
        if (display_format == WINED3DFMT_B5G6R5_UNORM && backbuffer_format != WINED3DFMT_B5G6R5_UNORM)
        {
5492
            TRACE("Unsupported format combination %s / %s.\n",
5493 5494 5495 5496 5497 5498 5499
                    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))
        {
5500
            TRACE("Unsupported format combination %s / %s.\n",
5501 5502 5503 5504 5505 5506 5507
                    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))
        {
5508
            TRACE("Unsupported format combination %s / %s.\n",
5509 5510 5511 5512 5513 5514 5515
                    debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
            return WINED3DERR_NOTAVAILABLE;
        }

        if (display_format == WINED3DFMT_B10G10R10A2_UNORM
                && backbuffer_format != WINED3DFMT_B10G10R10A2_UNORM)
        {
5516
            TRACE("Unsupported format combination %s / %s.\n",
5517 5518 5519
                    debug_d3dformat(display_format), debug_d3dformat(backbuffer_format));
            return WINED3DERR_NOTAVAILABLE;
        }
5520 5521
    }

5522 5523
    /* Validate that the back buffer format is usable for render targets. */
    if (FAILED(wined3d_check_device_format(wined3d, adapter_idx, device_type, display_format,
5524
            WINED3DUSAGE_RENDERTARGET, WINED3D_RTYPE_TEXTURE_2D, backbuffer_format)))
5525 5526 5527 5528
    {
        TRACE("Format %s not allowed for render targets.\n", debug_d3dformat(backbuffer_format));
        return WINED3DERR_NOTAVAILABLE;
    }
5529

5530
    return WINED3D_OK;
5531 5532
}

5533
HRESULT CDECL wined3d_get_device_caps(const struct wined3d *wined3d, UINT adapter_idx,
5534
        enum wined3d_device_type device_type, WINED3DCAPS *caps)
5535 5536
{
    const struct wined3d_adapter *adapter = &wined3d->adapters[adapter_idx];
5537
    const struct wined3d_d3d_info *d3d_info = &adapter->d3d_info;
5538
    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
5539
    struct wined3d_vertex_caps vertex_caps;
5540
    DWORD ckey_caps, blit_caps, fx_caps;
5541 5542
    struct fragment_caps fragment_caps;
    struct shader_caps shader_caps;
5543

5544
    TRACE("wined3d %p, adapter_idx %u, device_type %s, caps %p.\n",
5545
            wined3d, adapter_idx, debug_d3ddevicetype(device_type), caps);
5546

5547
    if (adapter_idx >= wined3d->adapter_count)
5548
        return WINED3DERR_INVALIDCALL;
5549

5550
    caps->DeviceType = (device_type == WINED3D_DEVICE_TYPE_HAL) ? WINED3D_DEVICE_TYPE_HAL : WINED3D_DEVICE_TYPE_REF;
5551
    caps->AdapterOrdinal           = adapter_idx;
5552

5553 5554
    caps->Caps                     = 0;
    caps->Caps2                    = WINED3DCAPS2_CANRENDERWINDOWED |
5555 5556
                                     WINED3DCAPS2_FULLSCREENGAMMA |
                                     WINED3DCAPS2_DYNAMICTEXTURES;
5557
    if (gl_info->supported[SGIS_GENERATE_MIPMAP])
5558
        caps->Caps2 |= WINED3DCAPS2_CANAUTOGENMIPMAP;
5559

5560
    caps->Caps3                    = WINED3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD |
5561 5562 5563
                                     WINED3DCAPS3_COPY_TO_VIDMEM                   |
                                     WINED3DCAPS3_COPY_TO_SYSTEMMEM;

5564
    caps->PresentationIntervals    = WINED3DPRESENT_INTERVAL_IMMEDIATE  |
5565 5566
                                     WINED3DPRESENT_INTERVAL_ONE;

5567
    caps->CursorCaps               = WINED3DCURSORCAPS_COLOR            |
5568 5569
                                     WINED3DCURSORCAPS_LOWRES;

5570
    caps->DevCaps                  = WINED3DDEVCAPS_FLOATTLVERTEX       |
5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582
                                     WINED3DDEVCAPS_EXECUTESYSTEMMEMORY |
                                     WINED3DDEVCAPS_TLVERTEXSYSTEMMEMORY|
                                     WINED3DDEVCAPS_TLVERTEXVIDEOMEMORY |
                                     WINED3DDEVCAPS_DRAWPRIMTLVERTEX    |
                                     WINED3DDEVCAPS_HWTRANSFORMANDLIGHT |
                                     WINED3DDEVCAPS_EXECUTEVIDEOMEMORY  |
                                     WINED3DDEVCAPS_PUREDEVICE          |
                                     WINED3DDEVCAPS_HWRASTERIZATION     |
                                     WINED3DDEVCAPS_TEXTUREVIDEOMEMORY  |
                                     WINED3DDEVCAPS_TEXTURESYSTEMMEMORY |
                                     WINED3DDEVCAPS_CANRENDERAFTERFLIP  |
                                     WINED3DDEVCAPS_DRAWPRIMITIVES2     |
5583
                                     WINED3DDEVCAPS_DRAWPRIMITIVES2EX;
5584

5585
    caps->PrimitiveMiscCaps        = WINED3DPMISCCAPS_CULLNONE              |
5586 5587 5588 5589 5590 5591
                                     WINED3DPMISCCAPS_CULLCCW               |
                                     WINED3DPMISCCAPS_CULLCW                |
                                     WINED3DPMISCCAPS_COLORWRITEENABLE      |
                                     WINED3DPMISCCAPS_CLIPTLVERTS           |
                                     WINED3DPMISCCAPS_CLIPPLANESCALEDPOINTS |
                                     WINED3DPMISCCAPS_MASKZ                 |
5592
                                     WINED3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING;
5593
                                    /* TODO:
5594 5595 5596 5597
                                        WINED3DPMISCCAPS_NULLREFERENCE
                                        WINED3DPMISCCAPS_FOGANDSPECULARALPHA
                                        WINED3DPMISCCAPS_MRTINDEPENDENTBITDEPTHS
                                        WINED3DPMISCCAPS_FOGVERTEXCLAMPED */
5598

5599 5600
    if (gl_info->supported[WINED3D_GL_BLEND_EQUATION])
        caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_BLENDOP;
5601
    if (gl_info->supported[EXT_BLEND_EQUATION_SEPARATE] && gl_info->supported[EXT_BLEND_FUNC_SEPARATE])
5602
        caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_SEPARATEALPHABLEND;
5603
    if (gl_info->supported[EXT_DRAW_BUFFERS2])
5604
        caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_INDEPENDENTWRITEMASKS;
5605 5606
    if (gl_info->supported[ARB_FRAMEBUFFER_SRGB])
        caps->PrimitiveMiscCaps |= WINED3DPMISCCAPS_POSTBLENDSRGBCONVERT;
5607

5608
    caps->RasterCaps               = WINED3DPRASTERCAPS_DITHER    |
5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619
                                     WINED3DPRASTERCAPS_PAT       |
                                     WINED3DPRASTERCAPS_WFOG      |
                                     WINED3DPRASTERCAPS_ZFOG      |
                                     WINED3DPRASTERCAPS_FOGVERTEX |
                                     WINED3DPRASTERCAPS_FOGTABLE  |
                                     WINED3DPRASTERCAPS_STIPPLE   |
                                     WINED3DPRASTERCAPS_SUBPIXEL  |
                                     WINED3DPRASTERCAPS_ZTEST     |
                                     WINED3DPRASTERCAPS_SCISSORTEST   |
                                     WINED3DPRASTERCAPS_SLOPESCALEDEPTHBIAS |
                                     WINED3DPRASTERCAPS_DEPTHBIAS;
5620

5621 5622
    if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
    {
5623
        caps->RasterCaps  |= WINED3DPRASTERCAPS_ANISOTROPY    |
5624 5625
                             WINED3DPRASTERCAPS_ZBIAS         |
                             WINED3DPRASTERCAPS_MIPMAPLODBIAS;
5626
    }
5627

5628
    caps->ZCmpCaps =  WINED3DPCMPCAPS_ALWAYS       |
5629 5630 5631 5632 5633 5634 5635 5636
                      WINED3DPCMPCAPS_EQUAL        |
                      WINED3DPCMPCAPS_GREATER      |
                      WINED3DPCMPCAPS_GREATEREQUAL |
                      WINED3DPCMPCAPS_LESS         |
                      WINED3DPCMPCAPS_LESSEQUAL    |
                      WINED3DPCMPCAPS_NEVER        |
                      WINED3DPCMPCAPS_NOTEQUAL;

5637 5638
    /* WINED3DPBLENDCAPS_BOTHINVSRCALPHA and WINED3DPBLENDCAPS_BOTHSRCALPHA
     * are legacy settings for srcblend only. */
5639
    caps->SrcBlendCaps  =  WINED3DPBLENDCAPS_BOTHINVSRCALPHA |
5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652
                           WINED3DPBLENDCAPS_BOTHSRCALPHA    |
                           WINED3DPBLENDCAPS_DESTALPHA       |
                           WINED3DPBLENDCAPS_DESTCOLOR       |
                           WINED3DPBLENDCAPS_INVDESTALPHA    |
                           WINED3DPBLENDCAPS_INVDESTCOLOR    |
                           WINED3DPBLENDCAPS_INVSRCALPHA     |
                           WINED3DPBLENDCAPS_INVSRCCOLOR     |
                           WINED3DPBLENDCAPS_ONE             |
                           WINED3DPBLENDCAPS_SRCALPHA        |
                           WINED3DPBLENDCAPS_SRCALPHASAT     |
                           WINED3DPBLENDCAPS_SRCCOLOR        |
                           WINED3DPBLENDCAPS_ZERO;

5653
    caps->DestBlendCaps =  WINED3DPBLENDCAPS_DESTALPHA       |
5654 5655 5656 5657 5658 5659 5660 5661 5662
                           WINED3DPBLENDCAPS_DESTCOLOR       |
                           WINED3DPBLENDCAPS_INVDESTALPHA    |
                           WINED3DPBLENDCAPS_INVDESTCOLOR    |
                           WINED3DPBLENDCAPS_INVSRCALPHA     |
                           WINED3DPBLENDCAPS_INVSRCCOLOR     |
                           WINED3DPBLENDCAPS_ONE             |
                           WINED3DPBLENDCAPS_SRCALPHA        |
                           WINED3DPBLENDCAPS_SRCCOLOR        |
                           WINED3DPBLENDCAPS_ZERO;
5663 5664 5665

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

5667 5668
    if (gl_info->supported[EXT_BLEND_COLOR])
    {
5669 5670
        caps->SrcBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
        caps->DestBlendCaps |= WINED3DPBLENDCAPS_BLENDFACTOR;
5671 5672 5673
    }


5674
    caps->AlphaCmpCaps  = WINED3DPCMPCAPS_ALWAYS       |
5675 5676 5677 5678 5679 5680 5681 5682
                          WINED3DPCMPCAPS_EQUAL        |
                          WINED3DPCMPCAPS_GREATER      |
                          WINED3DPCMPCAPS_GREATEREQUAL |
                          WINED3DPCMPCAPS_LESS         |
                          WINED3DPCMPCAPS_LESSEQUAL    |
                          WINED3DPCMPCAPS_NEVER        |
                          WINED3DPCMPCAPS_NOTEQUAL;

5683
    caps->ShadeCaps      = WINED3DPSHADECAPS_SPECULARGOURAUDRGB |
5684 5685 5686 5687 5688 5689 5690 5691
                           WINED3DPSHADECAPS_COLORGOURAUDRGB    |
                           WINED3DPSHADECAPS_ALPHAFLATBLEND     |
                           WINED3DPSHADECAPS_ALPHAGOURAUDBLEND  |
                           WINED3DPSHADECAPS_COLORFLATRGB       |
                           WINED3DPSHADECAPS_FOGFLAT            |
                           WINED3DPSHADECAPS_FOGGOURAUD         |
                           WINED3DPSHADECAPS_SPECULARFLATRGB;

5692
    caps->TextureCaps   = WINED3DPTEXTURECAPS_ALPHA              |
5693
                          WINED3DPTEXTURECAPS_ALPHAPALETTE       |
5694
                          WINED3DPTEXTURECAPS_TRANSPARENCY       |
5695 5696 5697 5698
                          WINED3DPTEXTURECAPS_BORDER             |
                          WINED3DPTEXTURECAPS_MIPMAP             |
                          WINED3DPTEXTURECAPS_PROJECTED          |
                          WINED3DPTEXTURECAPS_PERSPECTIVE;
5699

5700 5701
    if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
    {
5702 5703 5704
        caps->TextureCaps |= WINED3DPTEXTURECAPS_POW2;
        if (gl_info->supported[WINED3D_GL_NORMALIZED_TEXRECT] || gl_info->supported[ARB_TEXTURE_RECTANGLE])
            caps->TextureCaps |= WINED3DPTEXTURECAPS_NONPOW2CONDITIONAL;
5705
    }
5706

5707 5708
    if (gl_info->supported[EXT_TEXTURE3D])
    {
5709
        caps->TextureCaps  |=  WINED3DPTEXTURECAPS_VOLUMEMAP      |
5710 5711 5712
                               WINED3DPTEXTURECAPS_MIPVOLUMEMAP;
        if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
        {
5713
            caps->TextureCaps |= WINED3DPTEXTURECAPS_VOLUMEMAP_POW2;
5714
        }
5715 5716
    }

5717 5718
    if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
    {
5719
        caps->TextureCaps  |= WINED3DPTEXTURECAPS_CUBEMAP     |
5720 5721 5722
                              WINED3DPTEXTURECAPS_MIPCUBEMAP;
        if (!gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO])
        {
5723
            caps->TextureCaps |= WINED3DPTEXTURECAPS_CUBEMAP_POW2;
5724
        }
5725 5726
    }

5727
    caps->TextureFilterCaps =  WINED3DPTFILTERCAPS_MAGFLINEAR       |
5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738
                               WINED3DPTFILTERCAPS_MAGFPOINT        |
                               WINED3DPTFILTERCAPS_MINFLINEAR       |
                               WINED3DPTFILTERCAPS_MINFPOINT        |
                               WINED3DPTFILTERCAPS_MIPFLINEAR       |
                               WINED3DPTFILTERCAPS_MIPFPOINT        |
                               WINED3DPTFILTERCAPS_LINEAR           |
                               WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
                               WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
                               WINED3DPTFILTERCAPS_MIPLINEAR        |
                               WINED3DPTFILTERCAPS_MIPNEAREST       |
                               WINED3DPTFILTERCAPS_NEAREST;
5739

5740 5741
    if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
    {
5742
        caps->TextureFilterCaps  |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
5743
                                    WINED3DPTFILTERCAPS_MINFANISOTROPIC;
5744 5745
    }

5746 5747
    if (gl_info->supported[ARB_TEXTURE_CUBE_MAP])
    {
5748
        caps->CubeTextureFilterCaps =  WINED3DPTFILTERCAPS_MAGFLINEAR       |
5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759
                                       WINED3DPTFILTERCAPS_MAGFPOINT        |
                                       WINED3DPTFILTERCAPS_MINFLINEAR       |
                                       WINED3DPTFILTERCAPS_MINFPOINT        |
                                       WINED3DPTFILTERCAPS_MIPFLINEAR       |
                                       WINED3DPTFILTERCAPS_MIPFPOINT        |
                                       WINED3DPTFILTERCAPS_LINEAR           |
                                       WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
                                       WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
                                       WINED3DPTFILTERCAPS_MIPLINEAR        |
                                       WINED3DPTFILTERCAPS_MIPNEAREST       |
                                       WINED3DPTFILTERCAPS_NEAREST;
5760

5761 5762
        if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC])
        {
5763
            caps->CubeTextureFilterCaps  |= WINED3DPTFILTERCAPS_MAGFANISOTROPIC |
5764 5765
                                            WINED3DPTFILTERCAPS_MINFANISOTROPIC;
        }
5766 5767 5768 5769 5770
    }
    else
    {
        caps->CubeTextureFilterCaps = 0;
    }
5771

5772 5773
    if (gl_info->supported[EXT_TEXTURE3D])
    {
5774
        caps->VolumeTextureFilterCaps  = WINED3DPTFILTERCAPS_MAGFLINEAR       |
5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785
                                         WINED3DPTFILTERCAPS_MAGFPOINT        |
                                         WINED3DPTFILTERCAPS_MINFLINEAR       |
                                         WINED3DPTFILTERCAPS_MINFPOINT        |
                                         WINED3DPTFILTERCAPS_MIPFLINEAR       |
                                         WINED3DPTFILTERCAPS_MIPFPOINT        |
                                         WINED3DPTFILTERCAPS_LINEAR           |
                                         WINED3DPTFILTERCAPS_LINEARMIPLINEAR  |
                                         WINED3DPTFILTERCAPS_LINEARMIPNEAREST |
                                         WINED3DPTFILTERCAPS_MIPLINEAR        |
                                         WINED3DPTFILTERCAPS_MIPNEAREST       |
                                         WINED3DPTFILTERCAPS_NEAREST;
5786 5787 5788 5789 5790
    }
    else
    {
        caps->VolumeTextureFilterCaps = 0;
    }
5791

5792
    caps->TextureAddressCaps  =  WINED3DPTADDRESSCAPS_INDEPENDENTUV |
5793 5794
                                 WINED3DPTADDRESSCAPS_CLAMP  |
                                 WINED3DPTADDRESSCAPS_WRAP;
5795

5796 5797
    if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
    {
5798
        caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
5799
    }
5800 5801
    if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
    {
5802
        caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
5803
    }
5804
    if (gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE])
5805
    {
5806
        caps->TextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
5807 5808
    }

5809 5810
    if (gl_info->supported[EXT_TEXTURE3D])
    {
5811
        caps->VolumeTextureAddressCaps =   WINED3DPTADDRESSCAPS_INDEPENDENTUV |
5812 5813
                                           WINED3DPTADDRESSCAPS_CLAMP  |
                                           WINED3DPTADDRESSCAPS_WRAP;
5814 5815
        if (gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
        {
5816
            caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_BORDER;
5817
        }
5818 5819
        if (gl_info->supported[ARB_TEXTURE_MIRRORED_REPEAT])
        {
5820
            caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRROR;
5821
        }
5822
        if (gl_info->supported[ARB_TEXTURE_MIRROR_CLAMP_TO_EDGE])
5823
        {
5824
            caps->VolumeTextureAddressCaps |= WINED3DPTADDRESSCAPS_MIRRORONCE;
5825
        }
5826 5827 5828 5829 5830
    }
    else
    {
        caps->VolumeTextureAddressCaps = 0;
    }
5831

5832
    caps->LineCaps  = WINED3DLINECAPS_TEXTURE       |
5833 5834 5835 5836 5837 5838 5839
                      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
     */
5840

5841 5842
    caps->MaxTextureWidth = gl_info->limits.texture_size;
    caps->MaxTextureHeight = gl_info->limits.texture_size;
5843

5844
    if (gl_info->supported[EXT_TEXTURE3D])
5845
        caps->MaxVolumeExtent = gl_info->limits.texture3d_size;
5846
    else
5847
        caps->MaxVolumeExtent = 0;
5848

5849 5850 5851
    caps->MaxTextureRepeat = 32768;
    caps->MaxTextureAspectRatio = gl_info->limits.texture_size;
    caps->MaxVertexW = 1.0f;
5852

5853 5854 5855 5856
    caps->GuardBandLeft = 0.0f;
    caps->GuardBandTop = 0.0f;
    caps->GuardBandRight = 0.0f;
    caps->GuardBandBottom = 0.0f;
5857

5858
    caps->ExtentsAdjust = 0.0f;
5859

5860
    caps->StencilCaps   = WINED3DSTENCILCAPS_DECRSAT |
5861 5862 5863 5864 5865
                          WINED3DSTENCILCAPS_INCRSAT |
                          WINED3DSTENCILCAPS_INVERT  |
                          WINED3DSTENCILCAPS_KEEP    |
                          WINED3DSTENCILCAPS_REPLACE |
                          WINED3DSTENCILCAPS_ZERO;
5866 5867
    if (gl_info->supported[EXT_STENCIL_WRAP])
    {
5868
        caps->StencilCaps |= WINED3DSTENCILCAPS_DECR  |
5869
                              WINED3DSTENCILCAPS_INCR;
5870
    }
5871 5872
    if (gl_info->supported[WINED3D_GL_VERSION_2_0] || gl_info->supported[EXT_STENCIL_TWO_SIDE]
            || gl_info->supported[ATI_SEPARATE_STENCIL])
5873
    {
5874
        caps->StencilCaps |= WINED3DSTENCILCAPS_TWOSIDED;
5875
    }
5876

5877 5878
    caps->MaxAnisotropy = gl_info->limits.anisotropy;
    caps->MaxPointSize = gl_info->limits.pointsize_max;
5879

5880 5881
    caps->MaxPrimitiveCount   = 0x555555; /* Taken from an AMD Radeon HD 5700 (Evergreen) GPU. */
    caps->MaxVertexIndex      = 0xffffff; /* Taken from an AMD Radeon HD 5700 (Evergreen) GPU. */
5882 5883
    caps->MaxStreams          = MAX_STREAMS;
    caps->MaxStreamStride     = 1024;
5884

5885
    /* d3d9.dll sets D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES here because StretchRects is implemented in d3d9 */
5886 5887 5888 5889 5890 5891
    caps->DevCaps2                          = WINED3DDEVCAPS2_STREAMOFFSET |
                                              WINED3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET;
    caps->MaxNpatchTessellationLevel        = 0;
    caps->MasterAdapterOrdinal              = 0;
    caps->AdapterOrdinalInGroup             = 0;
    caps->NumberOfAdaptersInGroup           = 1;
5892

5893
    caps->NumSimultaneousRTs = gl_info->limits.buffers;
5894

5895
    caps->StretchRectFilterCaps               = WINED3DPTFILTERCAPS_MINFPOINT  |
5896 5897 5898
                                                WINED3DPTFILTERCAPS_MAGFPOINT  |
                                                WINED3DPTFILTERCAPS_MINFLINEAR |
                                                WINED3DPTFILTERCAPS_MAGFLINEAR;
5899
    caps->VertexTextureFilterCaps             = 0;
5900

5901
    adapter->shader_backend->shader_get_caps(&adapter->gl_info, &shader_caps);
5902
    adapter->fragment_pipe->get_caps(&adapter->gl_info, &fragment_caps);
5903
    adapter->vertex_pipe->vp_get_caps(&adapter->gl_info, &vertex_caps);
5904

5905
    /* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
5906
    caps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps;
5907

5908 5909
    caps->VertexShaderVersion = shader_caps.vs_version;
    caps->MaxVertexShaderConst = shader_caps.vs_uniform_count;
5910

5911 5912
    caps->PixelShaderVersion = shader_caps.ps_version;
    caps->PixelShader1xMaxValue = shader_caps.ps_1x_max_value;
5913

5914 5915 5916
    caps->TextureOpCaps                    = fragment_caps.TextureOpCaps;
    caps->MaxTextureBlendStages            = fragment_caps.MaxTextureBlendStages;
    caps->MaxSimultaneousTextures          = fragment_caps.MaxSimultaneousTextures;
5917

5918 5919 5920 5921 5922 5923 5924 5925
    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;

5926 5927 5928 5929
    /* 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
     */
5930
    if (caps->VertexShaderVersion >= 3)
5931 5932 5933 5934 5935
    {
        /* 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. */
5936
        caps->VS20Caps.caps = WINED3DVS20CAPS_PREDICATION;
5937
        /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
5938 5939
        caps->VS20Caps.dynamic_flow_control_depth = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH;
        caps->VS20Caps.temp_count = max(32, adapter->gl_info.limits.arb_vs_temps);
5940
        /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
5941
        caps->VS20Caps.static_flow_control_depth = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH;
5942 5943 5944

        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);
5945
        caps->VertexTextureFilterCaps = WINED3DPTFILTERCAPS_MINFPOINT | WINED3DPTFILTERCAPS_MAGFPOINT;
5946
    }
5947
    else if (caps->VertexShaderVersion == 2)
5948
    {
5949 5950 5951 5952
        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;
5953 5954 5955 5956 5957 5958

        caps->MaxVShaderInstructionsExecuted    = 65535;
        caps->MaxVertexShader30InstructionSlots = 0;
    }
    else
    { /* VS 1.x */
5959 5960 5961 5962
        caps->VS20Caps.caps = 0;
        caps->VS20Caps.dynamic_flow_control_depth = 0;
        caps->VS20Caps.temp_count = 0;
        caps->VS20Caps.static_flow_control_depth = 0;
5963 5964 5965 5966 5967

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

5968
    if (caps->PixelShaderVersion >= 3)
5969 5970 5971 5972 5973 5974 5975 5976 5977
    {
        /* 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 */
5978
        caps->PS20Caps.caps = WINED3DPS20CAPS_ARBITRARYSWIZZLE |
5979 5980 5981 5982
                WINED3DPS20CAPS_GRADIENTINSTRUCTIONS |
                WINED3DPS20CAPS_PREDICATION          |
                WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
                WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
5983
        /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
5984 5985
        caps->PS20Caps.dynamic_flow_control_depth = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH;
        caps->PS20Caps.temp_count = max(32, adapter->gl_info.limits.arb_ps_temps);
5986
        /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
5987
        caps->PS20Caps.static_flow_control_depth = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH;
5988
        /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
5989
        caps->PS20Caps.instruction_slot_count = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS;
5990 5991 5992

        caps->MaxPShaderInstructionsExecuted = 65535;
        caps->MaxPixelShader30InstructionSlots = max(WINED3DMIN30SHADERINSTRUCTIONS,
5993 5994
                adapter->gl_info.limits.arb_ps_instructions);
    }
5995
    else if(caps->PixelShaderVersion == 2)
5996
    {
5997
        /* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
5998 5999 6000 6001
        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 */
6002
        /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
6003
        caps->PS20Caps.instruction_slot_count = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS;
6004 6005 6006 6007 6008 6009

        caps->MaxPShaderInstructionsExecuted    = 512; /* Minimum value, a GeforceFX uses 1024 */
        caps->MaxPixelShader30InstructionSlots  = 0;
    }
    else /* PS 1.x */
    {
6010 6011 6012 6013 6014
        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;
6015 6016 6017 6018 6019

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

6020
    if (caps->VertexShaderVersion >= 2)
6021
    {
6022 6023 6024 6025 6026 6027 6028
        /* 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 */
6029 6030 6031 6032
        caps->DeclTypes = WINED3DDTCAPS_UBYTE4    |
                          WINED3DDTCAPS_UBYTE4N   |
                          WINED3DDTCAPS_SHORT2N   |
                          WINED3DDTCAPS_SHORT4N;
6033 6034
        if (gl_info->supported[ARB_HALF_FLOAT_VERTEX])
        {
6035 6036
            caps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 |
                               WINED3DDTCAPS_FLOAT16_4;
6037
        }
6038 6039 6040 6041 6042
    }
    else
    {
        caps->DeclTypes = 0;
    }
6043

6044 6045 6046 6047 6048 6049 6050 6051 6052 6053
    /* 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             |
6054
                                        WINEDDFXCAPS_BLTSHRINKYN            |
6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066
                                        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                 |
6067
                                        WINEDDCAPS_COLORKEYHWASSIST;
6068 6069

    /* Fill the ddraw caps structure */
6070
    caps->ddraw_caps.caps =             WINEDDCAPS_GDI                      |
6071
                                        WINEDDCAPS_PALETTE                  |
6072
                                        blit_caps;
6073 6074 6075 6076
    caps->ddraw_caps.caps2 =            WINEDDCAPS2_CERTIFIED               |
                                        WINEDDCAPS2_NOPAGELOCKREQUIRED      |
                                        WINEDDCAPS2_PRIMARYGAMMA            |
                                        WINEDDCAPS2_WIDESURFACES            |
6077
                                        WINEDDCAPS2_CANRENDERWINDOWED;
6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090
    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                   |
6091 6092 6093 6094 6095 6096 6097 6098
                                        WINEDDSCAPS_BACKBUFFER              |
                                        WINEDDSCAPS_FLIP                    |
                                        WINEDDSCAPS_FRONTBUFFER             |
                                        WINEDDSCAPS_OFFSCREENPLAIN          |
                                        WINEDDSCAPS_PALETTE                 |
                                        WINEDDSCAPS_PRIMARYSURFACE          |
                                        WINEDDSCAPS_SYSTEMMEMORY            |
                                        WINEDDSCAPS_VIDEOMEMORY             |
6099 6100
                                        WINEDDSCAPS_VISIBLE;

6101
    if (!(wined3d->flags & WINED3D_NO3D))
6102
    {
6103
        caps->ddraw_caps.dds_caps |=    WINEDDSCAPS_3DDEVICE                |
6104 6105 6106
                                        WINEDDSCAPS_MIPMAP                  |
                                        WINEDDSCAPS_TEXTURE                 |
                                        WINEDDSCAPS_ZBUFFER;
6107
        caps->ddraw_caps.caps |=        WINEDDCAPS_3D;
6108 6109
    }

6110 6111
    caps->shader_double_precision = d3d_info->shader_double_precision;

6112
    return WINED3D_OK;
6113 6114
}

6115
HRESULT CDECL wined3d_device_create(struct wined3d *wined3d, UINT adapter_idx, enum wined3d_device_type device_type,
6116 6117
        HWND focus_window, DWORD flags, BYTE surface_alignment, struct wined3d_device_parent *device_parent,
        struct wined3d_device **device)
6118
{
6119
    struct wined3d_device *object;
6120
    HRESULT hr;
6121

Andrey Gusev's avatar
Andrey Gusev committed
6122 6123
    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);
6124

6125
    /* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
6126
     * number and create a device without a 3D adapter for 2D only operation. */
6127
    if (wined3d->adapter_count && adapter_idx >= wined3d->adapter_count)
6128
        return WINED3DERR_INVALIDCALL;
6129

6130 6131 6132
    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
    if (!object)
        return E_OUTOFMEMORY;
6133

6134 6135
    hr = device_init(object, wined3d, adapter_idx, device_type,
            focus_window, flags, surface_alignment, device_parent);
6136 6137 6138
    if (FAILED(hr))
    {
        WARN("Failed to initialize device, hr %#x.\n", hr);
6139 6140 6141
        HeapFree(GetProcessHeap(), 0, object);
        return hr;
    }
6142

6143
    TRACE("Created device %p.\n", object);
6144
    *device = object;
6145

6146
    device_parent->ops->wined3d_device_created(device_parent, *device);
6147

6148 6149
    return WINED3D_OK;
}
6150

6151 6152
static void WINE_GLAPI invalid_func(const void *data)
{
6153
    ERR("Invalid vertex attribute function called.\n");
6154 6155 6156
    DebugBreak();
}

6157 6158
static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data)
{
6159
    ERR("Invalid texcoord function called.\n");
6160 6161 6162
    DebugBreak();
}

6163 6164 6165 6166 6167 6168
static void WINE_GLAPI invalid_generic_attrib_func(GLuint idx, const void *data)
{
    ERR("Invalid attribute function called.\n");
    DebugBreak();
}

6169 6170 6171
/* 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(). */
6172 6173 6174
static void WINE_GLAPI position_d3dcolor(const void *data)
{
    DWORD pos = *((const DWORD *)data);
6175

6176
    FIXME("Add a test for fixed function position from d3dcolor type.\n");
6177 6178 6179 6180
    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));
6181
}
6182 6183 6184 6185

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

6187
    if (pos[3] != 0.0f && pos[3] != 1.0f)
6188
    {
6189
        float w = 1.0f / pos[3];
6190

6191
        context_get_current()->gl_info->gl_ops.gl.p_glVertex4f(pos[0] * w, pos[1] * w, pos[2] * w, w);
6192
    }
6193 6194
    else
    {
6195
        context_get_current()->gl_info->gl_ops.gl.p_glVertex3fv(pos);
6196
    }
6197 6198
}

6199 6200 6201
static void WINE_GLAPI diffuse_d3dcolor(const void *data)
{
    DWORD diffuseColor = *((const DWORD *)data);
6202

6203 6204 6205 6206
    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));
6207 6208
}

6209 6210 6211
static void WINE_GLAPI specular_d3dcolor(const void *data)
{
    DWORD specularColor = *((const DWORD *)data);
6212 6213 6214 6215 6216 6217
    GLubyte d[] =
    {
        D3DCOLOR_B_R(specularColor),
        D3DCOLOR_B_G(specularColor),
        D3DCOLOR_B_B(specularColor)
    };
6218

6219
    context_get_current()->gl_info->gl_ops.ext.p_glSecondaryColor3ubvEXT(d);
6220
}
6221 6222 6223

static void WINE_GLAPI warn_no_specular_func(const void *data)
{
6224
    WARN("GL_EXT_secondary_color not supported.\n");
6225 6226
}

6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267
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);
}

6268
static void wined3d_adapter_init_ffp_attrib_ops(struct wined3d_adapter *adapter)
6269
{
6270
    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
6271 6272
    struct wined3d_d3d_info *d3d_info = &adapter->d3d_info;
    struct wined3d_ffp_attrib_ops *ops = &d3d_info->ffp_attrib_ops;
6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283
    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;
    }
6284

6285
    ops->position[WINED3D_FFP_EMIT_FLOAT3]    = (wined3d_ffp_attrib_func)gl_info->gl_ops.gl.p_glVertex3fv;
6286
    if (!d3d_info->xyzrhw)
6287
        ops->position[WINED3D_FFP_EMIT_FLOAT4]    = position_float4;
6288
    else
6289 6290 6291
        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;
6292

6293 6294 6295 6296 6297 6298 6299 6300
    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. */
6301
    if (gl_info->supported[EXT_SECONDARY_COLOR])
6302
        ops->specular[WINED3D_FFP_EMIT_FLOAT3]    = (wined3d_ffp_attrib_func)GL_EXTCALL(glSecondaryColor3fvEXT);
6303
    else
6304
        ops->specular[WINED3D_FFP_EMIT_FLOAT3]    = warn_no_specular_func;
6305
    if (gl_info->supported[EXT_SECONDARY_COLOR])
6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323
        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])
6324
    {
6325 6326 6327 6328 6329
        /* 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;
6330
    }
6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360

    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;
    }
6361 6362
}

6363 6364 6365
static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc)
{
    const struct wined3d_gl_info *gl_info = &adapter->gl_info;
6366
    int i;
6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378

    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));

6379
        adapter->cfgs = wined3d_calloc(cfg_count, sizeof(*adapter->cfgs));
6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 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 6442 6443
        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);
6444
        adapter->cfgs = wined3d_calloc(cfg_count, sizeof(*adapter->cfgs));
6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 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

        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;
        }
    }
}

6490
static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal, DWORD wined3d_creation_flags)
6491
{
6492 6493 6494 6495 6496
    static const DWORD supported_gl_versions[] =
    {
        MAKEDWORD_VERSION(3, 2),
        MAKEDWORD_VERSION(1, 0),
    };
6497
    struct wined3d_gl_info *gl_info = &adapter->gl_info;
6498
    struct wined3d_caps_gl_ctx caps_gl_ctx = {0};
6499
    unsigned int i;
6500
    DISPLAY_DEVICEW display_device;
6501

6502
    TRACE("adapter %p, ordinal %u.\n", adapter, ordinal);
6503

6504
    adapter->ordinal = ordinal;
6505

6506
/* Dynamically load all GL core functions */
6507
#ifdef USE_WIN32_OPENGL
6508 6509
    {
        HMODULE mod_gl = GetModuleHandleA("opengl32.dll");
6510
#define USE_GL_FUNC(f) gl_info->gl_ops.gl.p_##f = (void *)GetProcAddress(mod_gl, #f);
6511
        ALL_WGL_FUNCS
6512
#undef USE_GL_FUNC
6513
        gl_info->gl_ops.wgl.p_wglSwapBuffers = (void *)GetProcAddress(mod_gl, "wglSwapBuffers");
6514
        gl_info->gl_ops.wgl.p_wglGetPixelFormat = (void *)GetProcAddress(mod_gl, "wglGetPixelFormat");
6515
    }
6516
#else
6517
    /* To bypass the opengl32 thunks retrieve functions from the WGL driver instead of opengl32 */
6518 6519
    {
        HDC hdc = GetDC( 0 );
6520
        const struct opengl_funcs *wgl_driver = __wine_get_wgl_driver( hdc, WINE_WGL_DRIVER_VERSION );
6521
        ReleaseDC( 0, hdc );
6522
        if (!wgl_driver || wgl_driver == (void *)-1) return FALSE;
6523
        gl_info->gl_ops.wgl = wgl_driver->wgl;
6524
        gl_info->gl_ops.gl = wgl_driver->gl;
6525
    }
6526
#endif
6527

6528 6529
    glEnableWINE = gl_info->gl_ops.gl.p_glEnable;
    glDisableWINE = gl_info->gl_ops.gl.p_glDisable;
6530

6531
    if (!AllocateLocallyUniqueId(&adapter->luid))
6532
    {
6533 6534 6535 6536 6537
        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);
6538

6539
    if (!wined3d_caps_gl_ctx_create(adapter, &caps_gl_ctx))
6540 6541 6542 6543
    {
        ERR("Failed to get a GL context for adapter %p.\n", adapter);
        return FALSE;
    }
6544

6545 6546 6547 6548 6549 6550
    for (i = 0; i < ARRAY_SIZE(supported_gl_versions); ++i)
    {
        if (supported_gl_versions[i] <= wined3d_settings.max_gl_version)
            break;
    }
    if (i == ARRAY_SIZE(supported_gl_versions))
6551
    {
6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565
        ERR_(winediag)("Requested invalid GL version %u.%u.\n",
                wined3d_settings.max_gl_version >> 16, wined3d_settings.max_gl_version & 0xffff);
        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);
6566
    }
6567

6568
    if (!wined3d_adapter_init_gl_caps(adapter, &caps_gl_ctx, wined3d_creation_flags))
6569 6570
    {
        ERR("Failed to initialize GL caps for adapter %p.\n", adapter);
6571
        wined3d_caps_gl_ctx_destroy(&caps_gl_ctx);
6572 6573
        return FALSE;
    }
6574

6575 6576 6577 6578
    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");

6579
    wined3d_adapter_init_fb_cfgs(adapter, caps_gl_ctx.dc);
6580 6581 6582 6583 6584
    /* 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");
6585
        wined3d_caps_gl_ctx_destroy(&caps_gl_ctx);
6586 6587 6588
        HeapFree(GetProcessHeap(), 0, adapter->cfgs);
        return FALSE;
    }
6589

6590
    if (!wined3d_adapter_init_format_info(adapter, &caps_gl_ctx))
6591 6592
    {
        ERR("Failed to initialize GL format info.\n");
6593
        wined3d_caps_gl_ctx_destroy(&caps_gl_ctx);
6594 6595 6596
        HeapFree(GetProcessHeap(), 0, adapter->cfgs);
        return FALSE;
    }
6597

6598 6599 6600 6601
    gl_info->fixed_polyoffset_scale = wined3d_adapter_find_polyoffset_scale(&caps_gl_ctx, GL_DEPTH_COMPONENT);
    if (gl_info->supported[ARB_DEPTH_BUFFER_FLOAT])
        gl_info->float_polyoffset_scale = wined3d_adapter_find_polyoffset_scale(&caps_gl_ctx, GL_DEPTH32F_STENCIL8);

6602 6603 6604
    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));
6605

6606 6607 6608 6609
    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);
6610

6611
    wined3d_caps_gl_ctx_destroy(&caps_gl_ctx);
6612

6613
    wined3d_adapter_init_ffp_attrib_ops(adapter);
6614 6615

    return TRUE;
6616
}
6617

6618
static BOOL wined3d_adapter_init_nogl(struct wined3d_adapter *adapter, UINT ordinal)
6619
{
6620 6621
    DISPLAY_DEVICEW display_device;

6622 6623
    memset(adapter, 0, sizeof(*adapter));
    adapter->ordinal = ordinal;
6624

6625 6626
    adapter->driver_info.name = "Display";
    adapter->driver_info.description = "WineD3D DirectDraw Emulation";
6627
    if (wined3d_settings.emulated_textureram)
6628
        adapter->vram_bytes = wined3d_settings.emulated_textureram;
6629
    else
6630
        adapter->vram_bytes = 128 * 1024 * 1024;
6631

6632 6633
    if (!wined3d_adapter_init_format_info(adapter, NULL))
        return FALSE;
6634

6635
    adapter->vertex_pipe = &none_vertex_pipe;
6636 6637
    adapter->fragment_pipe = &none_fragment_pipe;
    adapter->shader_backend = &none_shader_backend;
6638 6639 6640 6641 6642

    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);
6643 6644

    return TRUE;
6645 6646
}

6647 6648 6649 6650 6651 6652
static void STDMETHODCALLTYPE wined3d_null_wined3d_object_destroyed(void *parent) {}

const struct wined3d_parent_ops wined3d_null_parent_ops =
{
    wined3d_null_wined3d_object_destroyed,
};
6653

6654
HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags)
6655
{
6656 6657
    BOOL ret;

6658
    wined3d->ref = 1;
6659
    wined3d->flags = flags;
6660

6661 6662
    TRACE("Initializing adapters.\n");

6663
    if (flags & WINED3D_NO3D)
6664 6665 6666 6667
        ret = wined3d_adapter_init_nogl(&wined3d->adapters[0], 0);
    else
        ret = wined3d_adapter_init(&wined3d->adapters[0], 0, flags);
    if (!ret)
6668
    {
6669
        WARN("Failed to initialize adapter.\n");
6670
        return E_FAIL;
6671
    }
6672
    wined3d->adapter_count = 1;
6673 6674 6675

    return WINED3D_OK;
}