WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(d3d_caps);
+#define GLINFO_LOCATION (*gl_info)
+
/* The d3d device ID */
static const GUID IID_D3DDEVICE_D3DUID = { 0xaeb2cdd4, 0x6e41, 0x43ea, { 0x94,0x1c,0x83,0x61,0xcc,0x76,0x07,0x81 } };
{"GL_ARB_draw_buffers", ARB_DRAW_BUFFERS, 0 },
{"GL_ARB_fragment_program", ARB_FRAGMENT_PROGRAM, 0 },
{"GL_ARB_fragment_shader", ARB_FRAGMENT_SHADER, 0 },
+ {"GL_ARB_geometry_shader4", ARB_GEOMETRY_SHADER4, 0 },
{"GL_ARB_half_float_pixel", ARB_HALF_FLOAT_PIXEL, 0 },
{"GL_ARB_imaging", ARB_IMAGING, 0 },
{"GL_ARB_multisample", ARB_MULTISAMPLE, 0 }, /* needs GLX_ARB_MULTISAMPLE as well */
{"GL_ARB_texture_mirrored_repeat", ARB_TEXTURE_MIRRORED_REPEAT, 0 },
{"GL_ARB_texture_non_power_of_two", ARB_TEXTURE_NON_POWER_OF_TWO, MAKEDWORD_VERSION(2, 0) },
{"GL_ARB_texture_rectangle", ARB_TEXTURE_RECTANGLE, 0 },
+ {"GL_ARB_texture_rg", ARB_TEXTURE_RG, 0 },
{"GL_ARB_vertex_blend", ARB_VERTEX_BLEND, 0 },
{"GL_ARB_vertex_buffer_object", ARB_VERTEX_BUFFER_OBJECT, 0 },
{"GL_ARB_vertex_program", ARB_VERTEX_PROGRAM, 0 },
{"GL_ARB_vertex_shader", ARB_VERTEX_SHADER, 0 },
{"GL_ARB_shader_objects", ARB_SHADER_OBJECTS, 0 },
+ {"GL_ARB_shader_texture_lod", ARB_SHADER_TEXTURE_LOD, 0 },
+ {"GL_ARB_half_float_vertex", ARB_HALF_FLOAT_VERTEX, 0 },
/* EXT */
{"GL_EXT_blend_color", EXT_BLEND_COLOR, 0 },
{"GL_EXT_texture_env_combine", EXT_TEXTURE_ENV_COMBINE, 0 },
{"GL_EXT_texture_env_dot3", EXT_TEXTURE_ENV_DOT3, 0 },
{"GL_EXT_texture_sRGB", EXT_TEXTURE_SRGB, 0 },
+ {"GL_EXT_texture_swizzle", EXT_TEXTURE_SWIZZLE, 0 },
{"GL_EXT_texture_filter_anisotropic", EXT_TEXTURE_FILTER_ANISOTROPIC, 0 },
{"GL_EXT_texture_lod", EXT_TEXTURE_LOD, 0 },
{"GL_EXT_texture_lod_bias", EXT_TEXTURE_LOD_BIAS, 0 },
+ {"GL_EXT_vertex_array_bgra", EXT_VERTEX_ARRAY_BGRA, 0 },
{"GL_EXT_vertex_shader", EXT_VERTEX_SHADER, 0 },
{"GL_EXT_gpu_program_parameters", EXT_GPU_PROGRAM_PARAMETERS, 0 },
* Utility functions follow
**********************************************************/
-/* Adapters */
-static int numAdapters = 0;
-static struct WineD3DAdapter Adapters[1];
-
static HRESULT WINAPI IWineD3DImpl_CheckDeviceFormat(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat, WINED3DSURFTYPE SurfaceType);
-static const struct fragment_pipeline *select_fragment_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType);
-static const shader_backend_t *select_shader_backend(UINT Adapter, WINED3DDEVTYPE DeviceType);
-static const struct blit_shader *select_blit_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType);
+static const struct fragment_pipeline *select_fragment_implementation(struct WineD3DAdapter *adapter,
+ WINED3DDEVTYPE DeviceType);
+static const shader_backend_t *select_shader_backend(struct WineD3DAdapter *adapter, WINED3DDEVTYPE DeviceType);
+static const struct blit_shader *select_blit_implementation(struct WineD3DAdapter *adapter, WINED3DDEVTYPE DeviceType);
/* lookup tables */
-int minLookup[MAX_LOOKUPS];
-int maxLookup[MAX_LOOKUPS];
+const int minLookup[MAX_LOOKUPS] =
+{
+ WINED3DTADDRESS_WRAP, /* WINELOOKUP_WARPPARAM */
+};
+
+const int maxLookup[MAX_LOOKUPS] =
+{
+ WINED3DTADDRESS_MIRRORONCE, /* WINELOOKUP_WARPPARAM */
+};
+
DWORD *stateLookup[MAX_LOOKUPS];
-DWORD minMipLookup[WINED3DTEXF_ANISOTROPIC + 1][WINED3DTEXF_LINEAR + 1];
-DWORD minMipLookup_noFilter[WINED3DTEXF_ANISOTROPIC + 1][WINED3DTEXF_LINEAR + 1] = {
- {GL_NEAREST, GL_NEAREST, GL_NEAREST},
- {GL_NEAREST, GL_NEAREST, GL_NEAREST},
- {GL_NEAREST, GL_NEAREST, GL_NEAREST},
- {GL_NEAREST, GL_NEAREST, GL_NEAREST},
+struct min_lookup minMipLookup[WINED3DTEXF_ANISOTROPIC + 1];
+const struct min_lookup minMipLookup_noFilter[WINED3DTEXF_ANISOTROPIC + 1] =
+{
+ {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
+ {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
+ {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
+ {{GL_NEAREST, GL_NEAREST, GL_NEAREST}},
};
-DWORD magLookup[WINED3DTEXF_ANISOTROPIC + 1];
-DWORD magLookup_noFilter[WINED3DTEXF_ANISOTROPIC + 1] = {
+GLenum magLookup[WINED3DTEXF_ANISOTROPIC + 1];
+const GLenum magLookup_noFilter[WINED3DTEXF_ANISOTROPIC + 1] =
+{
GL_NEAREST, GL_NEAREST, GL_NEAREST, GL_NEAREST
};
/* drawStridedSlow attributes */
-glAttribFunc position_funcs[WINED3DDECLTYPE_UNUSED];
-glAttribFunc diffuse_funcs[WINED3DDECLTYPE_UNUSED];
-glAttribFunc specular_funcs[WINED3DDECLTYPE_UNUSED];
-glAttribFunc normal_funcs[WINED3DDECLTYPE_UNUSED];
-glMultiTexCoordFunc multi_texcoord_funcs[WINED3DDECLTYPE_UNUSED];
-glAttribFunc texcoord_funcs[WINED3DDECLTYPE_UNUSED];
+glAttribFunc position_funcs[WINED3D_FFP_EMIT_COUNT];
+glAttribFunc diffuse_funcs[WINED3D_FFP_EMIT_COUNT];
+glAttribFunc specular_func_3ubv;
+glAttribFunc specular_funcs[WINED3D_FFP_EMIT_COUNT];
+glAttribFunc normal_funcs[WINED3D_FFP_EMIT_COUNT];
+glMultiTexCoordFunc multi_texcoord_funcs[WINED3D_FFP_EMIT_COUNT];
/**
* Note: GL seems to trap if GetDeviceCaps is called before any HWND's created,
if(!wined3d_fake_gl_context_foreign && glCtx) {
TRACE_(d3d_caps)("destroying fake GL context\n");
pwglMakeCurrent(NULL, NULL);
- //ros hack, this line does destire the real icd interface in windows and reactos
- // pwglDeleteContext(glCtx);
+ //pwglDeleteContext(glCtx);
}
if(wined3d_fake_gl_context_hdc)
ReleaseDC(wined3d_fake_gl_context_hwnd, wined3d_fake_gl_context_hdc);
/* Adjust the amount of used texture memory */
long WineD3DAdapterChangeGLRam(IWineD3DDeviceImpl *D3DDevice, long glram){
- UINT Adapter = D3DDevice->adapterNo;
+ struct WineD3DAdapter *adapter = D3DDevice->adapter;
- Adapters[Adapter].UsedTextureRam += glram;
- TRACE("Adjusted gl ram by %ld to %d\n", glram, Adapters[Adapter].UsedTextureRam);
- return Adapters[Adapter].UsedTextureRam;
+ adapter->UsedTextureRam += glram;
+ TRACE("Adjusted gl ram by %ld to %d\n", glram, adapter->UsedTextureRam);
+ return adapter->UsedTextureRam;
}
/**********************************************************
TRACE("(%p) : Releasing from %d\n", This, This->ref);
ref = InterlockedDecrement(&This->ref);
if (ref == 0) {
+ unsigned int i;
+
+ for (i = 0; i < This->adapter_count; ++i)
+ {
+ HeapFree(GetProcessHeap(), 0, This->adapters[i].cfgs);
+ }
HeapFree(GetProcessHeap(), 0, This);
}
/* Set the shader type for this device, depending on the given capabilities,
* the device type, and the user preferences in wined3d_settings */
-void select_shader_mode(
- WineD3D_GL_Info *gl_info,
- WINED3DDEVTYPE DeviceType,
- int* ps_selected,
- int* vs_selected) {
-
+static void select_shader_mode(const WineD3D_GL_Info *gl_info, WINED3DDEVTYPE DeviceType, int *ps_selected, int *vs_selected)
+{
if (wined3d_settings.vs_mode == VS_NONE) {
*vs_selected = SHADER_NONE;
} else if (gl_info->supported[ARB_VERTEX_SHADER] && wined3d_settings.glslRequested) {
switch (vs_selected_mode) {
case SHADER_GLSL:
- /* Subtract the other potential uniforms from the max available (bools, ints, and 1 row of projection matrix) */
- gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF - (MAX_CONST_B / 4) - MAX_CONST_I - 1;
+ gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF;
break;
case SHADER_ARB:
- /* We have to subtract any other PARAMs that we might use in our shader programs.
- * ATI seems to count 2 implicit PARAMs when we use fog and NVIDIA counts 1,
- * and we reference one row of the PROJECTION matrix which counts as 1 PARAM. */
- gl_info->max_vshader_constantsF = gl_info->vs_arb_constantsF - 3;
+ gl_info->max_vshader_constantsF = gl_info->vs_arb_constantsF;
break;
default:
gl_info->max_vshader_constantsF = 0;
switch (ps_selected_mode) {
case SHADER_GLSL:
- /* Subtract the other potential uniforms from the max available (bools & ints), and 2 states for fog.
- * In theory the texbem instruction may need one more shader constant too. But lets assume
- * that a sm <= 1.3 shader does not need all the uniforms provided by a glsl-capable card,
- * and lets not take away a uniform needlessly from all other shaders.
- */
- gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF - (MAX_CONST_B / 4) - MAX_CONST_I - 2;
+ gl_info->max_pshader_constantsF = gl_info->ps_glsl_constantsF;
break;
case SHADER_ARB:
- /* The arb shader only loads the bump mapping environment matrix into the shader if it finds
- * a free constant to do that, so only reduce the number of available constants by 2 for the fog states.
- */
- gl_info->max_pshader_constantsF = gl_info->ps_arb_constantsF - 2;
+ gl_info->max_pshader_constantsF = gl_info->ps_arb_constantsF;
break;
default:
gl_info->max_pshader_constantsF = 0;
* IWineD3D parts follows
**********************************************************/
-#define GLINFO_LOCATION (*gl_info)
-static inline BOOL test_arb_vs_offset_limit(WineD3D_GL_Info *gl_info) {
+static inline BOOL test_arb_vs_offset_limit(const WineD3D_GL_Info *gl_info)
+{
GLuint prog;
BOOL ret = FALSE;
const char *testcode =
return 0;
}
-BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
+static BOOL IWineD3DImpl_FillGLCaps(WineD3D_GL_Info *gl_info) {
const char *GL_Extensions = NULL;
const char *WGL_Extensions = NULL;
const char *gl_string = NULL;
ENTER_GL();
gl_string = (const char *) glGetString(GL_RENDERER);
- if (NULL == gl_string)
- gl_string = "None";
+ if (!gl_string) gl_string = "None";
strcpy(gl_info->gl_renderer, gl_string);
gl_string = (const char *) glGetString(GL_VENDOR);
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_combined_samplers = gl_info->max_fragment_samplers + gl_info->max_vertex_samplers;
gl_info->max_sampler_stages = 1;
gl_info->ps_arb_version = PS_VERSION_NOT_SUPPORTED;
gl_info->ps_arb_max_temps = 0;
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);
+ glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, gl_floatv);
gl_info->max_pointsizemin = gl_floatv[0];
gl_info->max_pointsize = gl_floatv[1];
TRACE_(d3d_caps)("Maximum point size support - max point size=%f\n", gl_floatv[1]);
gl_info->supported[NV_TEXTURE_SHADER2] = FALSE;
gl_info->supported[NV_TEXTURE_SHADER3] = FALSE;
}
-
+ if(gl_info->supported[NV_HALF_FLOAT]) {
+ /* GL_ARB_half_float_vertex is a subset of GL_NV_half_float */
+ gl_info->supported[ARB_HALF_FLOAT_VERTEX] = TRUE;
+ }
+ if(gl_info->supported[ARB_POINT_SPRITE]) {
+ gl_info->max_point_sprite_units = gl_info->max_textures;
+ } else {
+ gl_info->max_point_sprite_units = 0;
+ }
}
checkGLcall("extension detection\n");
* 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)) {
- /* Geforce9 - highend */
- if(strstr(gl_info->gl_renderer, "9800")) {
+ /* Geforce 200 - highend */
+ if(strstr(gl_info->gl_renderer, "GTX 280") ||
+ strstr(gl_info->gl_renderer, "GTX 285") ||
+ strstr(gl_info->gl_renderer, "GTX 295"))
+ {
+ gl_info->gl_card = CARD_NVIDIA_GEFORCE_GTX280;
+ vidmem = 1024;
+ }
+ /* Geforce 200 - midend high */
+ if(strstr(gl_info->gl_renderer, "GTX 275")) {
+ gl_info->gl_card = CARD_NVIDIA_GEFORCE_GTX275;
+ vidmem = 896;
+ }
+ /* Geforce 200 - midend */
+ if(strstr(gl_info->gl_renderer, "GTX 260")) {
+ gl_info->gl_card = CARD_NVIDIA_GEFORCE_GTX260;
+ vidmem = 1024;
+ }
+ /* Geforce9 - highend / Geforce 200 - midend (GTS 150/250 are based on the same core) */
+ else if(strstr(gl_info->gl_renderer, "9800") ||
+ strstr(gl_info->gl_renderer, "GTS 150") ||
+ strstr(gl_info->gl_renderer, "GTS 250"))
+ {
gl_info->gl_card = CARD_NVIDIA_GEFORCE_9800GT;
vidmem = 512;
}
gl_info->gl_card = CARD_NVIDIA_GEFORCE_9600GT;
vidmem = 384; /* The 9600GSO has 384MB, the 9600GT has 512-1024MB */
}
+ /* Geforce9 - midend low / Geforce 200 - low*/
+ else if(strstr(gl_info->gl_renderer, "9500") ||
+ strstr(gl_info->gl_renderer, "GT 120") ||
+ strstr(gl_info->gl_renderer, "GT 130"))
+ {
+ gl_info->gl_card = CARD_NVIDIA_GEFORCE_9500GT;
+ vidmem = 256; /* The 9500GT has 256-1024MB */
+ }
+ /* Geforce9 - lowend */
+ else if(strstr(gl_info->gl_renderer, "9400")) {
+ gl_info->gl_card = CARD_NVIDIA_GEFORCE_9400GT;
+ vidmem = 256; /* The 9400GT has 256-1024MB */
+ }
+ /* Geforce9 - lowend low */
+ else if(strstr(gl_info->gl_renderer, "9100") ||
+ strstr(gl_info->gl_renderer, "9200") ||
+ strstr(gl_info->gl_renderer, "9300") ||
+ strstr(gl_info->gl_renderer, "G 100"))
+ {
+ gl_info->gl_card = CARD_NVIDIA_GEFORCE_9200;
+ vidmem = 256; /* The 9100-9300 cards have 256MB */
+ }
/* Geforce8 - highend */
else if (strstr(gl_info->gl_renderer, "8800")) {
gl_info->gl_card = CARD_NVIDIA_GEFORCE_8800GTS;
gl_info->gl_card = CARD_ATI_RADEON_X700;
vidmem = 128; /* x700/x8*0 use 128-256MB, >=x1300 128-512MB */
}
+ /* Radeon Xpress Series - onboard, DX9b, Shader 2.0, 300-400MHz */
+ else if(strstr(gl_info->gl_renderer, "Radeon Xpress"))
+ {
+ gl_info->gl_card = CARD_ATI_RADEON_XPRESS_200M;
+ vidmem = 64; /* Shared RAM, BIOS configurable, 64-256M */
+ }
/* Radeon R3xx */
else {
gl_info->gl_card = CARD_ATI_RADEON_9500; /* Radeon 9500/9550/9600/9700/9800/X300/X550/X600 */
}
break;
case VENDOR_INTEL:
- if (strstr(gl_info->gl_renderer, "GMA 950")) {
+ if (strstr(gl_info->gl_renderer, "GMA 950") ||
+ strstr(gl_info->gl_renderer, "945GM")) {
/* MacOS calls the card GMA 950, but everywhere else the PCI ID is named 945GM */
gl_info->gl_card = CARD_INTEL_I945GM;
vidmem = 64;
else
gl_info->vidmem = WINE_DEFAULT_VIDMEM;
- /* Load all the lookup tables
- TODO: It may be a good idea to make minLookup and maxLookup const and populate them in wined3d_private.h where they are declared */
- minLookup[WINELOOKUP_WARPPARAM] = WINED3DTADDRESS_WRAP;
- maxLookup[WINELOOKUP_WARPPARAM] = WINED3DTADDRESS_MIRRORONCE;
-
+ /* Load all the lookup tables */
for (i = 0; i < MAX_LOOKUPS; i++) {
stateLookup[i] = HeapAlloc(GetProcessHeap(), 0, sizeof(*stateLookup[i]) * (1 + maxLookup[i] - minLookup[i]) );
}
gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR : GL_NEAREST;
- minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_NONE] = GL_LINEAR;
- minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_POINT] = GL_LINEAR;
- minMipLookup[WINED3DTEXF_NONE][WINED3DTEXF_LINEAR] = GL_LINEAR;
- minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_NONE] = GL_NEAREST;
- minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_POINT] = GL_NEAREST_MIPMAP_NEAREST;
- minMipLookup[WINED3DTEXF_POINT][WINED3DTEXF_LINEAR] = GL_NEAREST_MIPMAP_LINEAR;
- minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_NONE] = GL_LINEAR;
- minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_POINT] = GL_LINEAR_MIPMAP_NEAREST;
- minMipLookup[WINED3DTEXF_LINEAR][WINED3DTEXF_LINEAR] = GL_LINEAR_MIPMAP_LINEAR;
- minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_NONE] = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ?
- GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
- minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_POINT] = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR;
- minMipLookup[WINED3DTEXF_ANISOTROPIC][WINED3DTEXF_LINEAR] = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
+ minMipLookup[WINED3DTEXF_NONE].mip[WINED3DTEXF_NONE] = GL_LINEAR;
+ minMipLookup[WINED3DTEXF_NONE].mip[WINED3DTEXF_POINT] = GL_LINEAR;
+ minMipLookup[WINED3DTEXF_NONE].mip[WINED3DTEXF_LINEAR] = GL_LINEAR;
+ minMipLookup[WINED3DTEXF_POINT].mip[WINED3DTEXF_NONE] = GL_NEAREST;
+ minMipLookup[WINED3DTEXF_POINT].mip[WINED3DTEXF_POINT] = GL_NEAREST_MIPMAP_NEAREST;
+ minMipLookup[WINED3DTEXF_POINT].mip[WINED3DTEXF_LINEAR] = GL_NEAREST_MIPMAP_LINEAR;
+ minMipLookup[WINED3DTEXF_LINEAR].mip[WINED3DTEXF_NONE] = GL_LINEAR;
+ minMipLookup[WINED3DTEXF_LINEAR].mip[WINED3DTEXF_POINT] = GL_LINEAR_MIPMAP_NEAREST;
+ minMipLookup[WINED3DTEXF_LINEAR].mip[WINED3DTEXF_LINEAR] = GL_LINEAR_MIPMAP_LINEAR;
+ minMipLookup[WINED3DTEXF_ANISOTROPIC].mip[WINED3DTEXF_NONE]
+ = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
+ minMipLookup[WINED3DTEXF_ANISOTROPIC].mip[WINED3DTEXF_POINT]
+ = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR;
+ minMipLookup[WINED3DTEXF_ANISOTROPIC].mip[WINED3DTEXF_LINEAR]
+ = gl_info->supported[EXT_TEXTURE_FILTER_ANISOTROPIC] ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR;
/* TODO: config lookups */
/* Make sure there's an active HDC else the WGL extensions will fail */
hdc = pwglGetCurrentDC();
if (hdc) {
- WGL_Extensions = GL_EXTCALL(wglGetExtensionsStringARB(hdc));
- TRACE_(d3d_caps)("WGL_Extensions reported:\n");
+ /* Not all GL drivers might offer WGL extensions e.g. VirtualBox */
+ if(GL_EXTCALL(wglGetExtensionsStringARB))
+ WGL_Extensions = GL_EXTCALL(wglGetExtensionsStringARB(hdc));
if (NULL == WGL_Extensions) {
ERR(" WGL_Extensions returns NULL\n");
} else {
+ TRACE_(d3d_caps)("WGL_Extensions reported:\n");
while (*WGL_Extensions != 0x00) {
const char *Start;
char ThisExtn[256];
gl_info->supported[WGL_ARB_PBUFFER] = TRUE;
TRACE_(d3d_caps)("FOUND: WGL_ARB_pbuffer support\n");
}
+ if (!strcmp(ThisExtn, "WGL_ARB_pixel_format")) {
+ gl_info->supported[WGL_ARB_PIXEL_FORMAT] = TRUE;
+ TRACE_(d3d_caps)("FOUND: WGL_ARB_pixel_format support\n");
+ }
if (!strcmp(ThisExtn, "WGL_WINE_pixel_format_passthrough")) {
gl_info->supported[WGL_WINE_PIXEL_FORMAT_PASSTHROUGH] = TRUE;
TRACE_(d3d_caps)("FOUND: WGL_WINE_pixel_format_passthrough support\n");
return return_value;
}
-#undef GLINFO_LOCATION
/**********************************************************
* IWineD3D implementation follows
static UINT WINAPI IWineD3DImpl_GetAdapterCount (IWineD3D *iface) {
IWineD3DImpl *This = (IWineD3DImpl *)iface;
- TRACE_(d3d_caps)("(%p): Reporting %d adapters\n", This, numAdapters);
- return numAdapters;
+ TRACE_(d3d_caps)("(%p): Reporting %u adapters\n", This, This->adapter_count);
+
+ return This->adapter_count;
}
static HRESULT WINAPI IWineD3DImpl_RegisterSoftwareDevice(IWineD3D *iface, void* pInitializeFunction) {
return NULL;
}
- return MonitorFromPoint(Adapters[Adapter].monitorPoint, MONITOR_DEFAULTTOPRIMARY);
+ return MonitorFromPoint(This->adapters[Adapter].monitorPoint, MONITOR_DEFAULTTOPRIMARY);
}
/* FIXME: GetAdapterModeCount and EnumAdapterModes currently only returns modes
if (Adapter == 0 && !DEBUG_SINGLE_MODE) { /* Display */
DEVMODEW DevModeW;
int ModeIdx = 0;
- int i = 0;
+ UINT i = 0;
int j = 0;
ZeroMemory(&DevModeW, sizeof(DevModeW));
/* Return the information requested */
TRACE_(d3d_caps)("device/Vendor Name and Version detection using FillGLCaps\n");
- strcpy(pIdentifier->Driver, Adapters[Adapter].driver);
- strcpy(pIdentifier->Description, Adapters[Adapter].description);
+ strcpy(pIdentifier->Driver, This->adapters[Adapter].driver);
+ if(This->adapters[Adapter].gl_info.driver_description)
+ strcpy(pIdentifier->Description, This->adapters[Adapter].gl_info.driver_description);
+ else /* Copy default description "Direct3D HAL" */
+ strcpy(pIdentifier->Description, This->adapters[Adapter].description);
/* Note dx8 doesn't supply a DeviceName */
if (NULL != pIdentifier->DeviceName) strcpy(pIdentifier->DeviceName, "\\\\.\\DISPLAY"); /* FIXME: May depend on desktop? */
- pIdentifier->DriverVersion->u.HighPart = Adapters[Adapter].gl_info.driver_version_hipart;
- pIdentifier->DriverVersion->u.LowPart = Adapters[Adapter].gl_info.driver_version;
- *(pIdentifier->VendorId) = Adapters[Adapter].gl_info.gl_vendor;
- *(pIdentifier->DeviceId) = Adapters[Adapter].gl_info.gl_card;
+ pIdentifier->DriverVersion->u.HighPart = This->adapters[Adapter].gl_info.driver_version_hipart;
+ pIdentifier->DriverVersion->u.LowPart = This->adapters[Adapter].gl_info.driver_version;
+ *(pIdentifier->VendorId) = This->adapters[Adapter].gl_info.gl_vendor;
+ *(pIdentifier->DeviceId) = This->adapters[Adapter].gl_info.gl_card;
*(pIdentifier->SubSysId) = 0;
*(pIdentifier->Revision) = 0;
*pIdentifier->DeviceIdentifier = IID_D3DDEVICE_D3DUID;
+ if(wined3d_settings.pci_device_id != PCI_DEVICE_NONE)
+ {
+ TRACE_(d3d_caps)("Overriding pci device id with: %x\n", wined3d_settings.pci_device_id);
+ *(pIdentifier->DeviceId) = wined3d_settings.pci_device_id;
+ }
+
+ if(wined3d_settings.pci_vendor_id != PCI_VENDOR_NONE)
+ {
+ TRACE_(d3d_caps)("Overriding pci vendor id with: %x\n", wined3d_settings.pci_vendor_id);
+ *(pIdentifier->VendorId) = wined3d_settings.pci_vendor_id;
+ }
+
if (Flags & WINED3DENUM_NO_WHQL_LEVEL) {
*(pIdentifier->WHQLLevel) = 0;
} else {
return WINED3D_OK;
}
-static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const WineD3D_PixelFormat *cfg, WINED3DFORMAT Format) {
+static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(const WineD3D_GL_Info *gl_info,
+ const WineD3D_PixelFormat *cfg, const struct GlPixelFormatDesc *format_desc)
+{
short redSize, greenSize, blueSize, alphaSize, colorBits;
if(!cfg)
return FALSE;
if(cfg->iPixelType == WGL_TYPE_RGBA_ARB) { /* Integer RGBA formats */
- if(!getColorBits(Format, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits)) {
- ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(Format));
+ if (!getColorBits(format_desc, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
+ {
+ ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(format_desc->format));
return FALSE;
}
return TRUE;
} else if(cfg->iPixelType == WGL_TYPE_RGBA_FLOAT_ARB) { /* Float RGBA formats; TODO: WGL_NV_float_buffer */
- if(Format == WINED3DFMT_R16F)
+ if (format_desc->format == WINED3DFMT_R16_FLOAT)
return (cfg->redSize == 16 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0);
- if(Format == WINED3DFMT_G16R16F)
+ if (format_desc->format == WINED3DFMT_R16G16_FLOAT)
return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 0 && cfg->alphaSize == 0);
- if(Format == WINED3DFMT_A16B16G16R16F)
+ if (format_desc->format == WINED3DFMT_R16G16B16A16_FLOAT)
return (cfg->redSize == 16 && cfg->greenSize == 16 && cfg->blueSize == 16 && cfg->alphaSize == 16);
- if(Format == WINED3DFMT_R32F)
+ if (format_desc->format == WINED3DFMT_R32_FLOAT)
return (cfg->redSize == 32 && cfg->greenSize == 0 && cfg->blueSize == 0 && cfg->alphaSize == 0);
- if(Format == WINED3DFMT_G32R32F)
+ if (format_desc->format == WINED3DFMT_R32G32_FLOAT)
return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 0 && cfg->alphaSize == 0);
- if(Format == WINED3DFMT_A32B32G32R32F)
+ if (format_desc->format == WINED3DFMT_R32G32B32A32_FLOAT)
return (cfg->redSize == 32 && cfg->greenSize == 32 && cfg->blueSize == 32 && cfg->alphaSize == 32);
} else {
/* Probably a color index mode */
return FALSE;
}
-static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const WineD3D_PixelFormat *cfg, WINED3DFORMAT Format) {
+static BOOL IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(const WineD3D_GL_Info *gl_info,
+ const WineD3D_PixelFormat *cfg, const struct GlPixelFormatDesc *format_desc)
+{
short depthSize, stencilSize;
BOOL lockable = FALSE;
if(!cfg)
return FALSE;
- if(!getDepthStencilBits(Format, &depthSize, &stencilSize)) {
- ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(Format));
+ if (!getDepthStencilBits(format_desc, &depthSize, &stencilSize))
+ {
+ ERR("Unable to check compatibility for Format=%s\n", debug_d3dformat(format_desc->format));
return FALSE;
}
- if((Format == WINED3DFMT_D16_LOCKABLE) || (Format == WINED3DFMT_D32F_LOCKABLE))
+ if ((format_desc->format == WINED3DFMT_D16_LOCKABLE) || (format_desc->format == WINED3DFMT_D32F_LOCKABLE))
lockable = TRUE;
/* On some modern cards like the Geforce8/9 GLX doesn't offer some dephthstencil formats which D3D9 reports.
WINED3DFORMAT DepthStencilFormat) {
IWineD3DImpl *This = (IWineD3DImpl *)iface;
int nCfgs;
- WineD3D_PixelFormat *cfgs;
+ const WineD3D_PixelFormat *cfgs;
+ const struct WineD3DAdapter *adapter;
+ const struct GlPixelFormatDesc *rt_format_desc;
+ const struct GlPixelFormatDesc *ds_format_desc;
int it;
WARN_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%x,%s), AdptFmt:(%x,%s), RendrTgtFmt:(%x,%s), DepthStencilFmt:(%x,%s))\n",
return WINED3DERR_INVALIDCALL;
}
- cfgs = Adapters[Adapter].cfgs;
- nCfgs = Adapters[Adapter].nCfgs;
+ adapter = &This->adapters[Adapter];
+ rt_format_desc = getFormatDescEntry(RenderTargetFormat, &adapter->gl_info);
+ ds_format_desc = getFormatDescEntry(DepthStencilFormat, &adapter->gl_info);
+ cfgs = adapter->cfgs;
+ nCfgs = adapter->nCfgs;
for (it = 0; it < nCfgs; ++it) {
- if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&cfgs[it], RenderTargetFormat)) {
- if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&cfgs[it], DepthStencilFormat)) {
+ if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, &cfgs[it], rt_format_desc))
+ {
+ if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[it], ds_format_desc))
+ {
TRACE_(d3d_caps)("(%p) : Formats matched\n", This);
return WINED3D_OK;
}
BOOL Windowed, WINED3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels) {
IWineD3DImpl *This = (IWineD3DImpl *)iface;
- const GlPixelFormatDesc *glDesc;
- const StaticPixelFormatDesc *desc;
+ const struct GlPixelFormatDesc *glDesc;
+ const struct WineD3DAdapter *adapter;
TRACE_(d3d_caps)("(%p)-> (Adptr:%d, DevType:(%x,%s), SurfFmt:(%x,%s), Win?%d, MultiSamp:%x, pQual:%p)\n",
This,
if(!wined3d_settings.allow_multisampling)
return WINED3DERR_NOTAVAILABLE;
- desc = getFormatDescEntry(SurfaceFormat, &Adapters[Adapter].gl_info, &glDesc);
- if(!desc || !glDesc) {
- return WINED3DERR_INVALIDCALL;
- }
+ adapter = &This->adapters[Adapter];
+ glDesc = getFormatDescEntry(SurfaceFormat, &adapter->gl_info);
+ if (!glDesc) return WINED3DERR_INVALIDCALL;
if(glDesc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)) {
int i, nCfgs;
- WineD3D_PixelFormat *cfgs;
+ const WineD3D_PixelFormat *cfgs;
- cfgs = Adapters[Adapter].cfgs;
- nCfgs = Adapters[Adapter].nCfgs;
+ cfgs = adapter->cfgs;
+ nCfgs = adapter->nCfgs;
for(i=0; i<nCfgs; i++) {
if(cfgs[i].numSamples != MultiSampleType)
continue;
- if(!IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&cfgs[i], SurfaceFormat))
+ if (!IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, &cfgs[i], glDesc))
continue;
TRACE("Found iPixelFormat=%d to support MultiSampleType=%d for format %s\n", cfgs[i].iPixelFormat, MultiSampleType, debug_d3dformat(SurfaceFormat));
else if(glDesc->Flags & WINED3DFMT_FLAG_RENDERTARGET) {
short redSize, greenSize, blueSize, alphaSize, colorBits;
int i, nCfgs;
- WineD3D_PixelFormat *cfgs;
+ const WineD3D_PixelFormat *cfgs;
- if(!getColorBits(SurfaceFormat, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits)) {
+ if (!getColorBits(glDesc, &redSize, &greenSize, &blueSize, &alphaSize, &colorBits))
+ {
ERR("Unable to color bits for format %#x, can't check multisampling capability!\n", SurfaceFormat);
return WINED3DERR_NOTAVAILABLE;
}
- cfgs = Adapters[Adapter].cfgs;
- nCfgs = Adapters[Adapter].nCfgs;
+ cfgs = adapter->cfgs;
+ nCfgs = adapter->nCfgs;
for(i=0; i<nCfgs; i++) {
if(cfgs[i].numSamples != MultiSampleType)
continue;
}
-#define GLINFO_LOCATION Adapters[Adapter].gl_info
/* Check if we support bumpmapping for a format */
-static BOOL CheckBumpMapCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat)
+static BOOL CheckBumpMapCapability(struct WineD3DAdapter *adapter,
+ WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc)
{
const struct fragment_pipeline *fp;
- const GlPixelFormatDesc *glDesc;
- switch(CheckFormat) {
- case WINED3DFMT_V8U8:
- case WINED3DFMT_V16U16:
+ switch(format_desc->format)
+ {
+ case WINED3DFMT_R8G8_SNORM:
+ case WINED3DFMT_R16G16_SNORM:
case WINED3DFMT_L6V5U5:
case WINED3DFMT_X8L8V8U8:
- case WINED3DFMT_Q8W8V8U8:
- getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
- if(glDesc->conversion_group == WINED3DFMT_UNKNOWN) {
- /* We have a GL extension giving native support */
- TRACE_(d3d_caps)("[OK]\n");
- return TRUE;
- }
-
- /* No native support: Ask the fixed function pipeline implementation if it
- * can deal with the conversion
- */
- fp = select_fragment_implementation(Adapter, DeviceType);
- if(fp->conv_supported(CheckFormat)) {
+ case WINED3DFMT_R8G8B8A8_SNORM:
+ /* Ask the fixed function pipeline implementation if it can deal
+ * with the conversion. If we've got a GL extension giving native
+ * support this will be an identity conversion. */
+ fp = select_fragment_implementation(adapter, DeviceType);
+ if (fp->color_fixup_supported(format_desc->color_fixup))
+ {
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
- } else {
- TRACE_(d3d_caps)("[FAILED]\n");
- return FALSE;
}
+ TRACE_(d3d_caps)("[FAILED]\n");
+ return FALSE;
default:
TRACE_(d3d_caps)("[FAILED]\n");
}
/* Check if the given DisplayFormat + DepthStencilFormat combination is valid for the Adapter */
-static BOOL CheckDepthStencilCapability(UINT Adapter, WINED3DFORMAT DisplayFormat, WINED3DFORMAT DepthStencilFormat)
+static BOOL CheckDepthStencilCapability(struct WineD3DAdapter *adapter,
+ const struct GlPixelFormatDesc *display_format_desc, const struct GlPixelFormatDesc *ds_format_desc)
{
int it=0;
- const GlPixelFormatDesc *glDesc;
- const StaticPixelFormatDesc *desc = getFormatDescEntry(DepthStencilFormat, &GLINFO_LOCATION, &glDesc);
-
- /* Fail if we weren't able to get a description of the format */
- if(!desc || !glDesc)
- return FALSE;
/* Only allow depth/stencil formats */
- if(!(glDesc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL)))
- return FALSE;
+ if (!(ds_format_desc->Flags & (WINED3DFMT_FLAG_DEPTH | WINED3DFMT_FLAG_STENCIL))) return FALSE;
/* Walk through all WGL pixel formats to find a match */
- for (it = 0; it < Adapters[Adapter].nCfgs; ++it) {
- WineD3D_PixelFormat *cfg = &Adapters[Adapter].cfgs[it];
- if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(cfg, DisplayFormat)) {
- if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(cfg, DepthStencilFormat)) {
+ for (it = 0; it < adapter->nCfgs; ++it)
+ {
+ WineD3D_PixelFormat *cfg = &adapter->cfgs[it];
+ if (IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info, cfg, display_format_desc))
+ {
+ if (IWineD3DImpl_IsPixelFormatCompatibleWithDepthFmt(&adapter->gl_info, cfg, ds_format_desc))
+ {
return TRUE;
}
}
return FALSE;
}
-static BOOL CheckFilterCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
+static BOOL CheckFilterCapability(struct WineD3DAdapter *adapter, const struct GlPixelFormatDesc *format_desc)
{
- const GlPixelFormatDesc *glDesc;
- const StaticPixelFormatDesc *desc = getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
-
- /* Fail if we weren't able to get a description of the format */
- if(!desc || !glDesc)
- return FALSE;
-
/* The flags entry of a format contains the filtering capability */
- if(glDesc->Flags & WINED3DFMT_FLAG_FILTERING)
- return TRUE;
+ if (format_desc->Flags & WINED3DFMT_FLAG_FILTERING) return TRUE;
return FALSE;
}
/* Check the render target capabilities of a format */
-static BOOL CheckRenderTargetCapability(WINED3DFORMAT AdapterFormat, WINED3DFORMAT CheckFormat)
+static BOOL CheckRenderTargetCapability(struct WineD3DAdapter *adapter,
+ const struct GlPixelFormatDesc *adapter_format_desc, const struct GlPixelFormatDesc *check_format_desc)
{
- UINT Adapter = 0;
- const GlPixelFormatDesc *glDesc;
- const StaticPixelFormatDesc *desc = getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
-
- /* Fail if we weren't able to get a description of the format */
- if(!desc || !glDesc)
- return FALSE;
-
/* Filter out non-RT formats */
- if(!(glDesc->Flags & WINED3DFMT_FLAG_RENDERTARGET))
- return FALSE;
+ if (!(check_format_desc->Flags & WINED3DFMT_FLAG_RENDERTARGET)) return FALSE;
if(wined3d_settings.offscreen_rendering_mode == ORM_BACKBUFFER) {
- WineD3D_PixelFormat *cfgs = Adapters[Adapter].cfgs;
+ WineD3D_PixelFormat *cfgs = adapter->cfgs;
int it;
short AdapterRed, AdapterGreen, AdapterBlue, AdapterAlpha, AdapterTotalSize;
short CheckRed, CheckGreen, CheckBlue, CheckAlpha, CheckTotalSize;
- getColorBits(AdapterFormat, &AdapterRed, &AdapterGreen, &AdapterBlue, &AdapterAlpha, &AdapterTotalSize);
- getColorBits(CheckFormat, &CheckRed, &CheckGreen, &CheckBlue, &CheckAlpha, &CheckTotalSize);
+ getColorBits(adapter_format_desc, &AdapterRed, &AdapterGreen, &AdapterBlue, &AdapterAlpha, &AdapterTotalSize);
+ getColorBits(check_format_desc, &CheckRed, &CheckGreen, &CheckBlue, &CheckAlpha, &CheckTotalSize);
/* In backbuffer mode the front and backbuffer share the same WGL pixelformat.
* The format must match in RGB, alpha is allowed to be different. (Only the backbuffer can have alpha) */
/* Check if there is a WGL pixel format matching the requirements, the format should also be window
* drawable (not offscreen; e.g. Nvidia offers R5G6B5 for pbuffers even when X is running at 24bit) */
- for (it = 0; it < Adapters[Adapter].nCfgs; ++it) {
- if (cfgs[it].windowDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&cfgs[it], CheckFormat)) {
- TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n", cfgs[it].iPixelFormat, debug_d3dformat(CheckFormat));
+ for (it = 0; it < adapter->nCfgs; ++it)
+ {
+ if (cfgs[it].windowDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info,
+ &cfgs[it], check_format_desc))
+ {
+ TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n",
+ cfgs[it].iPixelFormat, debug_d3dformat(check_format_desc->format));
return TRUE;
}
}
} else if(wined3d_settings.offscreen_rendering_mode == ORM_PBUFFER) {
/* We can probably use this function in FBO mode too on some drivers to get some basic indication of the capabilities. */
- WineD3D_PixelFormat *cfgs = Adapters[Adapter].cfgs;
+ WineD3D_PixelFormat *cfgs = adapter->cfgs;
int it;
/* Check if there is a WGL pixel format matching the requirements, the pixel format should also be usable with pbuffers */
- for (it = 0; it < Adapters[Adapter].nCfgs; ++it) {
- if (cfgs[it].pbufferDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&cfgs[it], CheckFormat)) {
- TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n", cfgs[it].iPixelFormat, debug_d3dformat(CheckFormat));
+ for (it = 0; it < adapter->nCfgs; ++it)
+ {
+ if (cfgs[it].pbufferDrawable && IWineD3DImpl_IsPixelFormatCompatibleWithRenderFmt(&adapter->gl_info,
+ &cfgs[it], check_format_desc))
+ {
+ TRACE_(d3d_caps)("iPixelFormat=%d is compatible with CheckFormat=%s\n",
+ cfgs[it].iPixelFormat, debug_d3dformat(check_format_desc->format));
return TRUE;
}
}
return FALSE;
}
-static BOOL CheckSrgbReadCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
+static BOOL CheckSrgbReadCapability(struct WineD3DAdapter *adapter, const struct GlPixelFormatDesc *format_desc)
{
+ const WineD3D_GL_Info *gl_info = &adapter->gl_info;
+
/* Check for supported sRGB formats (Texture loading and framebuffer) */
if(!GL_SUPPORT(EXT_TEXTURE_SRGB)) {
TRACE_(d3d_caps)("[FAILED] GL_EXT_texture_sRGB not supported\n");
return FALSE;
}
- switch (CheckFormat) {
+ switch (format_desc->format)
+ {
case WINED3DFMT_A8R8G8B8:
case WINED3DFMT_X8R8G8B8:
case WINED3DFMT_A4R4G4B4:
return TRUE;
default:
- TRACE_(d3d_caps)("[FAILED] Gamma texture format %s not supported.\n", debug_d3dformat(CheckFormat));
+ TRACE_(d3d_caps)("[FAILED] Gamma texture format %s not supported.\n", debug_d3dformat(format_desc->format));
return FALSE;
}
return FALSE;
}
-static BOOL CheckSrgbWriteCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat)
+static BOOL CheckSrgbWriteCapability(struct WineD3DAdapter *adapter,
+ WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc)
{
/* Only offer SRGB writing on X8R8G8B8/A8R8G8B8 when we use ARB or GLSL shaders as we are
* doing the color fixup in shaders.
* Note Windows drivers (at least on the Geforce 8800) also offer this on R5G6B5. */
- if((CheckFormat == WINED3DFMT_X8R8G8B8) || (CheckFormat == WINED3DFMT_A8R8G8B8)) {
+ if ((format_desc->format == WINED3DFMT_X8R8G8B8) || (format_desc->format == WINED3DFMT_A8R8G8B8))
+ {
int vs_selected_mode;
int ps_selected_mode;
- select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode);
+ select_shader_mode(&adapter->gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
if((ps_selected_mode == SHADER_ARB) || (ps_selected_mode == SHADER_GLSL)) {
TRACE_(d3d_caps)("[OK]\n");
}
}
- TRACE_(d3d_caps)("[FAILED] - no SRGB writing support on format=%s\n", debug_d3dformat(CheckFormat));
+ TRACE_(d3d_caps)("[FAILED] - no SRGB writing support on format=%s\n", debug_d3dformat(format_desc->format));
return FALSE;
}
/* Check if a format support blending in combination with pixel shaders */
-static BOOL CheckPostPixelShaderBlendingCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
+static BOOL CheckPostPixelShaderBlendingCapability(struct WineD3DAdapter *adapter,
+ const struct GlPixelFormatDesc *format_desc)
{
- const GlPixelFormatDesc *glDesc;
- const StaticPixelFormatDesc *desc = getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
-
- /* Fail if we weren't able to get a description of the format */
- if(!desc || !glDesc)
- return FALSE;
-
/* The flags entry of a format contains the post pixel shader blending capability */
- if(glDesc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING)
- return TRUE;
+ if (format_desc->Flags & WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING) return TRUE;
return FALSE;
}
-static BOOL CheckWrapAndMipCapability(UINT Adapter, WINED3DFORMAT CheckFormat) {
+static BOOL CheckWrapAndMipCapability(struct WineD3DAdapter *adapter, const struct GlPixelFormatDesc *format_desc)
+{
/* OpenGL supports mipmapping on all formats basically. Wrapping is unsupported,
* but we have to report mipmapping so we cannot reject this flag. Tests show that
* windows reports WRAPANDMIP on unfilterable surfaces as well, apparently to show
}
/* Check if a texture format is supported on the given adapter */
-static BOOL CheckTextureCapability(UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat)
+static BOOL CheckTextureCapability(struct WineD3DAdapter *adapter,
+ WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *format_desc)
{
+ const WineD3D_GL_Info *gl_info = &adapter->gl_info;
const shader_backend_t *shader_backend;
const struct fragment_pipeline *fp;
- const GlPixelFormatDesc *glDesc;
-
- switch (CheckFormat) {
+ switch (format_desc->format)
+ {
/*****
* supported: RGB(A) formats
*/
case WINED3DFMT_X1R5G5B5:
case WINED3DFMT_A1R5G5B5:
case WINED3DFMT_A4R4G4B4:
- case WINED3DFMT_A8:
+ case WINED3DFMT_A8_UNORM:
case WINED3DFMT_X4R4G4B4:
- case WINED3DFMT_A8B8G8R8:
+ case WINED3DFMT_R8G8B8A8_UNORM:
case WINED3DFMT_X8B8G8R8:
case WINED3DFMT_A2R10G10B10:
- case WINED3DFMT_A2B10G10R10:
- case WINED3DFMT_G16R16:
+ case WINED3DFMT_R10G10B10A2_UNORM:
+ case WINED3DFMT_R16G16_UNORM:
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
* Supported: Depth/Stencil formats
*/
case WINED3DFMT_D16_LOCKABLE:
- case WINED3DFMT_D16:
+ case WINED3DFMT_D16_UNORM:
case WINED3DFMT_D15S1:
case WINED3DFMT_D24X8:
case WINED3DFMT_D24X4S4:
* Not supported everywhere(depends on GL_ATI_envmap_bumpmap or
* GL_NV_texture_shader). Emulated by shaders
*/
- case WINED3DFMT_V8U8:
+ case WINED3DFMT_R8G8_SNORM:
case WINED3DFMT_X8L8V8U8:
case WINED3DFMT_L6V5U5:
- case WINED3DFMT_Q8W8V8U8:
- case WINED3DFMT_V16U16:
- case WINED3DFMT_W11V11U10:
- getFormatDescEntry(CheckFormat, &GLINFO_LOCATION, &glDesc);
- if(glDesc->conversion_group == WINED3DFMT_UNKNOWN) {
- /* We have a GL extension giving native support */
- TRACE_(d3d_caps)("[OK]\n");
- return TRUE;
- }
-
- /* No native support: Ask the fixed function pipeline implementation if it
- * can deal with the conversion
- */
- shader_backend = select_shader_backend(Adapter, DeviceType);
- if(shader_backend->shader_conv_supported(CheckFormat)) {
+ case WINED3DFMT_R8G8B8A8_SNORM:
+ case WINED3DFMT_R16G16_SNORM:
+ /* Ask the shader backend if it can deal with the conversion. If
+ * we've got a GL extension giving native support this will be an
+ * identity conversion. */
+ shader_backend = select_shader_backend(adapter, DeviceType);
+ if (shader_backend->shader_color_fixup_supported(format_desc->color_fixup))
+ {
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
- } else {
- TRACE_(d3d_caps)("[FAILED]\n");
- return FALSE;
}
+ TRACE_(d3d_caps)("[FAILED]\n");
+ return FALSE;
case WINED3DFMT_DXT1:
case WINED3DFMT_DXT2:
* Odd formats - not supported
*/
case WINED3DFMT_VERTEXDATA:
- case WINED3DFMT_INDEX16:
- case WINED3DFMT_INDEX32:
- case WINED3DFMT_Q16W16V16U16:
+ case WINED3DFMT_R16_UINT:
+ case WINED3DFMT_R32_UINT:
+ case WINED3DFMT_R16G16B16A16_SNORM:
case WINED3DFMT_A2W10V10U10:
+ case WINED3DFMT_W11V11U10:
TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
return FALSE;
return FALSE;
/* Not supported */
- case WINED3DFMT_A16B16G16R16:
+ case WINED3DFMT_R16G16B16A16_UNORM:
case WINED3DFMT_A8R3G3B2:
TRACE_(d3d_caps)("[FAILED]\n"); /* Enable when implemented */
return FALSE;
/* Floating point formats */
- case WINED3DFMT_R16F:
- case WINED3DFMT_A16B16G16R16F:
+ case WINED3DFMT_R16_FLOAT:
+ case WINED3DFMT_R16G16_FLOAT:
+ case WINED3DFMT_R16G16B16A16_FLOAT:
if(GL_SUPPORT(ARB_TEXTURE_FLOAT) && GL_SUPPORT(ARB_HALF_FLOAT_PIXEL)) {
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
TRACE_(d3d_caps)("[FAILED]\n");
return FALSE;
- case WINED3DFMT_R32F:
- case WINED3DFMT_A32B32G32R32F:
+ case WINED3DFMT_R32_FLOAT:
+ case WINED3DFMT_R32G32_FLOAT:
+ case WINED3DFMT_R32G32B32A32_FLOAT:
if (GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
TRACE_(d3d_caps)("[FAILED]\n");
return FALSE;
- case WINED3DFMT_G16R16F:
- case WINED3DFMT_G32R32F:
- TRACE_(d3d_caps)("[FAILED]\n");
- return FALSE;
-
/* ATI instancing hack: Although ATI cards do not support Shader Model 3.0, they support
* instancing. To query if the card supports instancing CheckDeviceFormat with the special format
* MAKEFOURCC('I','N','S','T') is used. Should a (broken) app check for this provide a proper return value.
/* Vendor specific formats */
case WINED3DFMT_ATI2N:
if(GL_SUPPORT(ATI_TEXTURE_COMPRESSION_3DC) || GL_SUPPORT(EXT_TEXTURE_COMPRESSION_RGTC)) {
- shader_backend = select_shader_backend(Adapter, DeviceType);
- fp = select_fragment_implementation(Adapter, DeviceType);
- if(shader_backend->shader_conv_supported(CheckFormat) &&
- fp->conv_supported(CheckFormat)) {
+ shader_backend = select_shader_backend(adapter, DeviceType);
+ fp = select_fragment_implementation(adapter, DeviceType);
+ if (shader_backend->shader_color_fixup_supported(format_desc->color_fixup)
+ && fp->color_fixup_supported(format_desc->color_fixup))
+ {
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
}
return FALSE;
default:
- ERR("Unhandled format=%s\n", debug_d3dformat(CheckFormat));
+ ERR("Unhandled format=%s\n", debug_d3dformat(format_desc->format));
break;
}
return FALSE;
}
-static BOOL CheckSurfaceCapability(UINT Adapter, WINED3DFORMAT AdapterFormat, WINED3DDEVTYPE DeviceType, WINED3DFORMAT CheckFormat, WINED3DSURFTYPE SurfaceType) {
+static BOOL CheckSurfaceCapability(struct WineD3DAdapter *adapter, const struct GlPixelFormatDesc *adapter_format_desc,
+ WINED3DDEVTYPE DeviceType, const struct GlPixelFormatDesc *check_format_desc, WINED3DSURFTYPE SurfaceType)
+{
const struct blit_shader *blitter;
if(SurfaceType == SURFACE_GDI) {
- switch(CheckFormat) {
+ switch(check_format_desc->format)
+ {
case WINED3DFMT_R8G8B8:
case WINED3DFMT_A8R8G8B8:
case WINED3DFMT_X8R8G8B8:
case WINED3DFMT_A1R5G5B5:
case WINED3DFMT_A4R4G4B4:
case WINED3DFMT_R3G3B2:
- case WINED3DFMT_A8:
+ case WINED3DFMT_A8_UNORM:
case WINED3DFMT_A8R3G3B2:
case WINED3DFMT_X4R4G4B4:
- case WINED3DFMT_A2B10G10R10:
- case WINED3DFMT_A8B8G8R8:
+ case WINED3DFMT_R10G10B10A2_UNORM:
+ case WINED3DFMT_R8G8B8A8_UNORM:
case WINED3DFMT_X8B8G8R8:
- case WINED3DFMT_G16R16:
+ case WINED3DFMT_R16G16_UNORM:
case WINED3DFMT_A2R10G10B10:
- case WINED3DFMT_A16B16G16R16:
+ case WINED3DFMT_R16G16B16A16_UNORM:
case WINED3DFMT_P8:
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
}
/* All format that are supported for textures are supported for surfaces as well */
- if(CheckTextureCapability(Adapter, DeviceType, CheckFormat)) return TRUE;
+ if (CheckTextureCapability(adapter, DeviceType, check_format_desc)) return TRUE;
/* All depth stencil formats are supported on surfaces */
- if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) return TRUE;
+ if (CheckDepthStencilCapability(adapter, adapter_format_desc, check_format_desc)) return TRUE;
/* If opengl can't process the format natively, the blitter may be able to convert it */
- blitter = select_blit_implementation(Adapter, DeviceType);
- if(blitter->conv_supported(CheckFormat)) {
+ blitter = select_blit_implementation(adapter, DeviceType);
+ if (blitter->color_fixup_supported(check_format_desc->color_fixup))
+ {
TRACE_(d3d_caps)("[OK]\n");
return TRUE;
}
return FALSE;
}
-static BOOL CheckVertexTextureCapability(UINT Adapter, WINED3DFORMAT CheckFormat)
+static BOOL CheckVertexTextureCapability(struct WineD3DAdapter *adapter, const struct GlPixelFormatDesc *format_desc)
{
+ const WineD3D_GL_Info *gl_info = &adapter->gl_info;
+
if (!GL_LIMITS(vertex_samplers)) {
TRACE_(d3d_caps)("[FAILED]\n");
return FALSE;
}
- switch (CheckFormat) {
- case WINED3DFMT_A32B32G32R32F:
+ switch (format_desc->format)
+ {
+ case WINED3DFMT_R32G32B32A32_FLOAT:
if (!GL_SUPPORT(ARB_TEXTURE_FLOAT)) {
TRACE_(d3d_caps)("[FAILED]\n");
return FALSE;
WINED3DFORMAT AdapterFormat, DWORD Usage, WINED3DRESOURCETYPE RType, WINED3DFORMAT CheckFormat,
WINED3DSURFTYPE SurfaceType) {
IWineD3DImpl *This = (IWineD3DImpl *)iface;
+ struct WineD3DAdapter *adapter = &This->adapters[Adapter];
+ const WineD3D_GL_Info *gl_info = &adapter->gl_info;
+ const struct GlPixelFormatDesc *format_desc = getFormatDescEntry(CheckFormat, gl_info);
+ const struct GlPixelFormatDesc *adapter_format_desc = getFormatDescEntry(AdapterFormat, gl_info);
DWORD UsageCaps = 0;
TRACE_(d3d_caps)("(%p)-> (STUB) (Adptr:%d, DevType:(%u,%s), AdptFmt:(%u,%s), Use:(%u,%s,%s), ResTyp:(%x,%s), CheckFmt:(%u,%s))\n",
*/
if(GL_SUPPORT(ARB_TEXTURE_CUBE_MAP)) {
/* Check if the texture format is around */
- if(CheckTextureCapability(Adapter, DeviceType, CheckFormat)) {
+ if (CheckTextureCapability(adapter, DeviceType, format_desc))
+ {
if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
/* Check for automatic mipmap generation support */
if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
UsageCaps |= WINED3DUSAGE_DYNAMIC;
if(Usage & WINED3DUSAGE_RENDERTARGET) {
- if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
+ if(CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_RENDERTARGET;
} else {
TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
/* Check QUERY_FILTER support */
if(Usage & WINED3DUSAGE_QUERY_FILTER) {
- if(CheckFilterCapability(Adapter, CheckFormat)) {
+ if (CheckFilterCapability(adapter, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
} else {
TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
/* Check QUERY_POSTPIXELSHADER_BLENDING support */
if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
- if(CheckPostPixelShaderBlendingCapability(Adapter, CheckFormat)) {
+ if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
} else {
TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
/* Check QUERY_SRGBREAD support */
if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
- if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
+ if (CheckSrgbReadCapability(adapter, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
} else {
TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
/* Check QUERY_SRGBWRITE support */
if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
- if(CheckSrgbWriteCapability(Adapter, DeviceType, CheckFormat)) {
+ if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
} else {
TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
/* Check QUERY_VERTEXTEXTURE support */
if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
- if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
+ if (CheckVertexTextureCapability(adapter, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
} else {
TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
/* Check QUERY_WRAPANDMIP support */
if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
- if(CheckWrapAndMipCapability(Adapter, CheckFormat)) {
+ if (CheckWrapAndMipCapability(adapter, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
} else {
TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
* - D3DUSAGE_RENDERTARGET
*/
- if(CheckSurfaceCapability(Adapter, AdapterFormat, DeviceType, CheckFormat, SurfaceType)) {
+ if (CheckSurfaceCapability(adapter, adapter_format_desc, DeviceType, format_desc, SurfaceType))
+ {
if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
- if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) {
+ if (CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
} else {
TRACE_(d3d_caps)("[FAILED] - No depthstencil support\n");
}
if(Usage & WINED3DUSAGE_RENDERTARGET) {
- if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
+ if (CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_RENDERTARGET;
} else {
TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
/* Check QUERY_POSTPIXELSHADER_BLENDING support */
if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
- if(CheckPostPixelShaderBlendingCapability(Adapter, CheckFormat)) {
+ if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
} else {
TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
}
/* Check if the texture format is around */
- if(CheckTextureCapability(Adapter, DeviceType, CheckFormat)) {
+ if (CheckTextureCapability(adapter, DeviceType, format_desc))
+ {
if(Usage & WINED3DUSAGE_AUTOGENMIPMAP) {
/* Check for automatic mipmap generation support */
if(GL_SUPPORT(SGIS_GENERATE_MIPMAP)) {
UsageCaps |= WINED3DUSAGE_DYNAMIC;
if(Usage & WINED3DUSAGE_RENDERTARGET) {
- if(CheckRenderTargetCapability(AdapterFormat, CheckFormat)) {
+ if (CheckRenderTargetCapability(adapter, adapter_format_desc, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_RENDERTARGET;
} else {
TRACE_(d3d_caps)("[FAILED] - No rendertarget support\n");
/* Check QUERY_FILTER support */
if(Usage & WINED3DUSAGE_QUERY_FILTER) {
- if(CheckFilterCapability(Adapter, CheckFormat)) {
+ if (CheckFilterCapability(adapter, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
} else {
TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
/* Check QUERY_LEGACYBUMPMAP support */
if(Usage & WINED3DUSAGE_QUERY_LEGACYBUMPMAP) {
- if(CheckBumpMapCapability(Adapter, DeviceType, CheckFormat)) {
+ if (CheckBumpMapCapability(adapter, DeviceType, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_LEGACYBUMPMAP;
} else {
TRACE_(d3d_caps)("[FAILED] - No legacy bumpmap support\n");
/* Check QUERY_POSTPIXELSHADER_BLENDING support */
if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
- if(CheckPostPixelShaderBlendingCapability(Adapter, CheckFormat)) {
+ if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
} else {
TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
/* Check QUERY_SRGBREAD support */
if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
- if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
+ if (CheckSrgbReadCapability(adapter, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
} else {
TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
/* Check QUERY_SRGBWRITE support */
if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
- if(CheckSrgbWriteCapability(Adapter, DeviceType, CheckFormat)) {
+ if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
} else {
TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
/* Check QUERY_VERTEXTEXTURE support */
if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
- if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
+ if (CheckVertexTextureCapability(adapter, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
} else {
TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
/* Check QUERY_WRAPANDMIP support */
if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
- if(CheckWrapAndMipCapability(Adapter, CheckFormat)) {
+ if (CheckWrapAndMipCapability(adapter, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
} else {
TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
}
if(Usage & WINED3DUSAGE_DEPTHSTENCIL) {
- if(CheckDepthStencilCapability(Adapter, AdapterFormat, CheckFormat)) {
+ if (CheckDepthStencilCapability(adapter, adapter_format_desc, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_DEPTHSTENCIL;
} else {
TRACE_(d3d_caps)("[FAILED] - No depth stencil support\n");
/* Check volume texture and volume usage caps */
if(GL_SUPPORT(EXT_TEXTURE3D)) {
- if(CheckTextureCapability(Adapter, DeviceType, CheckFormat) == FALSE) {
+ if (!CheckTextureCapability(adapter, DeviceType, format_desc))
+ {
TRACE_(d3d_caps)("[FAILED] - Format not supported\n");
return WINED3DERR_NOTAVAILABLE;
}
/* Check QUERY_FILTER support */
if(Usage & WINED3DUSAGE_QUERY_FILTER) {
- if(CheckFilterCapability(Adapter, CheckFormat)) {
+ if (CheckFilterCapability(adapter, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_FILTER;
} else {
TRACE_(d3d_caps)("[FAILED] - No query filter support\n");
/* Check QUERY_POSTPIXELSHADER_BLENDING support */
if(Usage & WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING) {
- if(CheckPostPixelShaderBlendingCapability(Adapter, CheckFormat)) {
+ if (CheckPostPixelShaderBlendingCapability(adapter, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING;
} else {
TRACE_(d3d_caps)("[FAILED] - No query post pixelshader blending support\n");
/* Check QUERY_SRGBREAD support */
if(Usage & WINED3DUSAGE_QUERY_SRGBREAD) {
- if(CheckSrgbReadCapability(Adapter, CheckFormat)) {
+ if (CheckSrgbReadCapability(adapter, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_SRGBREAD;
} else {
TRACE_(d3d_caps)("[FAILED] - No query srgbread support\n");
/* Check QUERY_SRGBWRITE support */
if(Usage & WINED3DUSAGE_QUERY_SRGBWRITE) {
- if(CheckSrgbWriteCapability(Adapter, DeviceType, CheckFormat)) {
+ if (CheckSrgbWriteCapability(adapter, DeviceType, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_SRGBWRITE;
} else {
TRACE_(d3d_caps)("[FAILED] - No query srgbwrite support\n");
/* Check QUERY_VERTEXTEXTURE support */
if(Usage & WINED3DUSAGE_QUERY_VERTEXTEXTURE) {
- if(CheckVertexTextureCapability(Adapter, CheckFormat)) {
+ if (CheckVertexTextureCapability(adapter, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_VERTEXTEXTURE;
} else {
TRACE_(d3d_caps)("[FAILED] - No query vertextexture support\n");
/* Check QUERY_WRAPANDMIP support */
if(Usage & WINED3DUSAGE_QUERY_WRAPANDMIP) {
- if(CheckWrapAndMipCapability(Adapter, CheckFormat)) {
+ if (CheckWrapAndMipCapability(adapter, format_desc))
+ {
UsageCaps |= WINED3DUSAGE_QUERY_WRAPANDMIP;
} else {
TRACE_(d3d_caps)("[FAILED] - No wrapping and mipmapping support\n");
switch(CheckFormat) {
case WINED3DFMT_P8:
case WINED3DFMT_A4L4:
- case WINED3DFMT_R32F:
- case WINED3DFMT_R16F:
+ case WINED3DFMT_R32_FLOAT:
+ case WINED3DFMT_R16_FLOAT:
case WINED3DFMT_X8L8V8U8:
case WINED3DFMT_L6V5U5:
- case WINED3DFMT_G16R16:
+ case WINED3DFMT_R16G16_UNORM:
TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
return WINED3DERR_NOTAVAILABLE;
- case WINED3DFMT_Q8W8V8U8:
- case WINED3DFMT_V16U16:
+ case WINED3DFMT_R8G8B8A8_SNORM:
+ case WINED3DFMT_R16G16_SNORM:
if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
return WINED3DERR_NOTAVAILABLE;
}
break;
- case WINED3DFMT_V8U8:
+ case WINED3DFMT_R8G8_SNORM:
if(!GL_SUPPORT(NV_TEXTURE_SHADER)) {
TRACE_(d3d_caps)("[FAILED] - No converted formats on volumes\n");
return WINED3DERR_NOTAVAILABLE;
/* Do nothing, continue with checking the format below */
break;
}
- } else if((RType == WINED3DRTYPE_INDEXBUFFER) || (RType == WINED3DRTYPE_VERTEXBUFFER)){
+ } else if(RType == WINED3DRTYPE_BUFFER){
/* For instance vertexbuffer/indexbuffer aren't supported yet because no Windows drivers seem to offer it */
TRACE_(d3d_caps)("Unhandled resource type D3DRTYPE_INDEXBUFFER / D3DRTYPE_VERTEXBUFFER\n");
return WINED3DERR_NOTAVAILABLE;
return WINED3D_OK;
}
-static const shader_backend_t *select_shader_backend(UINT Adapter, WINED3DDEVTYPE DeviceType) {
+static const shader_backend_t *select_shader_backend(struct WineD3DAdapter *adapter, WINED3DDEVTYPE DeviceType)
+{
const shader_backend_t *ret;
int vs_selected_mode;
int ps_selected_mode;
- select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode);
+ select_shader_mode(&adapter->gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
if (vs_selected_mode == SHADER_GLSL || ps_selected_mode == SHADER_GLSL) {
ret = &glsl_shader_backend;
} else if (vs_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_ARB) {
return ret;
}
-static const struct fragment_pipeline *select_fragment_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType) {
+static const struct fragment_pipeline *select_fragment_implementation(struct WineD3DAdapter *adapter,
+ WINED3DDEVTYPE DeviceType)
+{
+ const WineD3D_GL_Info *gl_info = &adapter->gl_info;
int vs_selected_mode;
int ps_selected_mode;
- select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode);
+ select_shader_mode(&adapter->gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
if((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL) && GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
return &arbfp_fragment_pipeline;
} else if(ps_selected_mode == SHADER_ATI) {
}
}
-static const struct blit_shader *select_blit_implementation(UINT Adapter, WINED3DDEVTYPE DeviceType) {
+static const struct blit_shader *select_blit_implementation(struct WineD3DAdapter *adapter, WINED3DDEVTYPE DeviceType)
+{
+ const WineD3D_GL_Info *gl_info = &adapter->gl_info;
int vs_selected_mode;
int ps_selected_mode;
- select_shader_mode(&GLINFO_LOCATION, DeviceType, &ps_selected_mode, &vs_selected_mode);
+ select_shader_mode(&adapter->gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
if((ps_selected_mode == SHADER_ARB || ps_selected_mode == SHADER_GLSL) && GL_SUPPORT(ARB_FRAGMENT_PROGRAM)) {
return &arbfp_blit;
} else {
static HRESULT WINAPI IWineD3DImpl_GetDeviceCaps(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, WINED3DCAPS* pCaps) {
IWineD3DImpl *This = (IWineD3DImpl *)iface;
+ struct WineD3DAdapter *adapter = &This->adapters[Adapter];
+ const WineD3D_GL_Info *gl_info = &adapter->gl_info;
int vs_selected_mode;
int ps_selected_mode;
struct shader_caps shader_caps;
return WINED3DERR_INVALIDCALL;
}
- select_shader_mode(&Adapters[Adapter].gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
+ select_shader_mode(&adapter->gl_info, DeviceType, &ps_selected_mode, &vs_selected_mode);
/* This function should *not* be modifying GL caps
* TODO: move the functionality where it belongs */
- select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[Adapter].gl_info);
+ select_shader_max_constants(ps_selected_mode, vs_selected_mode, &adapter->gl_info);
/* ------------------------------------------------
The following fields apply to both d3d8 and d3d9
pCaps->RasterCaps |= WINED3DPRASTERCAPS_FOGRANGE;
}
/* FIXME Add:
- WINED3DPRASTERCAPS_COLORPERSPECTIVE
- WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
- WINED3DPRASTERCAPS_ANTIALIASEDGES
- WINED3DPRASTERCAPS_ZBUFFERLESSHSR
- WINED3DPRASTERCAPS_WBUFFER */
+ WINED3DPRASTERCAPS_COLORPERSPECTIVE
+ WINED3DPRASTERCAPS_STRETCHBLTMULTISAMPLE
+ WINED3DPRASTERCAPS_ANTIALIASEDGES
+ WINED3DPRASTERCAPS_ZBUFFERLESSHSR
+ WINED3DPRASTERCAPS_WBUFFER */
pCaps->ZCmpCaps = WINED3DPCMPCAPS_ALWAYS |
WINED3DPCMPCAPS_EQUAL |
pCaps->VertexTextureFilterCaps = 0;
memset(&shader_caps, 0, sizeof(shader_caps));
- shader_backend = select_shader_backend(Adapter, DeviceType);
- shader_backend->shader_get_caps(DeviceType, &GLINFO_LOCATION, &shader_caps);
+ shader_backend = select_shader_backend(adapter, DeviceType);
+ shader_backend->shader_get_caps(DeviceType, &adapter->gl_info, &shader_caps);
memset(&fragment_caps, 0, sizeof(fragment_caps));
- frag_pipeline = select_fragment_implementation(Adapter, DeviceType);
- frag_pipeline->get_caps(DeviceType, &GLINFO_LOCATION, &fragment_caps);
+ frag_pipeline = select_fragment_implementation(adapter, DeviceType);
+ frag_pipeline->get_caps(DeviceType, &adapter->gl_info, &fragment_caps);
/* Add shader misc caps. Only some of them belong to the shader parts of the pipeline */
pCaps->PrimitiveMiscCaps |= fragment_caps.PrimitiveMiscCaps;
use the VS 3.0 from MSDN or else if there's OpenGL spec use a hardcoded value minimum VS3.0 value. */
pCaps->VS20Caps.Caps = WINED3DVS20CAPS_PREDICATION;
pCaps->VS20Caps.DynamicFlowControlDepth = WINED3DVS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* VS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
- pCaps->VS20Caps.NumTemps = max(32, GLINFO_LOCATION.vs_arb_max_temps);
+ pCaps->VS20Caps.NumTemps = max(32, adapter->gl_info.vs_arb_max_temps);
pCaps->VS20Caps.StaticFlowControlDepth = WINED3DVS20_MAX_STATICFLOWCONTROLDEPTH ; /* level of nesting in loops / if-statements; VS 3.0 requires MAX (4) */
pCaps->MaxVShaderInstructionsExecuted = 65535; /* VS 3.0 needs at least 65535, some cards even use 2^32-1 */
- pCaps->MaxVertexShader30InstructionSlots = max(512, GLINFO_LOCATION.vs_arb_max_instructions);
+ pCaps->MaxVertexShader30InstructionSlots = max(512, adapter->gl_info.vs_arb_max_instructions);
} else if(pCaps->VertexShaderVersion == WINED3DVS_VERSION(2,0)) {
pCaps->VS20Caps.Caps = 0;
pCaps->VS20Caps.DynamicFlowControlDepth = WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH;
- pCaps->VS20Caps.NumTemps = max(12, GLINFO_LOCATION.vs_arb_max_temps);
+ pCaps->VS20Caps.NumTemps = max(12, adapter->gl_info.vs_arb_max_temps);
pCaps->VS20Caps.StaticFlowControlDepth = 1;
pCaps->MaxVShaderInstructionsExecuted = 65535;
WINED3DPS20CAPS_NODEPENDENTREADLIMIT |
WINED3DPS20CAPS_NOTEXINSTRUCTIONLIMIT;
pCaps->PS20Caps.DynamicFlowControlDepth = WINED3DPS20_MAX_DYNAMICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_DYNAMICFLOWCONTROLDEPTH (24) */
- pCaps->PS20Caps.NumTemps = max(32, GLINFO_LOCATION.ps_arb_max_temps);
+ pCaps->PS20Caps.NumTemps = max(32, adapter->gl_info.ps_arb_max_temps);
pCaps->PS20Caps.StaticFlowControlDepth = WINED3DPS20_MAX_STATICFLOWCONTROLDEPTH; /* PS 3.0 requires MAX_STATICFLOWCONTROLDEPTH (4) */
pCaps->PS20Caps.NumInstructionSlots = WINED3DPS20_MAX_NUMINSTRUCTIONSLOTS; /* PS 3.0 requires MAX_NUMINSTRUCTIONSLOTS (512) */
pCaps->MaxPShaderInstructionsExecuted = 65535;
- pCaps->MaxPixelShader30InstructionSlots = max(WINED3DMIN30SHADERINSTRUCTIONS, GLINFO_LOCATION.ps_arb_max_instructions);
+ pCaps->MaxPixelShader30InstructionSlots = max(WINED3DMIN30SHADERINSTRUCTIONS, adapter->gl_info.ps_arb_max_instructions);
} else if(pCaps->PixelShaderVersion == WINED3DPS_VERSION(2,0)) {
/* Below we assume PS2.0 specs, not extended 2.0a(GeforceFX)/2.0b(Radeon R3xx) ones */
pCaps->PS20Caps.Caps = 0;
pCaps->PS20Caps.DynamicFlowControlDepth = 0; /* WINED3DVS20_MIN_DYNAMICFLOWCONTROLDEPTH = 0 */
- pCaps->PS20Caps.NumTemps = max(12, GLINFO_LOCATION.ps_arb_max_temps);
+ pCaps->PS20Caps.NumTemps = max(12, adapter->gl_info.ps_arb_max_temps);
pCaps->PS20Caps.StaticFlowControlDepth = WINED3DPS20_MIN_STATICFLOWCONTROLDEPTH; /* Minimum: 1 */
pCaps->PS20Caps.NumInstructionSlots = WINED3DPS20_MIN_NUMINSTRUCTIONSLOTS; /* Minimum number (64 ALU + 32 Texture), a GeforceFX uses 512 */
WINED3DDTCAPS_UBYTE4N |
WINED3DDTCAPS_SHORT2N |
WINED3DDTCAPS_SHORT4N;
- if (GL_SUPPORT(NV_HALF_FLOAT)) {
+ if (GL_SUPPORT(ARB_HALF_FLOAT_VERTEX)) {
pCaps->DeclTypes |= WINED3DDTCAPS_FLOAT16_2 |
WINED3DDTCAPS_FLOAT16_4;
}
pCaps->DirectDrawCaps.StrideAlign = DDRAW_PITCH_ALIGNMENT;
/* Set D3D caps if OpenGL is available. */
- if(Adapters[Adapter].opengl) {
+ if (adapter->opengl)
+ {
pCaps->DirectDrawCaps.ddsCaps |=WINEDDSCAPS_3DDEVICE |
WINEDDSCAPS_MIPMAP |
WINEDDSCAPS_TEXTURE |
/* Note due to structure differences between dx8 and dx9 D3DPRESENT_PARAMETERS,
and fields being inserted in the middle, a new structure is used in place */
-static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter, WINED3DDEVTYPE DeviceType, HWND hFocusWindow,
- DWORD BehaviourFlags, IWineD3DDevice** ppReturnedDeviceInterface,
- IUnknown *parent) {
-
+static HRESULT WINAPI IWineD3DImpl_CreateDevice(IWineD3D *iface, UINT Adapter,
+ WINED3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviourFlags, IUnknown *parent,
+ IWineD3DDeviceParent *device_parent, IWineD3DDevice **ppReturnedDeviceInterface)
+{
IWineD3DDeviceImpl *object = NULL;
IWineD3DImpl *This = (IWineD3DImpl *)iface;
+ struct WineD3DAdapter *adapter = &This->adapters[Adapter];
WINED3DDISPLAYMODE mode;
const struct fragment_pipeline *frag_pipeline = NULL;
int i;
struct fragment_caps ffp_caps;
+ struct shader_caps shader_caps;
+ HRESULT hr;
/* Validate the adapter number. If no adapters are available(no GL), ignore the adapter
* number and create a device without a 3D adapter for 2D only operation.
object->lpVtbl = &IWineD3DDevice_Vtbl;
object->ref = 1;
object->wineD3D = iface;
- object->adapter = numAdapters ? &Adapters[Adapter] : NULL;
+ object->adapter = This->adapter_count ? adapter : NULL;
IWineD3D_AddRef(object->wineD3D);
object->parent = parent;
+ object->device_parent = device_parent;
list_init(&object->resources);
list_init(&object->shaders);
object->adapterNo = Adapter;
object->devType = DeviceType;
- select_shader_mode(&GLINFO_LOCATION, DeviceType, &object->ps_selected_mode, &object->vs_selected_mode);
- object->shader_backend = select_shader_backend(Adapter, DeviceType);
+ select_shader_mode(&adapter->gl_info, DeviceType,
+ &object->ps_selected_mode, &object->vs_selected_mode);
+ object->shader_backend = select_shader_backend(adapter, DeviceType);
+
+ memset(&shader_caps, 0, sizeof(shader_caps));
+ object->shader_backend->shader_get_caps(DeviceType, &adapter->gl_info, &shader_caps);
+ object->d3d_vshader_constantF = shader_caps.MaxVertexShaderConst;
+ object->d3d_pshader_constantF = shader_caps.MaxPixelShaderConst;
memset(&ffp_caps, 0, sizeof(ffp_caps));
- frag_pipeline = select_fragment_implementation(Adapter, DeviceType);
+ frag_pipeline = select_fragment_implementation(adapter, DeviceType);
object->frag_pipe = frag_pipeline;
- frag_pipeline->get_caps(DeviceType, &GLINFO_LOCATION, &ffp_caps);
+ frag_pipeline->get_caps(DeviceType, &adapter->gl_info, &ffp_caps);
object->max_ffp_textures = ffp_caps.MaxSimultaneousTextures;
object->max_ffp_texture_stages = ffp_caps.MaxTextureBlendStages;
- compile_state_table(object->StateTable, object->multistate_funcs, &GLINFO_LOCATION,
+ hr = compile_state_table(object->StateTable, object->multistate_funcs, &adapter->gl_info,
ffp_vertexstate_template, frag_pipeline, misc_state_template);
- object->blitter = select_blit_implementation(Adapter, DeviceType);
+ if (FAILED(hr)) {
+ IWineD3D_Release(object->wineD3D);
+ HeapFree(GetProcessHeap(), 0, object);
- /* Prefer the vtable with functions optimized for single dirtifyable objects if the shader
- * model can deal with that. It is essentially the same, just with adjusted
- * Set*ShaderConstantF implementations
- */
- if(object->shader_backend->shader_dirtifyable_constants((IWineD3DDevice *) object)) {
- object->lpVtbl = &IWineD3DDevice_DirtyConst_Vtbl;
+ return hr;
}
+ object->blitter = select_blit_implementation(adapter, DeviceType);
+
/* set the state of the device to valid */
object->state = WINED3D_OK;
for(i = 0; i < PATCHMAP_SIZE; i++) {
list_init(&object->patches[i]);
}
+
+ IWineD3DDeviceParent_WineD3DDeviceCreated(device_parent, *ppReturnedDeviceInterface);
+
return WINED3D_OK;
}
-#undef GLINFO_LOCATION
static HRESULT WINAPI IWineD3DImpl_GetParent(IWineD3D *iface, IUnknown **pParent) {
IWineD3DImpl *This = (IWineD3DImpl *)iface;
return IUnknown_Release(volumeParent);
}
-static BOOL implementation_is_apple(WineD3D_GL_Info *gl_info) {
+static BOOL match_apple(const WineD3D_GL_Info *gl_info)
+{
/* MacOS has various specialities in the extensions it advertises. Some have to be loaded from
* the opengl 1.2+ core, while other extensions are advertised, but software emulated. So try to
* detect the Apple OpenGL implementation to apply some extension fixups afterwards.
}
}
-#define GLINFO_LOCATION (*gl_info)
static void test_pbo_functionality(WineD3D_GL_Info *gl_info) {
/* Some OpenGL implementations, namely Apple's Geforce 8 driver, advertises PBOs,
* but glTexSubImage from a PBO fails miserably, with the first line repeated over
while(glGetError());
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
checkGLcall("Specifying the PBO test texture\n");
TRACE_(d3d_caps)("PBO test successful\n");
}
}
-#undef GLINFO_LOCATION
/* Certain applications(Steam) complain if we report an outdated driver version. In general,
* reporting a driver version is moot because we are not the Windows driver, and we have different
struct driver_version_information {
WORD vendor; /* reported PCI card vendor ID */
WORD card; /* reported PCI card device ID */
+ const char *description; /* Description of the card e.g. NVIDIA RIVA TNT */
WORD hipart_hi, hipart_lo; /* driver hiword to report */
WORD lopart_hi, lopart_lo; /* driver loword to report */
};
static const struct driver_version_information driver_version_table[] = {
- /* Nvidia drivers. Geforce6 and newer cards are supported by the current driver (177.x)*/
- /* GeforceFX support is up to 173.x, Geforce2MX/3/4 up to 96.x, TNT/Geforce1/2 up to 71.x */
- /* Note that version numbers >100 lets say 123.45 use >= x.y.11.2345 and not x.y.10.12345 */
- {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5200, 7, 15, 11, 7341 },
- {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5600, 7, 15, 11, 7341 },
- {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5800, 7, 15, 11, 7341 },
- {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6200, 7, 15, 11, 7341 },
- {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6600GT, 7, 15, 11, 7341 },
- {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6800, 7, 15, 11, 7341 },
- {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7400, 7, 15, 11, 7341 },
- {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7300, 7, 15, 11, 7341 },
- {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7600, 7, 15, 11, 7341 },
- {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7800GT, 7, 15, 11, 7341 },
- {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8300GS, 7, 15, 11, 7341 },
- {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600GT, 7, 15, 11, 7341 },
- {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600MGT, 7, 15, 11, 7341 },
- {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8800GTS, 7, 15, 11, 7341 },
- {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9600GT, 7, 15, 11, 7341 },
- {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9800GT, 7, 15, 11, 7341 },
+ /* Nvidia drivers. Geforce6 and newer cards are supported by the current driver (180.x)
+ * GeforceFX support is up to 173.x, - driver uses numbering x.y.11.7341 for 173.41 where x is the windows revision (6=2000/xp, 7=vista), y is unknown
+ * Geforce2MX/3/4 up to 96.x - driver uses numbering 9.6.8.9 for 96.89
+ * TNT/Geforce1/2 up to 71.x - driver uses numbering 7.1.8.6 for 71.86
+ *
+ * All version numbers used below are from the Linux nvidia drivers.
+ */
+ {VENDOR_NVIDIA, CARD_NVIDIA_RIVA_TNT, "NVIDIA RIVA TNT", 7, 1, 8, 6 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_RIVA_TNT2, "NVIDIA RIVA TNT2/TNT2 Pro", 7, 1, 8, 6 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE, "NVIDIA GeForce 256", 7, 1, 8, 6 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE2_MX, "NVIDIA GeForce2 MX/MX 400", 9, 6, 4, 3 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE2, "NVIDIA GeForce2 GTS/GeForce2 Pro", 7, 1, 8, 6 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE3, "NVIDIA GeForce3", 9, 6, 4, 3 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE4_MX, "NVIDIA GeForce4 MX 460", 9, 6, 4, 3 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE4_TI4200, "NVIDIA GeForce4 Ti 4200", 9, 6, 4, 3 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5200, "NVIDIA GeForce FX 5200", 7, 15, 11, 7341 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5600, "NVIDIA GeForce FX 5600", 7, 15, 11, 7341 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCEFX_5800, "NVIDIA GeForce FX 5800", 7, 15, 11, 7341 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6200, "NVIDIA GeForce 6200", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6600GT, "NVIDIA GeForce 6600 GT", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_6800, "NVIDIA GeForce 6800", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7300, "NVIDIA GeForce Go 7300", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7400, "NVIDIA GeForce Go 7400", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7600, "NVIDIA GeForce 7600 GT", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_7800GT, "NVIDIA GeForce 7800 GT", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8300GS, "NVIDIA GeForce 8300 GS", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600GT, "NVIDIA GeForce 8600 GT", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8600MGT, "NVIDIA GeForce 8600M GT", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_8800GTS, "NVIDIA GeForce 8800 GTS", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9200, "NVIDIA GeForce 9200", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9400GT, "NVIDIA GeForce 9400 GT", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9500GT, "NVIDIA GeForce 9500 GT", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9600GT, "NVIDIA GeForce 9600 GT", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_9800GT, "NVIDIA GeForce 9800 GT", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX260, "NVIDIA GeForce GTX 260", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX275, "NVIDIA GeForce GTX 275", 7, 15, 11, 8044 },
+ {VENDOR_NVIDIA, CARD_NVIDIA_GEFORCE_GTX280, "NVIDIA GeForce GTX 280", 7, 15, 11, 8044 },
/* ATI cards. The driver versions are somewhat similar, but not quite the same. Let's hardcode */
- {VENDOR_ATI, CARD_ATI_RADEON_9500, 6, 14, 10, 6764 },
- {VENDOR_ATI, CARD_ATI_RADEON_X700, 6, 14, 10, 6764 },
- {VENDOR_ATI, CARD_ATI_RADEON_X1600, 6, 14, 10, 6764 },
- {VENDOR_ATI, CARD_ATI_RADEON_HD2300, 6, 14, 10, 6764 },
- {VENDOR_ATI, CARD_ATI_RADEON_HD2600, 6, 14, 10, 6764 },
- {VENDOR_ATI, CARD_ATI_RADEON_HD2900, 6, 14, 10, 6764 },
-
- /* TODO: Add information about legacy nvidia and ATI hardware, Intel and other cards */
+ {VENDOR_ATI, CARD_ATI_RADEON_9500, "ATI Radeon 9500", 6, 14, 10, 6764 },
+ {VENDOR_ATI, CARD_ATI_RADEON_X700, "ATI Radeon X700 SE", 6, 14, 10, 6764 },
+ {VENDOR_ATI, CARD_ATI_RADEON_X1600, "ATI Radeon X1600 Series", 6, 14, 10, 6764 },
+ {VENDOR_ATI, CARD_ATI_RADEON_HD2300, "ATI Mobility Radeon HD 2300", 6, 14, 10, 6764 },
+ {VENDOR_ATI, CARD_ATI_RADEON_HD2600, "ATI Mobility Radeon HD 2600", 6, 14, 10, 6764 },
+ {VENDOR_ATI, CARD_ATI_RADEON_HD2900, "ATI Radeon HD 2900 XT", 6, 14, 10, 6764 },
+
+ /* TODO: Add information about legacy ATI hardware, Intel and other cards */
};
-static void fixup_extensions(WineD3D_GL_Info *gl_info) {
- unsigned int i;
- BOOL apple = implementation_is_apple(gl_info);
+static BOOL match_ati_r300_to_500(const WineD3D_GL_Info *gl_info) {
+ if(gl_info->gl_vendor != VENDOR_ATI) return FALSE;
+ if(gl_info->gl_card == CARD_ATI_RADEON_9500) return TRUE;
+ if(gl_info->gl_card == CARD_ATI_RADEON_X700) return TRUE;
+ if(gl_info->gl_card == CARD_ATI_RADEON_X1600) return TRUE;
+ return FALSE;
+}
- if(apple) {
- /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
- * used it falls back to software. While the compiler can detect if the shader uses all declared
- * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
- * using relative addressing falls back to software.
- *
- * ARB vp gives the correct amount of uniforms, so use it instead of GLSL
- */
- if(gl_info->vs_glsl_constantsF <= gl_info->vs_arb_constantsF) {
- FIXME("GLSL doesn't advertise more vertex shader uniforms than ARB. Driver fixup outdated?\n");
- } else {
- TRACE("Driver claims %u GLSL vs uniforms, replacing with %u ARB vp uniforms\n",
- gl_info->vs_glsl_constantsF, gl_info->vs_arb_constantsF);
- gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF;
+static BOOL match_geforce5(const WineD3D_GL_Info *gl_info) {
+ if(gl_info->gl_vendor == VENDOR_NVIDIA) {
+ if(gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5800 || gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5600) {
+ return TRUE;
}
+ }
+ return FALSE;
+}
- /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
- * with fixed function fragment processing. Ideally this flag should be detected with a test shader
- * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
- * do not like vertex shaders in feedback mode and return an error, even though it should be valid
- * according to the spec.
- *
- * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
- * makes the shader slower and eats instruction slots which should be available to the d3d app.
- *
- * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
- * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
- * this workaround is activated on cards that do not need it, it won't break things, just affect
- * performance negatively.
- */
- if(gl_info->gl_vendor == VENDOR_INTEL ||
- (gl_info->gl_vendor == VENDOR_ATI && gl_info->gl_card != CARD_ATI_RADEON_X1600)) {
- TRACE("Enabling vertex texture coord fixes in vertex shaders\n");
- gl_info->set_texcoord_w = TRUE;
- }
+static BOOL match_apple_intel(const WineD3D_GL_Info *gl_info) {
+ return gl_info->gl_vendor == VENDOR_INTEL && match_apple(gl_info);
+}
+
+static BOOL match_apple_nonr500ati(const WineD3D_GL_Info *gl_info) {
+ if(!match_apple(gl_info)) return FALSE;
+ if(gl_info->gl_vendor != VENDOR_ATI) return FALSE;
+ if(gl_info->gl_card == CARD_ATI_RADEON_X1600) return FALSE;
+ return TRUE;
+}
+
+static BOOL match_fglrx(const WineD3D_GL_Info *gl_info) {
+ if(gl_info->gl_vendor != VENDOR_ATI) return FALSE;
+ if(match_apple(gl_info)) return FALSE;
+ if(strstr(gl_info->gl_renderer, "DRI")) return FALSE; /* Filter out Mesa DRI drivers */
+ return TRUE;
+}
+
+static void quirk_arb_constants(WineD3D_GL_Info *gl_info) {
+ TRACE_(d3d_caps)("Using ARB vs constant limit(=%u) for GLSL\n", gl_info->vs_arb_constantsF);
+ gl_info->vs_glsl_constantsF = gl_info->vs_arb_constantsF;
+ TRACE_(d3d_caps)("Using ARB ps constant limit(=%u) for GLSL\n", gl_info->ps_arb_constantsF);
+ gl_info->ps_glsl_constantsF = gl_info->ps_arb_constantsF;
+}
+
+static void quirk_apple_glsl_constants(WineD3D_GL_Info *gl_info) {
+ quirk_arb_constants(gl_info);
+ /* MacOS needs uniforms for relative addressing offsets. This can accumulate to quite a few uniforms.
+ * Beyond that the general uniform isn't optimal, so reserve a number of uniforms. 12 vec4's should
+ * allow 48 different offsets or other helper immediate values
+ */
+ TRACE_(d3d_caps)("Reserving 12 GLSL constants for compiler private use\n");
+ gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 12);
+}
+
+/* fglrx crashes with a very bad kernel panic if GL_POINT_SPRITE_ARB is set to GL_COORD_REPLACE_ARB
+ * on more than one texture unit. This means that the d3d9 visual point size test will cause a
+ * kernel panic on any machine running fglrx 9.3(latest that supports r300 to r500 cards). This
+ * quirk only enables point sprites on the first texture unit. This keeps point sprites working in
+ * most games, but avoids the crash
+ *
+ * A more sophisticated way would be to find all units that need texture coordinates and enable
+ * point sprites for one if only one is found, and software emulate point sprites in drawStridedSlow
+ * if more than one unit needs texture coordinates(This requires software ffp and vertex shaders though)
+ *
+ * Note that disabling the extension entirely does not gain predictability because there is no point
+ * sprite capability flag in d3d, so the potential rendering bugs are the same if we disable the extension.
+ */
+static void quirk_one_point_sprite(WineD3D_GL_Info *gl_info) {
+ if(gl_info->supported[ARB_POINT_SPRITE]) {
+ TRACE("Limiting point sprites to one texture unit\n");
+ gl_info->max_point_sprite_units = 1;
}
+}
+
+static void quirk_ati_dx9(WineD3D_GL_Info *gl_info) {
+ quirk_arb_constants(gl_info);
/* MacOS advertises GL_ARB_texture_non_power_of_two on ATI r500 and earlier cards, although
* these cards only support GL_ARB_texture_rectangle(D3DPTEXTURECAPS_NONPOW2CONDITIONAL).
* has this extension promoted to core. The extension loading code sets this extension supported
* due to that, so this code works on fglrx as well.
*/
- if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && gl_info->gl_vendor == VENDOR_ATI) {
- if(gl_info->gl_card == CARD_ATI_RADEON_X700 || gl_info->gl_card == CARD_ATI_RADEON_X1600 ||
- gl_info->gl_card == CARD_ATI_RADEON_9500 || gl_info->gl_card == CARD_ATI_RADEON_8500 ||
- gl_info->gl_card == CARD_ATI_RADEON_7200 || gl_info->gl_card == CARD_ATI_RAGE_128PRO) {
- TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing\n");
- gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
- gl_info->supported[WINE_NORMALIZED_TEXRECT] = TRUE;
- }
- }
+ TRACE("GL_ARB_texture_non_power_of_two advertised on R500 or earlier card, removing\n");
+ gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
+ gl_info->supported[WINE_NORMALIZED_TEXRECT] = TRUE;
+ /* fglrx has the same structural issues as the one described in quirk_apple_glsl_constants, although
+ * it is generally more efficient. Reserve just 8 constants
+ */
+ TRACE_(d3d_caps)("Reserving 8 GLSL constants for compiler private use\n");
+ gl_info->reserved_glsl_constants = max(gl_info->reserved_glsl_constants, 8);
+}
+
+static void quirk_no_np2(WineD3D_GL_Info *gl_info) {
/* The nVidia GeForceFX series reports OpenGL 2.0 capabilities with the latest drivers versions, but
* doesn't explicitly advertise the ARB_tex_npot extension in the GL extension string.
* This usually means that ARB_tex_npot is supported in hardware as long as the application is staying
* post-processing effects in the game "Max Payne 2").
* The behaviour can be verified through a simple test app attached in bugreport #14724.
*/
- if(gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] && gl_info->gl_vendor == VENDOR_NVIDIA) {
- if(gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5800 || gl_info->gl_card == CARD_NVIDIA_GEFORCEFX_5600) {
- TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing\n");
- gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
- gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
- }
+ TRACE("GL_ARB_texture_non_power_of_two advertised through OpenGL 2.0 on NV FX card, removing\n");
+ gl_info->supported[ARB_TEXTURE_NON_POWER_OF_TWO] = FALSE;
+ gl_info->supported[ARB_TEXTURE_RECTANGLE] = TRUE;
+}
+
+static void quirk_texcoord_w(WineD3D_GL_Info *gl_info) {
+ /* The Intel GPUs on MacOS set the .w register of texcoords to 0.0 by default, which causes problems
+ * with fixed function fragment processing. Ideally this flag should be detected with a test shader
+ * and OpenGL feedback mode, but some GL implementations (MacOS ATI at least, probably all MacOS ones)
+ * do not like vertex shaders in feedback mode and return an error, even though it should be valid
+ * according to the spec.
+ *
+ * We don't want to enable this on all cards, as it adds an extra instruction per texcoord used. This
+ * makes the shader slower and eats instruction slots which should be available to the d3d app.
+ *
+ * ATI Radeon HD 2xxx cards on MacOS have the issue. Instead of checking for the buggy cards, blacklist
+ * all radeon cards on Macs and whitelist the good ones. That way we're prepared for the future. If
+ * this workaround is activated on cards that do not need it, it won't break things, just affect
+ * performance negatively.
+ */
+ TRACE("Enabling vertex texture coord fixes in vertex shaders\n");
+ gl_info->set_texcoord_w = TRUE;
+}
+
+struct driver_quirk quirk_table[] = {
+ {
+ match_ati_r300_to_500,
+ quirk_ati_dx9,
+ "ATI GLSL constant and normalized texrect quirk"
+ },
+ /* MacOS advertises more GLSL vertex shader uniforms than supported by the hardware, and if more are
+ * used it falls back to software. While the compiler can detect if the shader uses all declared
+ * uniforms, the optimization fails if the shader uses relative addressing. So any GLSL shader
+ * using relative addressing falls back to software.
+ *
+ * ARB vp gives the correct amount of uniforms, so use it instead of GLSL
+ */
+ {
+ match_apple,
+ quirk_apple_glsl_constants,
+ "Apple GLSL uniform override"
+ },
+ {
+ match_geforce5,
+ quirk_no_np2,
+ "Geforce 5 NP2 disable"
+ },
+ {
+ match_apple_intel,
+ quirk_texcoord_w,
+ "Init texcoord .w for Apple Intel GPU driver"
+ },
+ {
+ match_apple_nonr500ati,
+ quirk_texcoord_w,
+ "Init texcoord .w for Apple ATI >= r600 GPU driver"
+ },
+ {
+ match_fglrx,
+ quirk_one_point_sprite,
+ "Fglrx point sprite crash workaround"
+ }
+};
+
+static void fixup_extensions(WineD3D_GL_Info *gl_info) {
+ unsigned int i;
+
+ for(i = 0; i < (sizeof(quirk_table) / sizeof(*quirk_table)); i++) {
+ if(!quirk_table[i].match(gl_info)) continue;
+ TRACE_(d3d_caps)("Applying driver quirk \"%s\"\n", quirk_table[i].description);
+ quirk_table[i].apply(gl_info);
}
/* Find out if PBOs work as they are supposed to */
driver_version_table[i].lopart_lo);
gl_info->driver_version_hipart = MAKEDWORD_VERSION(driver_version_table[i].hipart_hi,
driver_version_table[i].hipart_lo);
+ strcpy(gl_info->driver_description, driver_version_table[i].description);
break;
}
}
}
-static void WINE_GLAPI invalid_func(void *data) {
+static void WINE_GLAPI invalid_func(const void *data)
+{
ERR("Invalid vertex attribute function called\n");
DebugBreak();
}
-static void WINE_GLAPI invalid_texcoord_func(GLenum unit, void * data) {
+static void WINE_GLAPI invalid_texcoord_func(GLenum unit, const void *data)
+{
ERR("Invalid texcoord function called\n");
DebugBreak();
}
-#define GLINFO_LOCATION (Adapters[0].gl_info)
-
/* Helper functions for providing vertex data to opengl. The arrays are initialized based on
* the extension detection and are used in drawStridedSlow
*/
-static void WINE_GLAPI position_d3dcolor(void *data) {
- DWORD pos = *((DWORD *) data);
+static void WINE_GLAPI position_d3dcolor(const void *data)
+{
+ DWORD pos = *((const DWORD *)data);
FIXME("Add a test for fixed function position from d3dcolor type\n");
glVertex4s(D3DCOLOR_B_R(pos),
D3DCOLOR_B_B(pos),
D3DCOLOR_B_A(pos));
}
-static void WINE_GLAPI position_float4(void *data) {
- GLfloat *pos = (float *) data;
+
+static void WINE_GLAPI position_float4(const void *data)
+{
+ const GLfloat *pos = data;
if (pos[3] < eps && pos[3] > -eps)
glVertex3fv(pos);
}
}
-static void WINE_GLAPI diffuse_d3dcolor(void *data) {
- DWORD diffuseColor = *((DWORD *) data);
+static void WINE_GLAPI diffuse_d3dcolor(const void *data)
+{
+ DWORD diffuseColor = *((const DWORD *)data);
glColor4ub(D3DCOLOR_B_R(diffuseColor),
D3DCOLOR_B_G(diffuseColor),
D3DCOLOR_B_A(diffuseColor));
}
-static void WINE_GLAPI specular_d3dcolor(void *data) {
- DWORD specularColor = *((DWORD *) data);
+static void WINE_GLAPI specular_d3dcolor(const void *data)
+{
+ DWORD specularColor = *((const DWORD *)data);
+ GLbyte d[] = {D3DCOLOR_B_R(specularColor),
+ D3DCOLOR_B_G(specularColor),
+ D3DCOLOR_B_B(specularColor)};
- GL_EXTCALL(glSecondaryColor3ubEXT)(D3DCOLOR_B_R(specularColor),
- D3DCOLOR_B_G(specularColor),
- D3DCOLOR_B_B(specularColor));
+ specular_func_3ubv(d);
}
-static void WINE_GLAPI warn_no_specular_func(void *data) {
+
+static void WINE_GLAPI warn_no_specular_func(const void *data)
+{
WARN("GL_EXT_secondary_color not supported\n");
}
-void fillGLAttribFuncs(WineD3D_GL_Info *gl_info) {
- position_funcs[WINED3DDECLTYPE_FLOAT1] = (void *) invalid_func;
- position_funcs[WINED3DDECLTYPE_FLOAT2] = (void *) invalid_func;
- position_funcs[WINED3DDECLTYPE_FLOAT3] = (void *) glVertex3fv;
- position_funcs[WINED3DDECLTYPE_FLOAT4] = (void *) position_float4;
- position_funcs[WINED3DDECLTYPE_D3DCOLOR] = (void *) position_d3dcolor;
- position_funcs[WINED3DDECLTYPE_UBYTE4] = (void *) invalid_func;
- position_funcs[WINED3DDECLTYPE_SHORT2] = (void *) invalid_func;
- position_funcs[WINED3DDECLTYPE_SHORT4] = (void *) glVertex2sv;
- position_funcs[WINED3DDECLTYPE_UBYTE4N] = (void *) invalid_func;
- position_funcs[WINED3DDECLTYPE_SHORT2N] = (void *) invalid_func;
- position_funcs[WINED3DDECLTYPE_SHORT4N] = (void *) invalid_func;
- position_funcs[WINED3DDECLTYPE_USHORT2N] = (void *) invalid_func;
- position_funcs[WINED3DDECLTYPE_USHORT4N] = (void *) invalid_func;
- position_funcs[WINED3DDECLTYPE_UDEC3] = (void *) invalid_func;
- position_funcs[WINED3DDECLTYPE_DEC3N] = (void *) invalid_func;
- position_funcs[WINED3DDECLTYPE_FLOAT16_2] = (void *) invalid_func;
- position_funcs[WINED3DDECLTYPE_FLOAT16_4] = (void *) invalid_func;
-
- diffuse_funcs[WINED3DDECLTYPE_FLOAT1] = (void *) invalid_func;
- diffuse_funcs[WINED3DDECLTYPE_FLOAT2] = (void *) invalid_func;
- diffuse_funcs[WINED3DDECLTYPE_FLOAT3] = (void *) glColor3fv;
- diffuse_funcs[WINED3DDECLTYPE_FLOAT4] = (void *) glColor4fv;
- diffuse_funcs[WINED3DDECLTYPE_D3DCOLOR] = (void *) diffuse_d3dcolor;
- diffuse_funcs[WINED3DDECLTYPE_UBYTE4] = (void *) invalid_func;
- diffuse_funcs[WINED3DDECLTYPE_SHORT2] = (void *) invalid_func;
- diffuse_funcs[WINED3DDECLTYPE_SHORT4] = (void *) invalid_func;
- diffuse_funcs[WINED3DDECLTYPE_UBYTE4N] = (void *) glColor4ubv;
- diffuse_funcs[WINED3DDECLTYPE_SHORT2N] = (void *) invalid_func;
- diffuse_funcs[WINED3DDECLTYPE_SHORT4N] = (void *) glColor4sv;
- diffuse_funcs[WINED3DDECLTYPE_USHORT2N] = (void *) invalid_func;
- diffuse_funcs[WINED3DDECLTYPE_USHORT4N] = (void *) glColor4usv;
- diffuse_funcs[WINED3DDECLTYPE_UDEC3] = (void *) invalid_func;
- diffuse_funcs[WINED3DDECLTYPE_DEC3N] = (void *) invalid_func;
- diffuse_funcs[WINED3DDECLTYPE_FLOAT16_2] = (void *) invalid_func;
- diffuse_funcs[WINED3DDECLTYPE_FLOAT16_4] = (void *) invalid_func;
+static void fillGLAttribFuncs(const WineD3D_GL_Info *gl_info)
+{
+ position_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)glVertex3fv;
+ position_funcs[WINED3D_FFP_EMIT_FLOAT4] = position_float4;
+ position_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = position_d3dcolor;
+ position_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_SHORT4] = (glAttribFunc)glVertex2sv;
+ position_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
+ position_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
+
+ diffuse_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)glColor3fv;
+ diffuse_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glAttribFunc)glColor4fv;
+ diffuse_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = diffuse_d3dcolor;
+ diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_UBYTE4N] = (glAttribFunc)glColor4ubv;
+ diffuse_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_SHORT4N] = (glAttribFunc)glColor4sv;
+ diffuse_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_USHORT4N] = (glAttribFunc)glColor4usv;
+ diffuse_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
+ diffuse_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
/* No 4 component entry points here */
- specular_funcs[WINED3DDECLTYPE_FLOAT1] = (void *) invalid_func;
- specular_funcs[WINED3DDECLTYPE_FLOAT2] = (void *) invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
if(GL_SUPPORT(EXT_SECONDARY_COLOR)) {
- specular_funcs[WINED3DDECLTYPE_FLOAT3] = (void *) GL_EXTCALL(glSecondaryColor3fvEXT);
+ specular_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)GL_EXTCALL(glSecondaryColor3fvEXT);
} else {
- specular_funcs[WINED3DDECLTYPE_FLOAT3] = (void *) warn_no_specular_func;
+ specular_funcs[WINED3D_FFP_EMIT_FLOAT3] = warn_no_specular_func;
}
- specular_funcs[WINED3DDECLTYPE_FLOAT4] = (void *) invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_FLOAT4] = invalid_func;
if(GL_SUPPORT(EXT_SECONDARY_COLOR)) {
- specular_funcs[WINED3DDECLTYPE_D3DCOLOR] = (void *) specular_d3dcolor;
+ specular_func_3ubv = (glAttribFunc)GL_EXTCALL(glSecondaryColor3ubvEXT);
+ specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = specular_d3dcolor;
} else {
- specular_funcs[WINED3DDECLTYPE_D3DCOLOR] = (void *) warn_no_specular_func;
+ specular_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = warn_no_specular_func;
}
- specular_funcs[WINED3DDECLTYPE_UBYTE4] = (void *) invalid_func;
- specular_funcs[WINED3DDECLTYPE_SHORT2] = (void *) invalid_func;
- specular_funcs[WINED3DDECLTYPE_SHORT4] = (void *) invalid_func;
- specular_funcs[WINED3DDECLTYPE_UBYTE4N] = (void *) invalid_func;
- specular_funcs[WINED3DDECLTYPE_SHORT2N] = (void *) invalid_func;
- specular_funcs[WINED3DDECLTYPE_SHORT4N] = (void *) invalid_func;
- specular_funcs[WINED3DDECLTYPE_USHORT2N] = (void *) invalid_func;
- specular_funcs[WINED3DDECLTYPE_USHORT4N] = (void *) invalid_func;
- specular_funcs[WINED3DDECLTYPE_UDEC3] = (void *) invalid_func;
- specular_funcs[WINED3DDECLTYPE_DEC3N] = (void *) invalid_func;
- specular_funcs[WINED3DDECLTYPE_FLOAT16_2] = (void *) invalid_func;
- specular_funcs[WINED3DDECLTYPE_FLOAT16_4] = (void *) invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
+ specular_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
/* Only 3 component entry points here. Test how others behave. Float4 normals are used
* by one of our tests, trying to pass it to the pixel shader, which fails on Windows.
*/
- normal_funcs[WINED3DDECLTYPE_FLOAT1] = (void *) invalid_func;
- normal_funcs[WINED3DDECLTYPE_FLOAT2] = (void *) invalid_func;
- normal_funcs[WINED3DDECLTYPE_FLOAT3] = (void *) glNormal3fv;
- normal_funcs[WINED3DDECLTYPE_FLOAT4] = (void *) glNormal3fv; /* Just ignore the 4th value */
- normal_funcs[WINED3DDECLTYPE_D3DCOLOR] = (void *) invalid_func;
- normal_funcs[WINED3DDECLTYPE_UBYTE4] = (void *) invalid_func;
- normal_funcs[WINED3DDECLTYPE_SHORT2] = (void *) invalid_func;
- normal_funcs[WINED3DDECLTYPE_SHORT4] = (void *) invalid_func;
- normal_funcs[WINED3DDECLTYPE_UBYTE4N] = (void *) invalid_func;
- normal_funcs[WINED3DDECLTYPE_SHORT2N] = (void *) invalid_func;
- normal_funcs[WINED3DDECLTYPE_SHORT4N] = (void *) invalid_func;
- normal_funcs[WINED3DDECLTYPE_USHORT2N] = (void *) invalid_func;
- normal_funcs[WINED3DDECLTYPE_USHORT4N] = (void *) invalid_func;
- normal_funcs[WINED3DDECLTYPE_UDEC3] = (void *) invalid_func;
- normal_funcs[WINED3DDECLTYPE_DEC3N] = (void *) invalid_func;
- normal_funcs[WINED3DDECLTYPE_FLOAT16_2] = (void *) invalid_func;
- normal_funcs[WINED3DDECLTYPE_FLOAT16_4] = (void *) invalid_func;
-
- multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT1] = (void *) GL_EXTCALL(glMultiTexCoord1fvARB);
- multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT2] = (void *) GL_EXTCALL(glMultiTexCoord2fvARB);
- multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT3] = (void *) GL_EXTCALL(glMultiTexCoord3fvARB);
- multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT4] = (void *) GL_EXTCALL(glMultiTexCoord4fvARB);
- multi_texcoord_funcs[WINED3DDECLTYPE_D3DCOLOR] = (void *) invalid_texcoord_func;
- multi_texcoord_funcs[WINED3DDECLTYPE_UBYTE4] = (void *) invalid_texcoord_func;
- multi_texcoord_funcs[WINED3DDECLTYPE_SHORT2] = (void *) GL_EXTCALL(glMultiTexCoord2svARB);
- multi_texcoord_funcs[WINED3DDECLTYPE_SHORT4] = (void *) GL_EXTCALL(glMultiTexCoord4svARB);
- multi_texcoord_funcs[WINED3DDECLTYPE_UBYTE4N] = (void *) invalid_texcoord_func;
- multi_texcoord_funcs[WINED3DDECLTYPE_SHORT2N] = (void *) invalid_texcoord_func;
- multi_texcoord_funcs[WINED3DDECLTYPE_SHORT4N] = (void *) invalid_texcoord_func;
- multi_texcoord_funcs[WINED3DDECLTYPE_USHORT2N] = (void *) invalid_texcoord_func;
- multi_texcoord_funcs[WINED3DDECLTYPE_USHORT4N] = (void *) invalid_texcoord_func;
- multi_texcoord_funcs[WINED3DDECLTYPE_UDEC3] = (void *) invalid_texcoord_func;
- multi_texcoord_funcs[WINED3DDECLTYPE_DEC3N] = (void *) invalid_texcoord_func;
- if (GL_SUPPORT(NV_HALF_FLOAT))
- {
- multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2] = (void *) GL_EXTCALL(glMultiTexCoord2hvNV);
- multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4] = (void *) GL_EXTCALL(glMultiTexCoord4hvNV);
- } else {
- multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2] = (void *) invalid_texcoord_func;
- multi_texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4] = (void *) invalid_texcoord_func;
- }
-
- texcoord_funcs[WINED3DDECLTYPE_FLOAT1] = (void *) glTexCoord1fv;
- texcoord_funcs[WINED3DDECLTYPE_FLOAT2] = (void *) glTexCoord2fv;
- texcoord_funcs[WINED3DDECLTYPE_FLOAT3] = (void *) glTexCoord3fv;
- texcoord_funcs[WINED3DDECLTYPE_FLOAT4] = (void *) glTexCoord4fv;
- texcoord_funcs[WINED3DDECLTYPE_D3DCOLOR] = (void *) invalid_func;
- texcoord_funcs[WINED3DDECLTYPE_UBYTE4] = (void *) invalid_func;
- texcoord_funcs[WINED3DDECLTYPE_SHORT2] = (void *) glTexCoord2sv;
- texcoord_funcs[WINED3DDECLTYPE_SHORT4] = (void *) glTexCoord4sv;
- texcoord_funcs[WINED3DDECLTYPE_UBYTE4N] = (void *) invalid_func;
- texcoord_funcs[WINED3DDECLTYPE_SHORT2N] = (void *) invalid_func;
- texcoord_funcs[WINED3DDECLTYPE_SHORT4N] = (void *) invalid_func;
- texcoord_funcs[WINED3DDECLTYPE_USHORT2N] = (void *) invalid_func;
- texcoord_funcs[WINED3DDECLTYPE_USHORT4N] = (void *) invalid_func;
- texcoord_funcs[WINED3DDECLTYPE_UDEC3] = (void *) invalid_func;
- texcoord_funcs[WINED3DDECLTYPE_DEC3N] = (void *) invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_FLOAT1] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_FLOAT2] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glAttribFunc)glNormal3fv;
+ normal_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glAttribFunc)glNormal3fv; /* Just ignore the 4th value */
+ normal_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_SHORT2] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_SHORT4] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_func;
+ normal_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_func;
+
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT1] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord1fvARB);
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2fvARB);
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT3] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord3fvARB);
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4fvARB);
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_D3DCOLOR] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2svARB);
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4svARB);
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_UBYTE4N] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT2N] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_SHORT4N] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT2N] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_USHORT4N] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_UDEC3] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_DEC3N] = invalid_texcoord_func;
if (GL_SUPPORT(NV_HALF_FLOAT))
{
- texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2] = (void *) GL_EXTCALL(glTexCoord2hvNV);
- texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4] = (void *) GL_EXTCALL(glTexCoord4hvNV);
+ /* Not supported by ARB_HALF_FLOAT_VERTEX, so check for NV_HALF_FLOAT */
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord2hvNV);
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = (glMultiTexCoordFunc)GL_EXTCALL(glMultiTexCoord4hvNV);
} else {
- texcoord_funcs[WINED3DDECLTYPE_FLOAT16_2] = (void *) invalid_func;
- texcoord_funcs[WINED3DDECLTYPE_FLOAT16_4] = (void *) invalid_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_2] = invalid_texcoord_func;
+ multi_texcoord_funcs[WINED3D_FFP_EMIT_FLOAT16_4] = invalid_texcoord_func;
}
}
-#define PUSH1(att) attribs[nAttribs++] = (att);
-BOOL InitAdapters(void) {
- static HMODULE mod_gl, mod_win32gl;
+BOOL InitAdapters(IWineD3DImpl *This)
+{
+ static HMODULE mod_gl;
BOOL ret;
int ps_selected_mode, vs_selected_mode;
/* No need to hold any lock. The calling library makes sure only one thread calls
* wined3d simultaneously
*/
- if(numAdapters > 0) return Adapters[0].opengl;
TRACE("Initializing adapters\n");
ERR("Can't load opengl32.dll!\n");
goto nogl_adapter;
}
- mod_win32gl = mod_gl;
#else
#define USE_GL_FUNC(pfn) pfn = (void*)pwglGetProcAddress(#pfn);
/* To bypass the opengl32 thunks load wglGetProcAddress from gdi32 (glXGetProcAddress wrapper) instead of opengl32's */
mod_gl = GetModuleHandleA("gdi32.dll");
- mod_win32gl = LoadLibraryA("opengl32.dll");
- if(!mod_win32gl) {
- ERR("Can't load opengl32.dll!\n");
- goto nogl_adapter;
- }
#endif
}
/* Load glFinish and glFlush from opengl32.dll even if we're not using WIN32 opengl
* otherwise because we have to use winex11.drv's override
*/
- glFinish = (void*)GetProcAddress(mod_win32gl, "glFinish");
- glFlush = (void*)GetProcAddress(mod_win32gl, "glFlush");
+#ifdef USE_WIN32_OPENGL
+ glFinish = (void*)GetProcAddress(mod_gl, "glFinish");
+ glFlush = (void*)GetProcAddress(mod_gl, "glFlush");
+#else
+ glFinish = (void*)pwglGetProcAddress("wglFinish");
+ glFlush = (void*)pwglGetProcAddress("wglFlush");
+#endif
+
+ glEnableWINE = glEnable;
+ glDisableWINE = glDisable;
/* For now only one default adapter */
{
+ struct WineD3DAdapter *adapter = &This->adapters[0];
+ const WineD3D_GL_Info *gl_info = &adapter->gl_info;
int iPixelFormat;
- int attribs[10];
- int values[10];
- int nAttribs = 0;
int res;
int i;
WineD3D_PixelFormat *cfgs;
- int attribute;
DISPLAY_DEVICEW DisplayDevice;
HDC hdc;
TRACE("Initializing default adapter\n");
- Adapters[0].num = 0;
- Adapters[0].monitorPoint.x = -1;
- Adapters[0].monitorPoint.y = -1;
+ adapter->num = 0;
+ adapter->monitorPoint.x = -1;
+ adapter->monitorPoint.y = -1;
if (!WineD3D_CreateFakeGLContext()) {
ERR("Failed to get a gl context for default adapter\n");
goto nogl_adapter;
}
- ret = IWineD3DImpl_FillGLCaps(&Adapters[0].gl_info);
+ ret = IWineD3DImpl_FillGLCaps(&adapter->gl_info);
if(!ret) {
ERR("Failed to initialize gl caps for default adapter\n");
WineD3D_ReleaseFakeGLContext();
goto nogl_adapter;
}
- ret = initPixelFormats(&Adapters[0].gl_info);
+ ret = initPixelFormats(&adapter->gl_info);
if(!ret) {
ERR("Failed to init gl formats\n");
WineD3D_ReleaseFakeGLContext();
goto nogl_adapter;
}
- Adapters[0].driver = "Display";
- Adapters[0].description = "Direct3D HAL";
+ adapter->driver = "Display";
+ adapter->description = "Direct3D HAL";
/* Use the VideoRamSize registry setting when set */
if(wined3d_settings.emulated_textureram)
- Adapters[0].TextureRam = wined3d_settings.emulated_textureram;
+ adapter->TextureRam = wined3d_settings.emulated_textureram;
else
- Adapters[0].TextureRam = Adapters[0].gl_info.vidmem;
- Adapters[0].UsedTextureRam = 0;
- TRACE("Emulating %dMB of texture ram\n", Adapters[0].TextureRam/(1024*1024));
+ adapter->TextureRam = adapter->gl_info.vidmem;
+ adapter->UsedTextureRam = 0;
+ TRACE("Emulating %dMB of texture ram\n", adapter->TextureRam/(1024*1024));
/* Initialize the Adapter's DeviceName which is required for ChangeDisplaySettings and friends */
DisplayDevice.cb = sizeof(DisplayDevice);
EnumDisplayDevicesW(NULL, 0 /* Adapter 0 = iDevNum 0 */, &DisplayDevice, 0);
TRACE("DeviceName: %s\n", debugstr_w(DisplayDevice.DeviceName));
- strcpyW(Adapters[0].DeviceName, DisplayDevice.DeviceName);
-
- attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
- GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &Adapters[0].nCfgs));
-
- Adapters[0].cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Adapters[0].nCfgs *sizeof(WineD3D_PixelFormat));
- cfgs = Adapters[0].cfgs;
- PUSH1(WGL_RED_BITS_ARB)
- PUSH1(WGL_GREEN_BITS_ARB)
- PUSH1(WGL_BLUE_BITS_ARB)
- PUSH1(WGL_ALPHA_BITS_ARB)
- PUSH1(WGL_DEPTH_BITS_ARB)
- PUSH1(WGL_STENCIL_BITS_ARB)
- PUSH1(WGL_DRAW_TO_WINDOW_ARB)
- PUSH1(WGL_PIXEL_TYPE_ARB)
- PUSH1(WGL_DOUBLE_BUFFER_ARB)
- PUSH1(WGL_AUX_BUFFERS_ARB)
-
- for(iPixelFormat=1; iPixelFormat<=Adapters[0].nCfgs; iPixelFormat++) {
- res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
-
- if(!res)
- continue;
+ strcpyW(adapter->DeviceName, DisplayDevice.DeviceName);
+
+ if(GL_SUPPORT(WGL_ARB_PIXEL_FORMAT))
+ {
+ int attribute;
+ int attribs[10];
+ int values[10];
+ int nAttribs = 0;
+
+ attribute = WGL_NUMBER_PIXEL_FORMATS_ARB;
+ GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, 0, 0, 1, &attribute, &adapter->nCfgs));
+
+ adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, adapter->nCfgs *sizeof(WineD3D_PixelFormat));
+ cfgs = adapter->cfgs;
+ attribs[nAttribs++] = WGL_RED_BITS_ARB;
+ attribs[nAttribs++] = WGL_GREEN_BITS_ARB;
+ attribs[nAttribs++] = WGL_BLUE_BITS_ARB;
+ attribs[nAttribs++] = WGL_ALPHA_BITS_ARB;
+ attribs[nAttribs++] = WGL_DEPTH_BITS_ARB;
+ attribs[nAttribs++] = WGL_STENCIL_BITS_ARB;
+ attribs[nAttribs++] = WGL_DRAW_TO_WINDOW_ARB;
+ attribs[nAttribs++] = WGL_PIXEL_TYPE_ARB;
+ attribs[nAttribs++] = WGL_DOUBLE_BUFFER_ARB;
+ attribs[nAttribs++] = WGL_AUX_BUFFERS_ARB;
+
+ for (iPixelFormat=1; iPixelFormat <= adapter->nCfgs; ++iPixelFormat)
+ {
+ res = GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, nAttribs, attribs, values));
+
+ if(!res)
+ continue;
+
+ /* Cache the pixel format */
+ cfgs->iPixelFormat = iPixelFormat;
+ cfgs->redSize = values[0];
+ cfgs->greenSize = values[1];
+ cfgs->blueSize = values[2];
+ cfgs->alphaSize = values[3];
+ cfgs->depthSize = values[4];
+ cfgs->stencilSize = values[5];
+ cfgs->windowDrawable = values[6];
+ cfgs->iPixelType = values[7];
+ cfgs->doubleBuffer = values[8];
+ cfgs->auxBuffers = values[9];
+
+ cfgs->pbufferDrawable = FALSE;
+ /* Check for pbuffer support when it is around as wglGetPixelFormatAttribiv fails for unknown attributes. */
+ if(GL_SUPPORT(WGL_ARB_PBUFFER)) {
+ int attrib = WGL_DRAW_TO_PBUFFER_ARB;
+ int value;
+ if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 1, &attrib, &value)))
+ cfgs->pbufferDrawable = value;
+ }
+
+ cfgs->numSamples = 0;
+ /* Check multisample support */
+ if(GL_SUPPORT(ARB_MULTISAMPLE)) {
+ int attrib[2] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
+ int value[2];
+ if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 2, attrib, value))) {
+ /* value[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether multisampling is supported.
+ * value[1] = number of multi sample buffers*/
+ if(value[0])
+ cfgs->numSamples = value[1];
+ }
+ }
- /* Cache the pixel format */
- cfgs->iPixelFormat = iPixelFormat;
- cfgs->redSize = values[0];
- cfgs->greenSize = values[1];
- cfgs->blueSize = values[2];
- cfgs->alphaSize = values[3];
- cfgs->depthSize = values[4];
- cfgs->stencilSize = values[5];
- cfgs->windowDrawable = values[6];
- cfgs->iPixelType = values[7];
- cfgs->doubleBuffer = values[8];
- cfgs->auxBuffers = values[9];
-
- cfgs->pbufferDrawable = FALSE;
- /* Check for pbuffer support when it is around as wglGetPixelFormatAttribiv fails for unknown attributes. */
- if(GL_SUPPORT(WGL_ARB_PBUFFER)) {
- int attrib = WGL_DRAW_TO_PBUFFER_ARB;
- int value;
- if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 1, &attrib, &value)))
- cfgs->pbufferDrawable = value;
+ TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, depth=%d, stencil=%d, windowDrawable=%d, pbufferDrawable=%d\n", cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer, cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable, cfgs->pbufferDrawable);
+ cfgs++;
}
+ }
+ else
+ {
+ int nCfgs = DescribePixelFormat(hdc, 0, 0, 0);
+ adapter->cfgs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nCfgs*sizeof(WineD3D_PixelFormat));
+ adapter->nCfgs = 0; /* We won't accept all formats e.g. software accelerated ones will be skipped */
- cfgs->numSamples = 0;
- /* Check multisample support */
- if(GL_SUPPORT(ARB_MULTISAMPLE)) {
- int attrib[2] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
- int value[2];
- if(GL_EXTCALL(wglGetPixelFormatAttribivARB(hdc, iPixelFormat, 0, 2, attrib, value))) {
- /* value[0] = WGL_SAMPLE_BUFFERS_ARB which tells whether multisampling is supported.
- * value[1] = number of multi sample buffers*/
- if(value[0])
- cfgs->numSamples = value[1];
+ cfgs = adapter->cfgs;
+ for(iPixelFormat=1; iPixelFormat<=nCfgs; iPixelFormat++)
+ {
+ PIXELFORMATDESCRIPTOR ppfd;
+
+ res = DescribePixelFormat(hdc, iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &ppfd);
+ if(!res)
+ continue;
+
+ /* We only want HW acceleration using an OpenGL ICD driver.
+ * PFD_GENERIC_FORMAT = slow opengl 1.1 gdi software rendering
+ * PFD_GENERIC_ACCELERATED = partial hw acceleration using a MCD driver (e.g. 3dfx minigl)
+ */
+ if(ppfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED))
+ {
+ TRACE("Skipping iPixelFormat=%d because it isn't ICD accelerated\n", iPixelFormat);
+ continue;
}
+
+ cfgs->iPixelFormat = iPixelFormat;
+ cfgs->redSize = ppfd.cRedBits;
+ cfgs->greenSize = ppfd.cGreenBits;
+ cfgs->blueSize = ppfd.cBlueBits;
+ cfgs->alphaSize = ppfd.cAlphaBits;
+ cfgs->depthSize = ppfd.cDepthBits;
+ cfgs->stencilSize = ppfd.cStencilBits;
+ cfgs->pbufferDrawable = 0;
+ cfgs->windowDrawable = (ppfd.dwFlags & PFD_DRAW_TO_WINDOW) ? 1 : 0;
+ cfgs->iPixelType = (ppfd.iPixelType == PFD_TYPE_RGBA) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB;
+ cfgs->doubleBuffer = (ppfd.dwFlags & PFD_DOUBLEBUFFER) ? 1 : 0;
+ cfgs->auxBuffers = ppfd.cAuxBuffers;
+ cfgs->numSamples = 0;
+
+ TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, depth=%d, stencil=%d, windowDrawable=%d, pbufferDrawable=%d\n", cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer, cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable, cfgs->pbufferDrawable);
+ cfgs++;
+ adapter->nCfgs++;
}
- TRACE("iPixelFormat=%d, iPixelType=%#x, doubleBuffer=%d, RGBA=%d/%d/%d/%d, depth=%d, stencil=%d, windowDrawable=%d, pbufferDrawable=%d\n", cfgs->iPixelFormat, cfgs->iPixelType, cfgs->doubleBuffer, cfgs->redSize, cfgs->greenSize, cfgs->blueSize, cfgs->alphaSize, cfgs->depthSize, cfgs->stencilSize, cfgs->windowDrawable, cfgs->pbufferDrawable);
- cfgs++;
+ /* Yikes we haven't found any suitable formats. This should only happen in case of GDI software rendering which we can't use anyway as its 3D functionality is very, very limited */
+ if(!adapter->nCfgs)
+ {
+ ERR("Disabling Direct3D because no hardware accelerated pixel formats have been found!\n");
+
+ WineD3D_ReleaseFakeGLContext();
+ HeapFree(GetProcessHeap(), 0, adapter->cfgs);
+ goto nogl_adapter;
+ }
}
/* D16, D24X8 and D24S8 are common depth / depth+stencil formats. All drivers support them though this doesn't
*
* Mark an adapter with this broken stencil behavior.
*/
- Adapters[0].brokenStencil = TRUE;
- for(i=0, cfgs=Adapters[0].cfgs; i<Adapters[0].nCfgs; i++) {
+ adapter->brokenStencil = TRUE;
+ for (i = 0, cfgs = adapter->cfgs; i < adapter->nCfgs; ++i)
+ {
/* Nearly all drivers offer depth formats without stencil, only on i915 this if-statement won't be entered. */
if(cfgs[i].depthSize && !cfgs[i].stencilSize) {
- Adapters[0].brokenStencil = FALSE;
+ adapter->brokenStencil = FALSE;
break;
}
}
- fixup_extensions(&Adapters[0].gl_info);
+ fixup_extensions(&adapter->gl_info);
+ add_gl_compat_wrappers(&adapter->gl_info);
WineD3D_ReleaseFakeGLContext();
- select_shader_mode(&Adapters[0].gl_info, WINED3DDEVTYPE_HAL, &ps_selected_mode, &vs_selected_mode);
- select_shader_max_constants(ps_selected_mode, vs_selected_mode, &Adapters[0].gl_info);
- fillGLAttribFuncs(&Adapters[0].gl_info);
- init_type_lookup(&Adapters[0].gl_info);
- Adapters[0].opengl = TRUE;
+ select_shader_mode(&adapter->gl_info, WINED3DDEVTYPE_HAL, &ps_selected_mode, &vs_selected_mode);
+ select_shader_max_constants(ps_selected_mode, vs_selected_mode, &adapter->gl_info);
+ fillGLAttribFuncs(&adapter->gl_info);
+ adapter->opengl = TRUE;
}
- numAdapters = 1;
- TRACE("%d adapters successfully initialized\n", numAdapters);
+ This->adapter_count = 1;
+ TRACE("%u adapters successfully initialized\n", This->adapter_count);
return TRUE;
nogl_adapter:
/* Initialize an adapter for ddraw-only memory counting */
- memset(Adapters, 0, sizeof(Adapters));
- Adapters[0].num = 0;
- Adapters[0].opengl = FALSE;
- Adapters[0].monitorPoint.x = -1;
- Adapters[0].monitorPoint.y = -1;
-
- Adapters[0].driver = "Display";
- Adapters[0].description = "WineD3D DirectDraw Emulation";
+ memset(This->adapters, 0, sizeof(This->adapters));
+ This->adapters[0].num = 0;
+ This->adapters[0].opengl = FALSE;
+ This->adapters[0].monitorPoint.x = -1;
+ This->adapters[0].monitorPoint.y = -1;
+
+ This->adapters[0].driver = "Display";
+ This->adapters[0].description = "WineD3D DirectDraw Emulation";
if(wined3d_settings.emulated_textureram) {
- Adapters[0].TextureRam = wined3d_settings.emulated_textureram;
+ This->adapters[0].TextureRam = wined3d_settings.emulated_textureram;
} else {
- Adapters[0].TextureRam = 8 * 1024 * 1024; /* This is plenty for a DDraw-only card */
+ This->adapters[0].TextureRam = 8 * 1024 * 1024; /* This is plenty for a DDraw-only card */
}
- numAdapters = 1;
+ initPixelFormatsNoGL(&This->adapters[0].gl_info);
+
+ This->adapter_count = 1;
return FALSE;
}
-#undef PUSH1
-#undef GLINFO_LOCATION
/**********************************************************
* IWineD3D VTbl follows