[PATCH 2/5] wined3d: Add a setting for the maximum OpenGL version to use. (v2)
Matteo Bruni
mbruni at codeweavers.com
Wed Jul 8 08:47:01 CDT 2015
---
sort-of-v2: Allow to set a maximum GL version instead of a core/legacy
profile switch, flag the context type with a WINED3D_GL_ "extension".
Drop the DEBUG_BIT part from wined3d_adapter_init() since
at that point the gl_info->supported[] flags aren't initialized yet.
v2: Introduce a helper function for the creation of the WGL context, print
a winediag message whenever the registry key selects a non-default max GL
version, rename the registry key to MaxVersionGL and make it DWORD.
A lot of stuff is still missing so 3.2 core profile doesn't work at the
moment (on some GL implementations it's going to crash if you enable the
option, actually). Still I need something like this to avoid adding dead
code moving forward.
---
dlls/wined3d/context.c | 52 +++++++++++++------
dlls/wined3d/directx.c | 113 +++++++++++++++++++++++++++++++----------
dlls/wined3d/wined3d_gl.h | 1 +
dlls/wined3d/wined3d_main.c | 10 ++++
dlls/wined3d/wined3d_private.h | 7 ++-
5 files changed, 137 insertions(+), 46 deletions(-)
diff --git a/dlls/wined3d/context.c b/dlls/wined3d/context.c
index 9cc7c11..c74983e 100644
--- a/dlls/wined3d/context.c
+++ b/dlls/wined3d/context.c
@@ -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
{
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 059332d..42072e9 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -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))
{
diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h
index 4257cd2..8c07ed1 100644
--- a/dlls/wined3d/wined3d_gl.h
+++ b/dlls/wined3d/wined3d_gl.h
@@ -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,
diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c
index 758ba43..0543d97 100644
--- a/dlls/wined3d/wined3d_main.c
+++ b/dlls/wined3d/wined3d_main.c
@@ -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"))
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index b7fa4c6..8dd9e80 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -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;
--
2.3.6
More information about the wine-patches
mailing list