📄 directx.c
字号:
/*
* Initialize openGL extension related variables
* with Default values
*/
memset(&gl_info->supported, 0, sizeof(gl_info->supported));
gl_info->max_buffers = 1;
gl_info->max_textures = 1;
gl_info->max_texture_stages = 1;
gl_info->max_fragment_samplers = 1;
gl_info->max_vertex_samplers = 0;
gl_info->max_combined_samplers = 0;
gl_info->max_sampler_stages = 1;
gl_info->ps_arb_version = PS_VERSION_NOT_SUPPORTED;
gl_info->ps_arb_max_temps = 0;
gl_info->ps_arb_max_instructions = 0;
gl_info->vs_arb_version = VS_VERSION_NOT_SUPPORTED;
gl_info->vs_arb_max_temps = 0;
gl_info->vs_arb_max_instructions = 0;
gl_info->vs_nv_version = VS_VERSION_NOT_SUPPORTED;
gl_info->vs_ati_version = VS_VERSION_NOT_SUPPORTED;
gl_info->vs_glsl_constantsF = 0;
gl_info->ps_glsl_constantsF = 0;
gl_info->vs_arb_constantsF = 0;
gl_info->ps_arb_constantsF = 0;
/* Now work out what GL support this card really has */
#define USE_GL_FUNC(type, pfn) gl_info->pfn = (type) pwglGetProcAddress(#pfn);
GL_EXT_FUNCS_GEN;
WGL_EXT_FUNCS_GEN;
#undef USE_GL_FUNC
/* Retrieve opengl defaults */
glGetIntegerv(GL_MAX_CLIP_PLANES, &gl_max);
gl_info->max_clipplanes = min(WINED3DMAXUSERCLIPPLANES, gl_max);
TRACE_(d3d_caps)("ClipPlanes support - num Planes=%d\n", gl_max);
glGetIntegerv(GL_MAX_LIGHTS, &gl_max);
gl_info->max_lights = gl_max;
TRACE_(d3d_caps)("Lights support - max lights=%d\n", gl_max);
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max);
gl_info->max_texture_size = gl_max;
TRACE_(d3d_caps)("Maximum texture size support - max texture size=%d\n", gl_max);
glGetFloatv(GL_POINT_SIZE_RANGE, gl_floatv);
gl_info->max_pointsize = gl_floatv[1];
TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
glGetIntegerv(GL_AUX_BUFFERS, &gl_max);
gl_info->max_aux_buffers = gl_max;
TRACE_(d3d_caps)("Offscreen rendering support - number of aux buffers=%d\n", gl_max);
/* Parse the gl supported features, in theory enabling parts of our code appropriately */
GL_Extensions = (const char *) glGetString(GL_EXTENSIONS);
TRACE_(d3d_caps)("GL_Extensions reported:\n");
if (NULL == GL_Extensions) {
ERR(" GL_Extensions returns NULL\n");
} else {
while (*GL_Extensions != 0x00) {
const char *Start;
char ThisExtn[256];
size_t len;
while (isspace(*GL_Extensions)) GL_Extensions++;
Start = GL_Extensions;
while (!isspace(*GL_Extensions) && *GL_Extensions != 0x00) {
GL_Extensions++;
}
len = GL_Extensions - Start;
if (len == 0 || len >= sizeof(ThisExtn))
continue;
memcpy(ThisExtn, Start, len);
ThisExtn[len] = '\0';
TRACE_(d3d_caps)("- %s\n", ThisExtn);
for (i = 0; i < (sizeof(EXTENSION_MAP) / sizeof(*EXTENSION_MAP)); ++i) {
if (!strcmp(ThisExtn, EXTENSION_MAP[i].extension_string)) {
TRACE_(d3d_caps)(" FOUND: %s support\n", EXTENSION_MAP[i].extension_string);
gl_info->supported[EXTENSION_MAP[i].extension] = TRUE;
break;
}
}
}
if (gl_info->supported[APPLE_FENCE]) {
/* GL_NV_fence and GL_APPLE_fence provide the same functionality basically.
* The apple extension interacts with some other apple exts. Disable the NV
* extension if the apple one is support to prevent confusion in other parts
* of the code
*/
gl_info->supported[NV_FENCE] = FALSE;
}
if (gl_info->supported[ARB_TEXTURE_CUBE_MAP]) {
TRACE_(d3d_caps)(" IMPLIED: NVIDIA (NV) Texture Gen Reflection support\n");
gl_info->supported[NV_TEXGEN_REFLECTION] = TRUE;
}
if (gl_info->supported[NV_TEXTURE_SHADER2]) {
/* GL_ATI_envmap_bumpmap won't play nice with texture shaders, so disable it
* Won't occur in any real world situation though
*/
gl_info->supported[ATI_ENVMAP_BUMPMAP] = FALSE;
}
if (gl_info->supported[ARB_DRAW_BUFFERS]) {
glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &gl_max);
gl_info->max_buffers = gl_max;
TRACE_(d3d_caps)("Max draw buffers: %u\n", gl_max);
}
if (gl_info->supported[ARB_MULTITEXTURE]) {
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_max);
gl_info->max_textures = min(MAX_TEXTURES, gl_max);
TRACE_(d3d_caps)("Max textures: %d\n", gl_info->max_textures);
if (gl_info->supported[NV_REGISTER_COMBINERS]) {
GLint tmp;
glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &tmp);
gl_info->max_texture_stages = min(MAX_TEXTURES, tmp);
} else {
gl_info->max_texture_stages = min(MAX_TEXTURES, gl_max);
}
TRACE_(d3d_caps)("Max texture stages: %d\n", gl_info->max_texture_stages);
if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
GLint tmp;
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
gl_info->max_fragment_samplers = min(MAX_FRAGMENT_SAMPLERS, tmp);
} else {
gl_info->max_fragment_samplers = max(gl_info->max_fragment_samplers, gl_max);
}
TRACE_(d3d_caps)("Max fragment samplers: %d\n", gl_info->max_fragment_samplers);
if (gl_info->supported[ARB_VERTEX_SHADER]) {
GLint tmp;
glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &tmp);
gl_info->max_vertex_samplers = tmp;
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB, &tmp);
gl_info->max_combined_samplers = tmp;
} else {
gl_info->max_combined_samplers = gl_info->max_fragment_samplers;
}
TRACE_(d3d_caps)("Max vertex samplers: %u\n", gl_info->max_vertex_samplers);
TRACE_(d3d_caps)("Max combined samplers: %u\n", gl_info->max_combined_samplers);
}
if (gl_info->supported[ARB_VERTEX_BLEND]) {
glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &gl_max);
gl_info->max_blends = gl_max;
TRACE_(d3d_caps)("Max blends: %u\n", gl_info->max_blends);
}
if (gl_info->supported[EXT_TEXTURE3D]) {
glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE_EXT, &gl_max);
gl_info->max_texture3d_size = gl_max;
TRACE_(d3d_caps)("Max texture3D size: %d\n", gl_info->max_texture3d_size);
}
if (gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC]) {
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_max);
gl_info->max_anisotropy = gl_max;
TRACE_(d3d_caps)("Max anisotropy: %d\n", gl_info->max_anisotropy);
}
if (gl_info->supported[ARB_FRAGMENT_PROGRAM]) {
gl_info->ps_arb_version = PS_VERSION_11;
GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
gl_info->ps_arb_constantsF = gl_max;
TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM float constants: %d\n", gl_info->ps_arb_constantsF);
GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, &gl_max));
gl_info->ps_arb_max_temps = gl_max;
TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM temporaries: %d\n", gl_info->ps_arb_max_temps);
GL_EXTCALL(glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, &gl_max));
gl_info->ps_arb_max_instructions = gl_max;
TRACE_(d3d_caps)("Max ARB_FRAGMENT_PROGRAM instructions: %d\n", gl_info->ps_arb_max_instructions);
}
if (gl_info->supported[ARB_VERTEX_PROGRAM]) {
gl_info->vs_arb_version = VS_VERSION_11;
GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_ENV_PARAMETERS_ARB, &gl_max));
gl_info->vs_arb_constantsF = gl_max;
TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM float constants: %d\n", gl_info->vs_arb_constantsF);
GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_TEMPORARIES_ARB, &gl_max));
gl_info->vs_arb_max_temps = gl_max;
TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM temporaries: %d\n", gl_info->vs_arb_max_temps);
GL_EXTCALL(glGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_MAX_PROGRAM_INSTRUCTIONS_ARB, &gl_max));
gl_info->vs_arb_max_instructions = gl_max;
TRACE_(d3d_caps)("Max ARB_VERTEX_PROGRAM instructions: %d\n", gl_info->vs_arb_max_instructions);
}
if (gl_info->supported[ARB_VERTEX_SHADER]) {
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB, &gl_max);
gl_info->vs_glsl_constantsF = gl_max / 4;
TRACE_(d3d_caps)("Max ARB_VERTEX_SHADER float constants: %u\n", gl_info->vs_glsl_constantsF);
}
if (gl_info->supported[ARB_FRAGMENT_SHADER]) {
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB, &gl_max);
gl_info->ps_glsl_constantsF = gl_max / 4;
TRACE_(d3d_caps)("Max ARB_FRAGMENT_SHADER float constants: %u\n", gl_info->ps_glsl_constantsF);
}
if (gl_info->supported[EXT_VERTEX_SHADER]) {
gl_info->vs_ati_version = VS_VERSION_11;
}
if (gl_info->supported[NV_VERTEX_PROGRAM3]) {
gl_info->vs_nv_version = VS_VERSION_30;
} else if (gl_info->supported[NV_VERTEX_PROGRAM2]) {
gl_info->vs_nv_version = VS_VERSION_20;
} else if (gl_info->supported[NV_VERTEX_PROGRAM1_1]) {
gl_info->vs_nv_version = VS_VERSION_11;
} else if (gl_info->supported[NV_VERTEX_PROGRAM]) {
gl_info->vs_nv_version = VS_VERSION_10;
}
if (gl_info->supported[NV_FRAGMENT_PROGRAM2]) {
gl_info->ps_nv_version = PS_VERSION_30;
} else if (gl_info->supported[NV_FRAGMENT_PROGRAM]) {
gl_info->ps_nv_version = PS_VERSION_20;
}
}
checkGLcall("extension detection\n");
/* In some cases the number of texture stages can be larger than the number
* of samplers. The GF4 for example can use only 2 samplers (no fragment
* shaders), but 8 texture stages (register combiners). */
gl_info->max_sampler_stages = max(gl_info->max_fragment_samplers, gl_info->max_texture_stages);
/* We can only use ORM_FBO when the hardware supports it. */
if (wined3d_settings.offscreen_rendering_mode == ORM_FBO && !gl_info->supported[EXT_FRAMEBUFFER_OBJECT]) {
WARN_(d3d_caps)("GL_EXT_framebuffer_object not supported, falling back to PBuffer offscreen rendering mode.\n");
wined3d_settings.offscreen_rendering_mode = ORM_PBUFFER;
}
/* MRTs are currently only supported when FBOs are used. */
if (wined3d_settings.offscreen_rendering_mode != ORM_FBO) {
gl_info->max_buffers = 1;
}
/* Below is a list of Nvidia and ATI GPUs. Both vendors have dozens of different GPUs with roughly the same
* features. In most cases GPUs from a certain family differ in clockspeeds, the amount of video memory and
* in case of the latest videocards in the number of pixel/vertex pipelines.
*
* A Direct3D device object contains the PCI id (vendor + device) of the videocard which is used for
* rendering. Various games use this information to get a rough estimation of the features of the card
* and some might use it for enabling 3d effects only on certain types of videocards. In some cases
* games might even use it to work around bugs which happen on certain videocards/driver combinations.
* The problem is that OpenGL only exposes a rendering string containing the name of the videocard and
* not the PCI id.
*
* Various games depend on the PCI id, so somehow we need to provide one. A simple option is to parse
* the renderer string and translate this to the right PCI id. This is a lot of work because there are more
* than 200 GPUs just for Nvidia. Various cards share the same renderer string, so the amount of code might
* be 'small' but there are quite a number of exceptions which would make this a pain to maintain.
* Another way would be to query the PCI id from the operating system (assuming this is the videocard which
* is used for rendering which is not always the case). This would work but it is not very portable. Second
* it would not work well in, let's say, a remote X situation in which the amount of 3d features which can be used
* is limited.
*
* As said most games only use the PCI id to get an indication of the capabilities of the card.
* It doesn't really matter if the given id is the correct one if we return the id of a card with
* similar 3d features.
*
* The code below checks the OpenGL capabilities of a videocard and matches that to a certain level of
* Direct3D functionality. Once a card passes the Direct3D9 check, we know that the card (in case of Nvidia)
* is at least a GeforceFX. To give a better estimate we do a basic check on the renderer string but if that
* won't pass we return a default card. This way is better than maintaining a full card database as even
* without a full database we can return a card with similar features. Second the size of the database
* can be made quite small because when you know what type of 3d functionality a card has, you know to which
* GPU family the GPU must belong. Because of this you only have to check a small part of the renderer string
* to distinguishes between different models from that family.
*/
switch (gl_info->gl_vendor) {
case VENDOR_NVIDIA:
/* Both the GeforceFX, 6xxx and 7xxx series support D3D9. The last two types have more
* shader capabilities, so we use the shader capabilities to distinguish between FX and 6xxx/7xxx.
*/
if(WINE_D3D9_CAPABLE(gl_info) && (gl_info->vs_nv_version == VS_VERSION_30)) {
if (strstr(gl_info->gl_renderer, "7800") ||
strstr(gl_info->gl_renderer, "7900") ||
strstr(gl_info->gl_renderer, "7950") ||
strstr(gl_info->gl_renderer, "Quadro FX 4") ||
strstr(gl_info->gl_renderer, "Quadro FX 5"))
gl_info->gl_card = CARD_NVIDIA_GEFORCE_7800GT;
else if(strstr(gl_info->gl_renderer, "6800") ||
strstr(gl_info->gl_renderer, "7600"))
gl_info->gl_card = CARD_NVIDIA_GEFORCE_6800;
else if(strstr(gl_info->gl_renderer, "6600") ||
strstr(gl_info->gl_renderer, "6610") ||
strstr(gl_info->gl_renderer, "6700"))
gl_info->gl_card = CARD_NVIDIA_GEFORCE_6600GT;
else
gl_info->gl_card = CARD_NVIDIA_GEFORCE_6200; /* Geforce 6100/6150/6200/7300/7400 */
} else if(WINE_D3D9_CAPABLE(gl_info)) {
if (strstr(gl_info->gl_renderer, "5800") ||
strstr(gl_info->gl_renderer, "5900") ||
strstr(gl_info->gl_renderer, "5950") ||
strstr(gl_info->gl_renderer, "Quadro FX"))
gl_info->gl_card = CARD_NVIDIA_GEFORCEFX_5800;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -