Commit 60d9211f authored by Józef Kucia's avatar Józef Kucia Committed by Alexandre Julliard

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: 's avatarJózef Kucia <jkucia@codeweavers.com> Signed-off-by: 's avatarHenri Verbeet <hverbeet@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent ceef4e77
......@@ -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;
......
......@@ -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);
}
......
......@@ -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
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment