From 60d9211f0f2862c503fdb1fe229bc96f2cc06be4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=B3zef=20Kucia?= Date: Thu, 22 Nov 2018 17:49:04 +0100 Subject: [PATCH] wined3d: Fix mapping of SV_VertexID to gl_VertexID. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 parameter, the value of is zero." Signed-off-by: Józef Kucia Signed-off-by: Henri Verbeet Signed-off-by: Alexandre Julliard --- 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 ca79b711714..c7c0c0bddb8 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 545e1bff9f5..ad59e97e3fc 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 f908ff71732..4e80cc75acf 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 { -- 2.11.4.GIT