[PATCH] wined3d: Allow changing settings using a new WINE_D3D_CONFIG environment variable.

Zebediah Figura zfigura at codeweavers.com
Tue Mar 8 12:10:00 CST 2022


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 at codeweavers.com>
---
 dlls/wined3d/wined3d_main.c | 108 +++++++++++++++++++++++++++---------
 1 file changed, 83 insertions(+), 25 deletions(-)

diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c
index 248c886542f..a4eb23eac05 100644
--- a/dlls/wined3d/wined3d_main.c
+++ b/dlls/wined3d/wined3d_main.c
@@ -152,17 +152,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);
@@ -214,6 +264,7 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
     char app_name[MAX_PATH], buffer[MAX_PATH + 10];
     DWORD wined3d_context_tls_idx;
     DWORD size = sizeof(buffer);
+    const char *env;
     HKEY hkey = 0;
     HKEY appkey = 0;
     DWORD tmpvalue;
@@ -271,17 +322,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))
             {
@@ -305,10 +363,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;
 
@@ -323,7 +381,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;
 
@@ -338,7 +396,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)
@@ -351,7 +409,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;
 
@@ -360,38 +418,38 @@ static BOOL wined3d_dll_init(HINSTANCE hInstDLL)
             else
                 memcpy(wined3d_settings.logo, buffer, len);
         }
-        if (!get_config_key_dword(hkey, appkey, "MultisampleTextures", &tmpvalue))
+        if (!get_config_key_dword(hkey, appkey, env, "MultisampleTextures", &tmpvalue))
         {
             wined3d_settings.multisample_textures = !!tmpvalue;
             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 = 1;
         }
-        if (!get_config_key_dword(hkey, appkey, "strict_shader_math", &tmpvalue))
+        if (!get_config_key_dword(hkey, appkey, env, "strict_shader_math", &tmpvalue))
         {
             wined3d_settings.strict_shader_math = !!tmpvalue;
             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"))
             {
@@ -409,18 +467,18 @@ 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 = 1;
         }
-        if (!get_config_key_dword(hkey, appkey, "lenient_nooverwrite", &tmpvalue))
+        if (!get_config_key_dword(hkey, appkey, env, "lenient_nooverwrite", &tmpvalue))
             wined3d_settings.lenient_nooverwrite = tmpvalue;
         else
             wined3d_settings.lenient_nooverwrite = quirk_match_lenient_nooverwrite(app_name);
         if (wined3d_settings.lenient_nooverwrite)
             TRACE("Allowing DISCARD and NOOVERWRITE maps on non-dynamic resources.\n");
-        if (!get_config_key_dword(hkey, appkey, "fake_screen_bit_depth", &wined3d_settings.fake_screen_bit_depth))
+        if (!get_config_key_dword(hkey, appkey, env, "fake_screen_bit_depth", &wined3d_settings.fake_screen_bit_depth))
             TRACE("Overriding screen bit depth with %u.\n", wined3d_settings.fake_screen_bit_depth);
     }
 
-- 
2.35.1




More information about the wine-devel mailing list