wined3d: Use shader and fragment capabilities to select d3d level

Andrei Slăvoiu andrei.slavoiu at gmail.com
Mon Jun 23 14:10:56 CDT 2014


Remove code duplication by checking the caps from the shader_backend (DX8 and newer) or the fragment_pipeline (DX6 & 7).

I had to move select_fragment_implementation and select_shader_backend before d3d_level_from_gl_info to be able to use them and that makes the diff appear more complicated then it really is.

Using forward declarations instead would make the diff look cleaner but the resulting code messier so I opted for moving them.

---
 dlls/wined3d/directx.c | 120 ++++++++++++++++++++++++++-----------------------
 1 file changed, 64 insertions(+), 56 deletions(-)

diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index d6bb3836..11dda4d 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -1651,27 +1651,72 @@ static enum wined3d_pci_vendor wined3d_guess_card_vendor(const char *gl_vendor_s
     return HW_VENDOR_NVIDIA;
 }
 
-static UINT d3d_level_from_gl_info(const struct wined3d_gl_info *gl_info)
+static const struct fragment_pipeline *select_fragment_implementation(const struct wined3d_gl_info *gl_info,
+        const struct wined3d_shader_backend_ops *shader_backend_ops)
+{
+    if (shader_backend_ops == &glsl_shader_backend)
+        return &glsl_fragment_pipe;
+    if (shader_backend_ops == &arb_program_shader_backend && gl_info->supported[ARB_FRAGMENT_PROGRAM])
+        return &arbfp_fragment_pipeline;
+    if (gl_info->supported[ATI_FRAGMENT_SHADER])
+        return &atifs_fragment_pipeline;
+    if (gl_info->supported[NV_REGISTER_COMBINERS] && gl_info->supported[NV_TEXTURE_SHADER2])
+        return &nvts_fragment_pipeline;
+    if (gl_info->supported[NV_REGISTER_COMBINERS])
+        return &nvrc_fragment_pipeline;
+    return &ffp_fragment_pipeline;
+}
+
+static const struct wined3d_shader_backend_ops *select_shader_backend(const struct wined3d_gl_info *gl_info)
 {
-    UINT level = 0;
+    BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
 
-    if (gl_info->supported[ARB_MULTITEXTURE])
-        level = 6;
-    if (gl_info->supported[ARB_TEXTURE_COMPRESSION]
-            && gl_info->supported[ARB_TEXTURE_CUBE_MAP]
-            && gl_info->supported[ARB_TEXTURE_ENV_DOT3])
-        level = 7;
-    if (level == 7 && gl_info->supported[ARB_MULTISAMPLE]
-            && gl_info->supported[ARB_TEXTURE_BORDER_CLAMP])
-        level = 8;
-    if (level == 8 && gl_info->supported[ARB_FRAGMENT_PROGRAM]
-            && gl_info->supported[ARB_VERTEX_SHADER])
-        level = 9;
-    if (level == 9 && (gl_info->supported[EXT_GPU_SHADER4]
-	    || gl_info->glsl_version >= MAKEDWORD_VERSION(1, 30)))
-        level = 10;
-
-    return level;
+    if (glsl && gl_info->supported[ARB_FRAGMENT_SHADER])
+        return &glsl_shader_backend;
+    if (glsl && gl_info->supported[ARB_VERTEX_SHADER])
+    {
+        /* Geforce4 cards support GLSL but for vertex shaders only. Further
+         * its reported GLSL caps are wrong. This combined with the fact that
+         * GLSL won't offer more features or performance, use ARB shaders only
+         * on this card. */
+        if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2])
+            return &arb_program_shader_backend;
+        return &glsl_shader_backend;
+    }
+    if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
+        return &arb_program_shader_backend;
+    return &none_shader_backend;
+}
+
+static UINT d3d_level_from_gl_info(const struct wined3d_gl_info *gl_info)
+{
+    struct shader_caps shader_caps;
+    struct fragment_caps fragment_caps;
+    const struct wined3d_shader_backend_ops *shader_backend;
+    const struct fragment_pipeline *fragment_pipeline;
+
+    shader_backend = select_shader_backend(gl_info);
+    shader_backend->shader_get_caps(gl_info, &shader_caps);
+
+    if (shader_caps.vs_version >= 4)
+      return 10;
+    //wine can not use SM 4 on mesa drivers as the necessary functionality is not exposed on compatibility contexts, but still set the pci id accordingly
+    if (shader_caps.vs_version == 3 && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 30))
+      return 10;
+    if (shader_caps.vs_version >= 2)
+      return 9;
+    if (shader_caps.vs_version == 1)
+      return 8;
+
+    fragment_pipeline = select_fragment_implementation(gl_info, shader_backend);
+    fragment_pipeline->get_caps(gl_info, &fragment_caps);
+
+    if (fragment_caps.TextureOpCaps & WINED3DTEXOPCAPS_DOTPRODUCT3)
+      return 7;
+    if (gl_info->limits.textures > 1)
+      return 6;
+
+    return 0;
 }
 
 static enum wined3d_pci_device select_card_nvidia_binary(const struct wined3d_gl_info *gl_info,
@@ -2480,43 +2525,6 @@ static const struct wined3d_vertex_pipe_ops *select_vertex_implementation(const
     return &ffp_vertex_pipe;
 }
 
-static const struct fragment_pipeline *select_fragment_implementation(const struct wined3d_gl_info *gl_info,
-        const struct wined3d_shader_backend_ops *shader_backend_ops)
-{
-    if (shader_backend_ops == &glsl_shader_backend)
-        return &glsl_fragment_pipe;
-    if (shader_backend_ops == &arb_program_shader_backend && gl_info->supported[ARB_FRAGMENT_PROGRAM])
-        return &arbfp_fragment_pipeline;
-    if (gl_info->supported[ATI_FRAGMENT_SHADER])
-        return &atifs_fragment_pipeline;
-    if (gl_info->supported[NV_REGISTER_COMBINERS] && gl_info->supported[NV_TEXTURE_SHADER2])
-        return &nvts_fragment_pipeline;
-    if (gl_info->supported[NV_REGISTER_COMBINERS])
-        return &nvrc_fragment_pipeline;
-    return &ffp_fragment_pipeline;
-}
-
-static const struct wined3d_shader_backend_ops *select_shader_backend(const struct wined3d_gl_info *gl_info)
-{
-    BOOL glsl = wined3d_settings.glslRequested && gl_info->glsl_version >= MAKEDWORD_VERSION(1, 20);
-
-    if (glsl && gl_info->supported[ARB_FRAGMENT_SHADER])
-        return &glsl_shader_backend;
-    if (glsl && gl_info->supported[ARB_VERTEX_SHADER])
-    {
-        /* Geforce4 cards support GLSL but for vertex shaders only. Further
-         * its reported GLSL caps are wrong. This combined with the fact that
-         * GLSL won't offer more features or performance, use ARB shaders only
-         * on this card. */
-        if (gl_info->supported[NV_VERTEX_PROGRAM] && !gl_info->supported[NV_VERTEX_PROGRAM2])
-            return &arb_program_shader_backend;
-        return &glsl_shader_backend;
-    }
-    if (gl_info->supported[ARB_VERTEX_PROGRAM] || gl_info->supported[ARB_FRAGMENT_PROGRAM])
-        return &arb_program_shader_backend;
-    return &none_shader_backend;
-}
-
 static const struct blit_shader *select_blit_implementation(const struct wined3d_gl_info *gl_info,
         const struct wined3d_shader_backend_ops *shader_backend_ops)
 {
-- 
2.0.0





More information about the wine-patches mailing list