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