=?UTF-8?Q?J=C3=B3zef=20Kucia=20?=: wined3d: Fix mapping of SV_VertexID to gl_VertexID.

Alexandre Julliard julliard at winehq.org
Fri Nov 23 14:18:03 CST 2018


Module: wine
Branch: master
Commit: 60d9211f0f2862c503fdb1fe229bc96f2cc06be4
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=60d9211f0f2862c503fdb1fe229bc96f2cc06be4

Author: Józef Kucia <jkucia at codeweavers.com>
Date:   Thu Nov 22 17:49:04 2018 +0100

wined3d: Fix mapping of SV_VertexID to gl_VertexID.

Based on a patch by Andrew Wesie.

In Direct3D, SV_VertexID generally starts from zero. In OpenGL,
gl_VertexID starts from "first" parameter passed to glDrawArrays(), or
from "baseVertex" parameter for indexed draw calls.  The
GL_ARB_shader_draw_parameters extension doesn't help us much because
gl_BaseVertexARB is zero for non-indexed draw calls [1]. If
gl_BaseVertexARB would be equal to "first" for non-indexed draw calls,
we could simply use gl_VertexID - gl_BaseVertexARB.

After this commit, SV_VertexID is still wrong for indirect draw calls
because we cannot easily access the "first" field from struct
DrawArraysIndirectCommand in a vertex shader.

[1] - The ARB_shader_draw_parameters spec says that "In the case where
the command has no <baseVertex> parameter, the value of
<gl_BaseVertexARB> is zero."

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/wined3d/cs.c              |  9 ++++++++-
 dlls/wined3d/glsl_shader.c     | 29 +++++++++++++++++++----------
 dlls/wined3d/wined3d_private.h |  1 +
 3 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index ca79b71..c7c0c0b 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -845,6 +845,7 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data)
     const struct wined3d_d3d_info *d3d_info = &cs->device->adapter->d3d_info;
     const struct wined3d_gl_info *gl_info = &cs->device->adapter->gl_info;
     const struct wined3d_shader *geometry_shader;
+    struct wined3d_device *device = cs->device;
     int base_vertex_idx, load_base_vertex_idx;
     struct wined3d_state *state = &cs->state;
     const struct wined3d_cs_draw *op = data;
@@ -867,7 +868,13 @@ static void wined3d_cs_exec_draw(struct wined3d_cs *cs, const void *data)
     else
         load_base_vertex_idx = 0;
 
-    state->base_vertex_index = base_vertex_idx;
+    if (state->base_vertex_index != base_vertex_idx)
+    {
+        state->base_vertex_index = base_vertex_idx;
+        for (i = 0; i < device->context_count; ++i)
+            device->contexts[i]->constant_update_mask |= WINED3D_SHADER_CONST_BASE_VERTEX_ID;
+    }
+
     if (state->load_base_vertex_index != load_base_vertex_idx)
     {
         state->load_base_vertex_index = load_base_vertex_idx;
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 545e1bf..ad59e97 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -155,6 +155,7 @@ struct glsl_vs_program
     GLint uniform_i_locations[WINED3D_MAX_CONSTS_I];
     GLint uniform_b_locations[WINED3D_MAX_CONSTS_B];
     GLint pos_fixup_location;
+    GLint base_vertex_id_location;
 
     GLint modelview_matrix_location[MAX_VERTEX_BLENDS];
     GLint projection_matrix_location;
@@ -1775,22 +1776,21 @@ static void shader_glsl_load_color_key_constant(const struct glsl_ps_program *ps
 static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context *context,
         const struct wined3d_state *state)
 {
-    const struct glsl_context_data *ctx_data = context->shader_backend_data;
     const struct wined3d_shader *vshader = state->shader[WINED3D_SHADER_TYPE_VERTEX];
     const struct wined3d_shader *pshader = state->shader[WINED3D_SHADER_TYPE_PIXEL];
+    const struct glsl_context_data *ctx_data = context->shader_backend_data;
+    struct glsl_shader_prog_link *prog = ctx_data->glsl_program;
     const struct wined3d_gl_info *gl_info = context->gl_info;
-    struct shader_glsl_priv *priv = shader_priv;
     float position_fixup[4 * WINED3D_MAX_VIEWPORTS];
+    struct shader_glsl_priv *priv = shader_priv;
+    unsigned int constant_version;
     DWORD update_mask;
-
-    struct glsl_shader_prog_link *prog = ctx_data->glsl_program;
-    UINT constant_version;
     int i;
 
-    if (!prog) {
-        /* No GLSL program set - nothing to do. */
+    /* No GLSL program set - nothing to do. */
+    if (!prog)
         return;
-    }
+
     constant_version = prog->constant_version;
     update_mask = context->constant_update_mask & prog->constant_update_mask;
 
@@ -1829,6 +1829,12 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context
         checkGLcall("glUniform4fv");
     }
 
+    if (update_mask & WINED3D_SHADER_CONST_BASE_VERTEX_ID)
+    {
+        GL_EXTCALL(glUniform1i(prog->vs.base_vertex_id_location, state->base_vertex_index));
+        checkGLcall("base vertex id");
+    }
+
     if (update_mask & WINED3D_SHADER_CONST_FFP_MODELVIEW)
     {
         struct wined3d_matrix mat;
@@ -2359,8 +2365,8 @@ static void shader_glsl_declare_generic_vertex_attribute(struct wined3d_string_b
 
     if (e->sysval_semantic == WINED3D_SV_VERTEX_ID)
     {
-        shader_addline(buffer, "vec4 vs_in%u = vec4(intBitsToFloat(gl_VertexID), 0.0, 0.0, 0.0);\n",
-                index);
+        shader_addline(buffer, "uniform int base_vertex_id;\n");
+        shader_addline(buffer, "vec4 vs_in%u = vec4(intBitsToFloat(gl_VertexID - base_vertex_id), 0.0, 0.0, 0.0);\n", index);
         return;
     }
     if (e->sysval_semantic == WINED3D_SV_INSTANCE_ID)
@@ -10123,6 +10129,7 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info *
     }
 
     vs->pos_fixup_location = GL_EXTCALL(glGetUniformLocation(program_id, "pos_fixup"));
+    vs->base_vertex_id_location = GL_EXTCALL(glGetUniformLocation(program_id, "base_vertex_id"));
 
     for (i = 0; i < MAX_VERTEX_BLENDS; ++i)
     {
@@ -10694,6 +10701,8 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
             entry->constant_update_mask |= WINED3D_SHADER_CONST_VS_B;
         if (entry->vs.pos_fixup_location != -1)
             entry->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP;
+        if (entry->vs.base_vertex_id_location != -1)
+            entry->constant_update_mask |= WINED3D_SHADER_CONST_BASE_VERTEX_ID;
 
         shader_glsl_load_program_resources(context, priv, program_id, vshader);
     }
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index f908ff7..4e80cc7 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -445,6 +445,7 @@ enum wined3d_shader_resource_type
 #define WINED3D_SHADER_CONST_FFP_LIGHTS      0x00080000
 #define WINED3D_SHADER_CONST_FFP_PS          0x00100000
 #define WINED3D_SHADER_CONST_FFP_COLOR_KEY   0x00200000
+#define WINED3D_SHADER_CONST_BASE_VERTEX_ID  0x00400000
 
 enum wined3d_shader_register_type
 {




More information about the wine-cvs mailing list