Henri Verbeet : wined3d: Handle pre-transformed vertices in the GLSL vertex pipe.

Alexandre Julliard julliard at winehq.org
Fri Jun 14 11:03:50 CDT 2013


Module: wine
Branch: master
Commit: ffc9f535eb7817ea4cd0d0657471e61a9813debd
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=ffc9f535eb7817ea4cd0d0657471e61a9813debd

Author: Henri Verbeet <hverbeet at codeweavers.com>
Date:   Fri Jun 14 09:07:12 2013 +0200

wined3d: Handle pre-transformed vertices in the GLSL vertex pipe.

This also avoids a fallback to drawStridedSlow().

---

 dlls/wined3d/buffer.c          |   11 ++++++-----
 dlls/wined3d/device.c          |    7 ++-----
 dlls/wined3d/directx.c         |    4 ++++
 dlls/wined3d/glsl_shader.c     |   20 +++++++++++++++-----
 dlls/wined3d/state.c           |    1 +
 dlls/wined3d/utils.c           |    4 ++--
 dlls/wined3d/wined3d_private.h |    5 ++++-
 7 files changed, 34 insertions(+), 18 deletions(-)

diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index adfae98..586b16c 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -266,7 +266,7 @@ static BOOL buffer_process_converted_attribute(struct wined3d_buffer *This,
 }
 
 static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct wined3d_stream_info *si,
-        UINT attrib_idx, const BOOL check_d3dcolor, const BOOL is_ffp_position, const BOOL is_ffp_color,
+        UINT attrib_idx, const BOOL check_d3dcolor, const BOOL check_position, const BOOL is_ffp_color,
         DWORD *stride_this_run)
 {
     const struct wined3d_stream_info_element *attrib = &si->elements[attrib_idx];
@@ -288,7 +288,7 @@ static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct win
 
         if (!is_ffp_color) FIXME("Test for non-color fixed function WINED3DFMT_B8G8R8A8_UNORM format\n");
     }
-    else if (is_ffp_position && si->position_transformed)
+    else if (check_position && si->position_transformed)
     {
         if (format != WINED3DFMT_R32G32B32A32_FLOAT)
         {
@@ -309,12 +309,13 @@ static BOOL buffer_check_attribute(struct wined3d_buffer *This, const struct win
 static BOOL buffer_find_decl(struct wined3d_buffer *This)
 {
     struct wined3d_device *device = This->resource.device;
-    const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
+    const struct wined3d_adapter *adapter = device->adapter;
     const struct wined3d_stream_info *si = &device->stream_info;
     const struct wined3d_state *state = &device->stateBlock->state;
+    BOOL support_d3dcolor = adapter->gl_info.supported[ARB_VERTEX_ARRAY_BGRA];
+    BOOL support_xyzrhw = adapter->d3d_info.xyzrhw;
     UINT stride_this_run = 0;
     BOOL ret = FALSE;
-    BOOL support_d3dcolor = gl_info->supported[ARB_VERTEX_ARRAY_BGRA];
 
     /* In d3d7 the vertex buffer declaration NEVER changes because it is stored in the d3d7 vertex buffer.
      * Once we have our declaration there is no need to look it up again. Index buffers also never need
@@ -386,7 +387,7 @@ static BOOL buffer_find_decl(struct wined3d_buffer *This)
      */
 
     ret = buffer_check_attribute(This, si, WINED3D_FFP_POSITION,
-            TRUE, TRUE,  FALSE, &stride_this_run) || ret;
+            TRUE, !support_xyzrhw,  FALSE, &stride_this_run) || ret;
     ret = buffer_check_attribute(This, si, WINED3D_FFP_NORMAL,
             TRUE, FALSE, FALSE, &stride_this_run) || ret;
     ret = buffer_check_attribute(This, si, WINED3D_FFP_DIFFUSE,
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 42456b0..464181f 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -332,14 +332,11 @@ void device_update_stream_info(struct wined3d_device *device, const struct wined
         slow_mask |= -!gl_info->supported[ARB_VERTEX_ARRAY_BGRA]
                 & ((1 << WINED3D_FFP_DIFFUSE) | (1 << WINED3D_FFP_SPECULAR));
 
-        if ((stream_info->position_transformed || (stream_info->use_map & slow_mask)) && !stream_info->all_vbo)
-        {
+        if (((stream_info->position_transformed && !device->adapter->d3d_info.xyzrhw)
+                || (stream_info->use_map & slow_mask)) && !stream_info->all_vbo)
             device->useDrawStridedSlow = TRUE;
-        }
         else
-        {
             device->useDrawStridedSlow = FALSE;
-        }
     }
 
     if (prev_all_vbo != stream_info->all_vbo)
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 91e5d1f..067c60b 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2635,6 +2635,7 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
     struct wined3d_driver_info *driver_info = &adapter->driver_info;
     const char *gl_vendor_str, *gl_renderer_str, *gl_version_str;
     struct wined3d_gl_info *gl_info = &adapter->gl_info;
+    struct wined3d_vertex_caps vertex_caps;
     enum wined3d_pci_vendor card_vendor;
     struct fragment_caps fragment_caps;
     struct shader_caps shader_caps;
@@ -2865,6 +2866,9 @@ static BOOL wined3d_adapter_init_gl_caps(struct wined3d_adapter *adapter)
     adapter->d3d_info.limits.vs_uniform_count = shader_caps.vs_uniform_count;
     adapter->d3d_info.limits.ps_uniform_count = shader_caps.ps_uniform_count;
 
+    adapter->vertex_pipe->vp_get_caps(gl_info, &vertex_caps);
+    adapter->d3d_info.xyzrhw = vertex_caps.xyzrhw;
+
     adapter->fragment_pipe->get_caps(gl_info, &fragment_caps);
     adapter->d3d_info.limits.ffp_blend_stages = fragment_caps.MaxTextureBlendStages;
     adapter->d3d_info.limits.ffp_textures = fragment_caps.MaxSimultaneousTextures;
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 412c601..e14d7ab 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -5011,11 +5011,20 @@ static GLhandleARB shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_
     shader_addline(buffer, "float m;\n");
     shader_addline(buffer, "vec3 r;\n");
 
-    shader_addline(buffer, "vec4 ec_pos = gl_ModelViewMatrix * gl_Vertex;\n");
-    shader_addline(buffer, "gl_Position = gl_ProjectionMatrix * ec_pos;\n");
-    if (settings->clipping)
-        shader_addline(buffer, "gl_ClipVertex = ec_pos;\n");
-    shader_addline(buffer, "ec_pos /= ec_pos.w;\n");
+    if (settings->transformed)
+    {
+        shader_addline(buffer, "vec4 ec_pos = vec4(gl_Vertex.xyz, 1.0);\n");
+        shader_addline(buffer, "gl_Position = gl_ProjectionMatrix * ec_pos;\n");
+        shader_addline(buffer, "if (gl_Vertex.w != 0.0) gl_Position /= gl_Vertex.w;\n");
+    }
+    else
+    {
+        shader_addline(buffer, "vec4 ec_pos = gl_ModelViewMatrix * gl_Vertex;\n");
+        shader_addline(buffer, "gl_Position = gl_ProjectionMatrix * ec_pos;\n");
+        if (settings->clipping)
+            shader_addline(buffer, "gl_ClipVertex = ec_pos;\n");
+        shader_addline(buffer, "ec_pos /= ec_pos.w;\n");
+    }
 
     if (!settings->normal)
         shader_addline(buffer, "vec3 normal = vec3(0.0);\n");
@@ -6737,6 +6746,7 @@ static void glsl_vertex_pipe_vp_enable(const struct wined3d_gl_info *gl_info, BO
 
 static void glsl_vertex_pipe_vp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
 {
+    caps->xyzrhw = TRUE;
     caps->max_active_lights = gl_info->limits.lights;
     caps->max_vertex_blend_matrices = 0;
     caps->max_vertex_blend_matrix_index = 0;
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 74261ec..ffce803 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -5641,6 +5641,7 @@ static void ffp_free(struct wined3d_device *device) {}
 
 static void vp_ffp_get_caps(const struct wined3d_gl_info *gl_info, struct wined3d_vertex_caps *caps)
 {
+    caps->xyzrhw = FALSE;
     caps->max_active_lights = gl_info->limits.lights;
     caps->max_vertex_blend_matrices = gl_info->limits.blends;
     caps->max_vertex_blend_matrix_index = 0;
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index b83a05a..5b7fb3c 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -3552,8 +3552,7 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct
     {
         memset(settings, 0, sizeof(*settings));
 
-        settings->clipping = state->render_states[WINED3D_RS_CLIPPING]
-                && state->render_states[WINED3D_RS_CLIPPLANEENABLE];
+        settings->transformed = 1;
         settings->point_size = state->gl_primitive_type == GL_POINTS;
         if (!state->render_states[WINED3D_RS_FOGENABLE])
             settings->fog_mode = WINED3D_FFP_VS_FOG_OFF;
@@ -3573,6 +3572,7 @@ void wined3d_ffp_get_vs_settings(const struct wined3d_state *state, const struct
         return;
     }
 
+    settings->transformed = 0;
     settings->clipping = state->render_states[WINED3D_RS_CLIPPING]
             && state->render_states[WINED3D_RS_CLIPPLANEENABLE];
     settings->normal = !!(si->use_map & (1 << WINED3D_FFP_NORMAL));
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 82a4584..1fbe081 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1193,6 +1193,7 @@ struct fragment_pipeline
 
 struct wined3d_vertex_caps
 {
+    BOOL xyzrhw;
     DWORD max_active_lights;
     DWORD max_vertex_blend_matrices;
     DWORD max_vertex_blend_matrix_index;
@@ -1606,6 +1607,7 @@ struct wined3d_d3d_limits
 struct wined3d_d3d_info
 {
     struct wined3d_d3d_limits limits;
+    BOOL xyzrhw;
     BOOL vs_clipping;
     DWORD valid_rt_mask;
 };
@@ -1723,6 +1725,7 @@ struct wined3d_ffp_vs_settings
     DWORD ambient_source  : 2;
     DWORD specular_source : 2;
 
+    DWORD transformed     : 1;
     DWORD clipping        : 1;
     DWORD normal          : 1;
     DWORD normalize       : 1;
@@ -1731,7 +1734,7 @@ struct wined3d_ffp_vs_settings
     DWORD point_size      : 1;
     DWORD fog_mode        : 2;
     DWORD texcoords       : 8;  /* MAX_TEXTURES */
-    DWORD padding         : 16;
+    DWORD padding         : 15;
 
     BYTE texgen[MAX_TEXTURES];
 };




More information about the wine-cvs mailing list