This can be significantly more convenient than modifying the registry.
config_list_get_value() is based on vkd3d_debug_list_has_member() by Józef
Kucia.
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/wined3d/wined3d_main.c | 104 ++++++++++++++++++++++++++++--------
1 file changed, 81 insertions(+), 23 deletions(-)
diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c
index 5bddc2587f4..524dc7508f9 100644
--- a/dlls/wined3d/wined3d_main.c
+++ b/dlls/wined3d/wined3d_main.c
@@ -150,17 +150,67 @@ struct wined3d * CDECL wined3d_create(DWORD flags)
return object;
}
-static DWORD get_config_key(HKEY defkey, HKEY appkey, const char *name, char *buffer, DWORD size)
+static bool is_option_separator(char c)
{
+ return c == ',' || c == ';' || c == '\0';
+}
+
+static const char *config_list_get_value(const char *string, const char *key, size_t *len)
+{
+ const char *p, *end;
+ char prev_char;
+
+ p = string;
+ while (p)
+ {
+ if ((p = strstr(p, key)))
+ {
+ prev_char = p > string ? p[-1] : 0;
+ p += strlen(key);
+
+ if (is_option_separator(prev_char) && *p == '=')
+ {
+ if ((end = strpbrk(p + 1, ",;")))
+ *len = end - p + 1;
+ else
+ *len = strlen(p + 1);
+ return p + 1;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static DWORD get_config_key(HKEY defkey, HKEY appkey, const char *env, const char *name, char *buffer, DWORD size)
+{
+ const char *env_value;
+ size_t env_len;
+
+ if ((env_value = config_list_get_value(env, name, &env_len)) && env_len < size)
+ {
+ memcpy(buffer, env_value, env_len);
+ buffer[env_len] = 0;
+ return 0;
+ }
if (appkey && !RegQueryValueExA(appkey, name, 0, NULL, (BYTE *)buffer, &size)) return 0;
if (defkey && !RegQueryValueExA(defkey, name, 0, NULL, (BYTE *)buffer, &size)) return 0;
return ERROR_FILE_NOT_FOUND;
}
-static DWORD get_config_key_dword(HKEY defkey, HKEY appkey, const char *name, DWORD *value)
+static DWORD get_config_key_dword(HKEY defkey, HKEY appkey, const char *env, const char *name, DWORD *value)
{
DWORD type, data, size;
+ const char *env_value;
+ size_t env_len;
+ char *end;
+ if ((env_value = config_list_get_value(env, name, &env_len)))
+ {
+ *value = strtoul(env_value, &end, 0);
+ if (end != env_value)
+ return 0;
+ }
size = sizeof(data);
if (appkey && !RegQueryValueExA(appkey, name, 0, &type, (BYTE *)&data, &size) && type == REG_DWORD) goto success;
size = sizeof(data);
@@ -202,6 +252,7 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
DWORD wined3d_context_tls_idx;
char buffer[MAX_PATH+10];
DWORD size = sizeof(buffer);
+ const char *env;
HKEY hkey = 0;
HKEY appkey = 0;
DWORD tmpvalue;
@@ -259,17 +310,24 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
}
}
- if (hkey || appkey)
+ /* Allow modifying settings using the WINE_D3D_CONFIG environment variable,
+ * which takes precedence over registry keys. An example is as follows:
+ *
+ * WINE_D3D_CONFIG=csmt=0x1,shader_backend=glsl
+ */
+ env = getenv("WINE_D3D_CONFIG");
+
+ if (hkey || appkey || env)
{
- if (!get_config_key_dword(hkey, appkey, "csmt", &wined3d_settings.cs_multithreaded))
+ if (!get_config_key_dword(hkey, appkey, env, "csmt", &wined3d_settings.cs_multithreaded))
ERR_(winediag)("Setting multithreaded command stream to %#x.\n", wined3d_settings.cs_multithreaded);
- if (!get_config_key_dword(hkey, appkey, "MaxVersionGL", &tmpvalue))
+ if (!get_config_key_dword(hkey, appkey, env, "MaxVersionGL", &tmpvalue))
{
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, "shader_backend", buffer, size))
+ if (!get_config_key(hkey, appkey, env, "shader_backend", buffer, size))
{
if (!_strnicmp(buffer, "glsl", -1))
{
@@ -293,10 +351,10 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
ERR_(winediag)("The GLSL shader backend has been disabled. You get to keep all the pieces if it breaks.\n");
TRACE("Use of GL Shading Language disabled.\n");
}
- if (!get_config_key(hkey, appkey, "OffscreenRenderingMode", buffer, size)
+ if (!get_config_key(hkey, appkey, env, "OffscreenRenderingMode", buffer, size)
&& !strcmp(buffer,"backbuffer"))
wined3d_settings.offscreen_rendering_mode = ORM_BACKBUFFER;
- if ( !get_config_key_dword( hkey, appkey, "VideoPciDeviceID", &tmpvalue) )
+ if (!get_config_key_dword(hkey, appkey, env, "VideoPciDeviceID", &tmpvalue))
{
int pci_device_id = tmpvalue;
@@ -311,7 +369,7 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
wined3d_settings.pci_device_id = pci_device_id;
}
}
- if ( !get_config_key_dword( hkey, appkey, "VideoPciVendorID", &tmpvalue) )
+ if (!get_config_key_dword(hkey, appkey, env, "VideoPciVendorID", &tmpvalue))
{
int pci_vendor_id = tmpvalue;
@@ -326,7 +384,7 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
wined3d_settings.pci_vendor_id = pci_vendor_id;
}
}
- if ( !get_config_key( hkey, appkey, "VideoMemorySize", buffer, size) )
+ if (!get_config_key(hkey, appkey, env, "VideoMemorySize", buffer, size))
{
int TmpVideoMemorySize = atoi(buffer);
if(TmpVideoMemorySize > 0)
@@ -339,7 +397,7 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
else
ERR("VideoMemorySize is %i but must be >0\n", TmpVideoMemorySize);
}
- if ( !get_config_key( hkey, appkey, "WineLogo", buffer, size) )
+ if (!get_config_key(hkey, appkey, env, "WineLogo", buffer, size))
{
size_t len = strlen(buffer) + 1;
@@ -348,32 +406,32 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
else
memcpy(wined3d_settings.logo, buffer, len);
}
- if (!get_config_key_dword(hkey, appkey, "MultisampleTextures", &wined3d_settings.multisample_textures))
+ if (!get_config_key_dword(hkey, appkey, env, "MultisampleTextures", &wined3d_settings.multisample_textures))
ERR_(winediag)("Setting multisample textures to %#x.\n", wined3d_settings.multisample_textures);
- if (!get_config_key_dword(hkey, appkey, "SampleCount", &wined3d_settings.sample_count))
+ if (!get_config_key_dword(hkey, appkey, env, "SampleCount", &wined3d_settings.sample_count))
ERR_(winediag)("Forcing sample count to %u. This may not be compatible with all applications.\n",
wined3d_settings.sample_count);
- if (!get_config_key(hkey, appkey, "CheckFloatConstants", buffer, size)
+ if (!get_config_key(hkey, appkey, env, "CheckFloatConstants", buffer, size)
&& !strcmp(buffer, "enabled"))
{
TRACE("Checking relative addressing indices in float constants.\n");
wined3d_settings.check_float_constants = TRUE;
}
- if (!get_config_key_dword(hkey, appkey, "strict_shader_math", &wined3d_settings.strict_shader_math))
+ if (!get_config_key_dword(hkey, appkey, env, "strict_shader_math", &wined3d_settings.strict_shader_math))
ERR_(winediag)("Setting strict shader math to %#x.\n", wined3d_settings.strict_shader_math);
- if (!get_config_key_dword(hkey, appkey, "MaxShaderModelVS", &wined3d_settings.max_sm_vs))
+ if (!get_config_key_dword(hkey, appkey, env, "MaxShaderModelVS", &wined3d_settings.max_sm_vs))
TRACE("Limiting VS shader model to %u.\n", wined3d_settings.max_sm_vs);
- if (!get_config_key_dword(hkey, appkey, "MaxShaderModelHS", &wined3d_settings.max_sm_hs))
+ if (!get_config_key_dword(hkey, appkey, env, "MaxShaderModelHS", &wined3d_settings.max_sm_hs))
TRACE("Limiting HS shader model to %u.\n", wined3d_settings.max_sm_hs);
- if (!get_config_key_dword(hkey, appkey, "MaxShaderModelDS", &wined3d_settings.max_sm_ds))
+ if (!get_config_key_dword(hkey, appkey, env, "MaxShaderModelDS", &wined3d_settings.max_sm_ds))
TRACE("Limiting DS shader model to %u.\n", wined3d_settings.max_sm_ds);
- if (!get_config_key_dword(hkey, appkey, "MaxShaderModelGS", &wined3d_settings.max_sm_gs))
+ if (!get_config_key_dword(hkey, appkey, env, "MaxShaderModelGS", &wined3d_settings.max_sm_gs))
TRACE("Limiting GS shader model to %u.\n", wined3d_settings.max_sm_gs);
- if (!get_config_key_dword(hkey, appkey, "MaxShaderModelPS", &wined3d_settings.max_sm_ps))
+ if (!get_config_key_dword(hkey, appkey, env, "MaxShaderModelPS", &wined3d_settings.max_sm_ps))
TRACE("Limiting PS shader model to %u.\n", wined3d_settings.max_sm_ps);
- if (!get_config_key_dword(hkey, appkey, "MaxShaderModelCS", &wined3d_settings.max_sm_cs))
+ if (!get_config_key_dword(hkey, appkey, env, "MaxShaderModelCS", &wined3d_settings.max_sm_cs))
TRACE("Limiting CS shader model to %u.\n", wined3d_settings.max_sm_cs);
- if (!get_config_key(hkey, appkey, "renderer", buffer, size))
+ if (!get_config_key(hkey, appkey, env, "renderer", buffer, size))
{
if (!strcmp(buffer, "vulkan"))
{
@@ -391,7 +449,7 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
wined3d_settings.renderer = WINED3D_RENDERER_NO3D;
}
}
- if (!get_config_key_dword(hkey, appkey, "cb_access_map_w", &tmpvalue) && tmpvalue)
+ if (!get_config_key_dword(hkey, appkey, env, "cb_access_map_w", &tmpvalue) && tmpvalue)
{
TRACE("Forcing all constant buffers to be write-mappable.\n");
wined3d_settings.cb_access_map_w = TRUE;
--
2.35.1