Commit a1e718cc authored by Matteo Bruni's avatar Matteo Bruni Committed by Alexandre Julliard

wined3d: Add a setting for the maximum OpenGL version to use.

parent 6521fc78
......@@ -1376,7 +1376,7 @@ static void bind_dummy_textures(const struct wined3d_device *device, const struc
}
}
BOOL context_debug_output_enabled(const struct wined3d_gl_info *gl_info)
static BOOL context_debug_output_enabled(const struct wined3d_gl_info *gl_info)
{
return gl_info->supported[ARB_DEBUG_OUTPUT]
&& (ERR_ON(d3d) || FIXME_ON(d3d) || WARN_ON(d3d_perf));
......@@ -1407,6 +1407,40 @@ static void WINE_GLAPI wined3d_debug_callback(GLenum source, GLenum type, GLuint
}
}
HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, HGLRC share_ctx)
{
HGLRC ctx;
unsigned int ctx_attrib_idx = 0;
GLint ctx_attribs[7], ctx_flags = 0;
if (context_debug_output_enabled(gl_info))
ctx_flags = WGL_CONTEXT_DEBUG_BIT_ARB;
ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_MAJOR_VERSION_ARB;
ctx_attribs[ctx_attrib_idx++] = gl_info->selected_gl_version >> 16;
ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_MINOR_VERSION_ARB;
ctx_attribs[ctx_attrib_idx++] = gl_info->selected_gl_version & 0xffff;
if (gl_info->selected_gl_version >= MAKEDWORD_VERSION(3, 2))
ctx_flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
if (ctx_flags)
{
ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_FLAGS_ARB;
ctx_attribs[ctx_attrib_idx++] = ctx_flags;
}
ctx_attribs[ctx_attrib_idx] = 0;
if (!(ctx = gl_info->p_wglCreateContextAttribsARB(hdc, share_ctx, ctx_attribs)))
{
if (ctx_flags & WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB)
{
ctx_attribs[ctx_attrib_idx - 1] &= ~WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
if (!(ctx = gl_info->p_wglCreateContextAttribsARB(hdc, share_ctx, ctx_attribs)))
WARN("Failed to create a WGL context with wglCreateContextAttribsARB, last error %#x.\n",
GetLastError());
}
}
return ctx;
}
struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
struct wined3d_surface *target, const struct wined3d_format *ds_format)
{
......@@ -1557,22 +1591,8 @@ struct wined3d_context *context_create(struct wined3d_swapchain *swapchain,
share_ctx = device->context_count ? device->contexts[0]->glCtx : NULL;
if (gl_info->p_wglCreateContextAttribsARB)
{
unsigned int ctx_attrib_idx = 0;
GLint ctx_attribs[3];
if (context_debug_output_enabled(gl_info))
{
ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_FLAGS_ARB;
ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_DEBUG_BIT_ARB;
}
ctx_attribs[ctx_attrib_idx] = 0;
if (!(ctx = gl_info->p_wglCreateContextAttribsARB(hdc, share_ctx, ctx_attribs)))
{
ERR("Failed to create a WGL context.\n");
context_release(ret);
if (!(ctx = context_create_wgl_attribs(gl_info, hdc, share_ctx)))
goto out;
}
}
else
{
......
......@@ -279,19 +279,18 @@ static void wined3d_caps_gl_ctx_destroy(const struct wined3d_caps_gl_ctx *ctx)
ERR("Failed to restore previous GL context.\n");
}
static void wined3d_caps_gl_ctx_create_attribs(struct wined3d_caps_gl_ctx *caps_gl_ctx,
struct wined3d_gl_info *gl_info, const GLint *ctx_attribs)
static BOOL wined3d_caps_gl_ctx_create_attribs(struct wined3d_caps_gl_ctx *caps_gl_ctx,
struct wined3d_gl_info *gl_info)
{
HGLRC new_ctx;
if (!(gl_info->p_wglCreateContextAttribsARB = (void *)wglGetProcAddress("wglCreateContextAttribsARB")))
return;
return TRUE;
if (!(new_ctx = gl_info->p_wglCreateContextAttribsARB(caps_gl_ctx->dc, NULL, ctx_attribs)))
if (!(new_ctx = context_create_wgl_attribs(gl_info, caps_gl_ctx->dc, NULL)))
{
ERR("Failed to create a context using wglCreateContextAttribsARB(), last error %#x.\n", GetLastError());
gl_info->p_wglCreateContextAttribsARB = NULL;
return;
return FALSE;
}
if (!wglMakeCurrent(caps_gl_ctx->dc, new_ctx))
......@@ -300,12 +299,14 @@ static void wined3d_caps_gl_ctx_create_attribs(struct wined3d_caps_gl_ctx *caps_
if (!wglDeleteContext(new_ctx))
ERR("Failed to delete new context, last error %#x.\n", GetLastError());
gl_info->p_wglCreateContextAttribsARB = NULL;
return;
return TRUE;
}
if (!wglDeleteContext(caps_gl_ctx->gl_ctx))
ERR("Failed to delete old context, last error %#x.\n", GetLastError());
caps_gl_ctx->gl_ctx = new_ctx;
return TRUE;
}
static BOOL wined3d_caps_gl_ctx_create(struct wined3d_caps_gl_ctx *ctx)
......@@ -2420,6 +2421,30 @@ static void parse_extension_string(struct wined3d_gl_info *gl_info, const char *
}
}
static void enumerate_gl_extensions(struct wined3d_gl_info *gl_info,
const struct wined3d_extension_map *map, unsigned int map_entries_count)
{
const char *gl_extension_name;
unsigned int i, j;
GLint extensions_count;
glGetIntegerv(GL_NUM_EXTENSIONS, &extensions_count);
for (i = 0; i < extensions_count; ++i)
{
gl_extension_name = (const char *)GL_EXTCALL(glGetStringi(GL_EXTENSIONS, i));
TRACE("- %s.\n", debugstr_a(gl_extension_name));
for (j = 0; j < map_entries_count; ++j)
{
if (!strcmp(gl_extension_name, map[j].extension_string))
{
TRACE("FOUND: %s support.\n", map[j].extension_string);
gl_info->supported[map[j].extension] = TRUE;
break;
}
}
}
}
static void load_gl_funcs(struct wined3d_gl_info *gl_info)
{
#define USE_GL_FUNC(pfn) gl_info->gl_ops.ext.p_##pfn = (void *)wglGetProcAddress(#pfn);
......@@ -2912,6 +2937,7 @@ static void load_gl_funcs(struct wined3d_gl_info *gl_info)
USE_GL_FUNC(glGetShaderInfoLog) /* OpenGL 2.0 */
USE_GL_FUNC(glGetShaderiv) /* OpenGL 2.0 */
USE_GL_FUNC(glGetShaderSource) /* OpenGL 2.0 */
USE_GL_FUNC(glGetStringi) /* OpenGL 3.0 */
USE_GL_FUNC(glGetUniformfv) /* OpenGL 2.0 */
USE_GL_FUNC(glGetUniformiv) /* OpenGL 2.0 */
USE_GL_FUNC(glGetUniformLocation) /* OpenGL 2.0 */
......@@ -3324,12 +3350,12 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
struct fragment_caps fragment_caps;
struct shader_caps shader_caps;
const char *WGL_Extensions = NULL;
const char *GL_Extensions = NULL;
enum wined3d_gl_vendor gl_vendor;
enum wined3d_pci_device device;
DWORD gl_version;
HDC hdc;
unsigned int i;
GLint context_profile = 0;
TRACE("adapter %p.\n", adapter);
......@@ -3359,23 +3385,39 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
}
gl_version = wined3d_parse_gl_version(gl_version_str);
/* Parse the gl supported features, in theory enabling parts of our code appropriately. */
GL_Extensions = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_EXTENSIONS);
if (!GL_Extensions)
{
ERR("Received a NULL GL_EXTENSIONS.\n");
return FALSE;
}
load_gl_funcs(gl_info);
memset(gl_info->supported, 0, sizeof(gl_info->supported));
gl_info->supported[WINED3D_GL_EXT_NONE] = TRUE;
if (gl_version >= MAKEDWORD_VERSION(3, 2))
{
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &context_profile);
checkGLcall("Querying context profile");
}
if (context_profile & GL_CONTEXT_CORE_PROFILE_BIT)
TRACE("Got a core profile context.\n");
else
gl_info->supported[WINED3D_GL_LEGACY_CONTEXT] = TRUE;
TRACE("GL extensions reported:\n");
parse_extension_string(gl_info, GL_Extensions, gl_extension_map,
sizeof(gl_extension_map) / sizeof(*gl_extension_map));
if (gl_info->supported[WINED3D_GL_LEGACY_CONTEXT])
{
const char *gl_extensions = (const char *)gl_info->gl_ops.gl.p_glGetString(GL_EXTENSIONS);
/* Now work out what GL support this card really has. */
load_gl_funcs( gl_info );
if (!gl_extensions)
{
ERR("Received a NULL GL_EXTENSIONS.\n");
return FALSE;
}
parse_extension_string(gl_info, gl_extensions, gl_extension_map,
sizeof(gl_extension_map) / sizeof(*gl_extension_map));
}
else
{
enumerate_gl_extensions(gl_info, gl_extension_map,
sizeof(gl_extension_map) / sizeof(*gl_extension_map));
}
hdc = wglGetCurrentDC();
/* Not all GL drivers might offer WGL extensions e.g. VirtualBox. */
......@@ -5667,11 +5709,15 @@ static void wined3d_adapter_init_fb_cfgs(struct wined3d_adapter *adapter, HDC dc
static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal)
{
static const DWORD supported_gl_versions[] =
{
MAKEDWORD_VERSION(3, 2),
MAKEDWORD_VERSION(1, 0),
};
struct wined3d_gl_info *gl_info = &adapter->gl_info;
struct wined3d_caps_gl_ctx caps_gl_ctx = {0};
unsigned int ctx_attrib_idx = 0;
unsigned int i;
DISPLAY_DEVICEW display_device;
GLint ctx_attribs[3];
TRACE("adapter %p, ordinal %u.\n", adapter, ordinal);
......@@ -5717,13 +5763,28 @@ static BOOL wined3d_adapter_init(struct wined3d_adapter *adapter, UINT ordinal)
return FALSE;
}
if (context_debug_output_enabled(gl_info))
for (i = 0; i < ARRAY_SIZE(supported_gl_versions); ++i)
{
if (supported_gl_versions[i] <= wined3d_settings.max_gl_version)
break;
}
if (i == ARRAY_SIZE(supported_gl_versions))
{
ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_FLAGS_ARB;
ctx_attribs[ctx_attrib_idx++] = WGL_CONTEXT_DEBUG_BIT_ARB;
ERR_(winediag)("Requested invalid GL version %u.%u.\n",
wined3d_settings.max_gl_version >> 16, wined3d_settings.max_gl_version & 0xffff);
i = ARRAY_SIZE(supported_gl_versions) - 1;
}
for (; i < ARRAY_SIZE(supported_gl_versions); ++i)
{
gl_info->selected_gl_version = supported_gl_versions[i];
if (wined3d_caps_gl_ctx_create_attribs(&caps_gl_ctx, gl_info))
break;
WARN("Couldn't create an OpenGL %u.%u context, trying fallback to a lower version.\n",
supported_gl_versions[i] >> 16, supported_gl_versions[i] & 0xffff);
}
ctx_attribs[ctx_attrib_idx] = 0;
wined3d_caps_gl_ctx_create_attribs(&caps_gl_ctx, gl_info, ctx_attribs);
if (!wined3d_adapter_init_gl_caps(adapter))
{
......
......@@ -162,6 +162,7 @@ enum wined3d_gl_extension
/* Internally used */
WINED3D_GL_BLEND_EQUATION,
WINED3D_GL_NORMALIZED_TEXRECT,
WINED3D_GL_LEGACY_CONTEXT,
WINED3D_GL_VERSION_2_0,
WINED3D_GL_EXT_COUNT,
......
......@@ -72,6 +72,7 @@ static CRITICAL_SECTION wined3d_wndproc_cs = {&wined3d_wndproc_cs_debug, -1, 0,
* where appropriate. */
struct wined3d_settings wined3d_settings =
{
MAKEDWORD_VERSION(1, 0), /* Default to legacy OpenGL */
TRUE, /* Use of GLSL enabled by default */
ORM_FBO, /* Use FBOs to do offscreen rendering */
PCI_VENDOR_NONE,/* PCI Vendor ID */
......@@ -199,6 +200,15 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
if (hkey || appkey)
{
if (!get_config_key_dword(hkey, appkey, "MaxVersionGL", &tmpvalue))
{
if (tmpvalue != wined3d_settings.max_gl_version)
{
ERR_(winediag)("Setting maximum allowed wined3d GL version to %u.%u.\n",
tmpvalue >> 16, tmpvalue & 0xffff);
wined3d_settings.max_gl_version = tmpvalue;
}
}
if ( !get_config_key( hkey, appkey, "UseGLSL", buffer, size) )
{
if (!strcmp(buffer,"disabled"))
......
......@@ -262,9 +262,7 @@ static inline float float_24_to_32(DWORD in)
* values in wined3d_main.c as well. */
struct wined3d_settings
{
/* Ideally, we don't want the user to have to request GLSL. If the
* hardware supports GLSL, we should use it. However, until it's fully
* implemented, we'll leave it as a registry setting for developers. */
DWORD max_gl_version;
BOOL glslRequested;
int offscreen_rendering_mode;
unsigned short pci_vendor_id;
......@@ -1402,7 +1400,7 @@ void context_bind_texture(struct wined3d_context *context, GLenum target, GLuint
void context_check_fbo_status(const struct wined3d_context *context, GLenum target) DECLSPEC_HIDDEN;
struct wined3d_context *context_create(struct wined3d_swapchain *swapchain, struct wined3d_surface *target,
const struct wined3d_format *ds_format) DECLSPEC_HIDDEN;
BOOL context_debug_output_enabled(const struct wined3d_gl_info *gl_info) DECLSPEC_HIDDEN;
HGLRC context_create_wgl_attribs(const struct wined3d_gl_info *gl_info, HDC hdc, HGLRC share_ctx) DECLSPEC_HIDDEN;
void context_destroy(struct wined3d_device *device, struct wined3d_context *context) DECLSPEC_HIDDEN;
void context_free_event_query(struct wined3d_event_query *query) DECLSPEC_HIDDEN;
void context_free_occlusion_query(struct wined3d_occlusion_query *query) DECLSPEC_HIDDEN;
......@@ -1713,6 +1711,7 @@ struct wined3d_gl_limits
struct wined3d_gl_info
{
DWORD selected_gl_version;
DWORD glsl_version;
struct wined3d_gl_limits limits;
DWORD reserved_glsl_constants, reserved_arb_constants;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment