From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/glsl_shader.c | 48 ++++++++++------------------------ dlls/wined3d/stateblock.c | 34 +++++++++++++++++++++--- dlls/wined3d/utils.c | 2 +- dlls/wined3d/wined3d_private.h | 3 ++- 4 files changed, 47 insertions(+), 40 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 7d14ba7580d..78926739310 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1563,17 +1563,16 @@ static void get_projection_matrix(const struct wined3d_context *context, }
static void shader_glsl_ffp_vertex_normalmatrix_uniform(const struct wined3d_context_gl *context_gl, - const struct wined3d_state *state, struct glsl_shader_prog_link *prog) + const struct wined3d_ffp_vs_constants *constants, struct glsl_shader_prog_link *prog) { const struct wined3d_gl_info *gl_info = context_gl->gl_info; - struct wined3d_matrix mv; float mat[3 * 3];
if (prog->vs.normal_matrix_location == -1) return;
- get_modelview_matrix(state, 0, &mv); - compute_normal_matrix(mat, context_gl->c.d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING, &mv); + compute_normal_matrix(mat, context_gl->c.d3d_info->wined3d_creation_flags & WINED3D_LEGACY_FFP_LIGHTING, + &constants->modelview_matrices[0]);
GL_EXTCALL(glUniformMatrix3fv(prog->vs.normal_matrix_location, 1, FALSE, mat)); checkGLcall("glUniformMatrix3fv"); @@ -1788,26 +1787,30 @@ static void shader_glsl_load_constants(struct shader_glsl_priv *priv,
if (update_mask & WINED3D_SHADER_CONST_FFP_MODELVIEW) { - struct wined3d_matrix mat; + const struct wined3d_ffp_vs_constants *constants;
- get_modelview_matrix(state, 0, &mat); - GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[0], 1, FALSE, &mat._11)); + constants = wined3d_buffer_load_sysmem(context->device->push_constants[WINED3D_PUSH_CONSTANTS_VS_FFP], context); + + GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[0], 1, + FALSE, &constants->modelview_matrices[0]._11)); checkGLcall("glUniformMatrix4fv");
- shader_glsl_ffp_vertex_normalmatrix_uniform(context_gl, state, prog); + shader_glsl_ffp_vertex_normalmatrix_uniform(context_gl, constants, prog); }
if (update_mask & WINED3D_SHADER_CONST_FFP_VERTEXBLEND) { - struct wined3d_matrix mat; + const struct wined3d_ffp_vs_constants *constants; + + constants = wined3d_buffer_load_sysmem(context->device->push_constants[WINED3D_PUSH_CONSTANTS_VS_FFP], context);
for (i = 1; i < MAX_VERTEX_BLENDS; ++i) { if (prog->vs.modelview_matrix_location[i] == -1) break;
- get_modelview_matrix(state, i, &mat); - GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], 1, FALSE, &mat._11)); + GL_EXTCALL(glUniformMatrix4fv(prog->vs.modelview_matrix_location[i], + 1, FALSE, &constants->modelview_matrices[i]._11)); checkGLcall("glUniformMatrix4fv"); } } @@ -11908,24 +11911,6 @@ static void glsl_vertex_pipe_pixel_shader(struct wined3d_context *context, context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_VERTEX; }
-static void glsl_vertex_pipe_world(struct wined3d_context *context, - const struct wined3d_state *state, DWORD state_id) -{ - context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW; -} - -static void glsl_vertex_pipe_vertexblend(struct wined3d_context *context, - const struct wined3d_state *state, DWORD state_id) -{ - context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_VERTEXBLEND; -} - -static void glsl_vertex_pipe_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) -{ - context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW - | WINED3D_SHADER_CONST_FFP_VERTEXBLEND; -} - static void glsl_vertex_pipe_projection(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { @@ -12015,12 +12000,7 @@ static const struct wined3d_state_entry_template glsl_vertex_pipe_vp_states[] = /* Viewport */ {STATE_VIEWPORT, {STATE_VIEWPORT, glsl_vertex_pipe_viewport}, WINED3D_GL_EXT_NONE }, /* Transform states */ - {STATE_TRANSFORM(WINED3D_TS_VIEW), {STATE_TRANSFORM(WINED3D_TS_VIEW), glsl_vertex_pipe_view }, WINED3D_GL_EXT_NONE }, {STATE_TRANSFORM(WINED3D_TS_PROJECTION), {STATE_TRANSFORM(WINED3D_TS_PROJECTION), glsl_vertex_pipe_projection}, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(0)), glsl_vertex_pipe_world }, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(1)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(2)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)), {STATE_TRANSFORM(WINED3D_TS_WORLD_MATRIX(3)), glsl_vertex_pipe_vertexblend }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXCOORD_INDEX), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXCOORD_INDEX), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), NULL }, WINED3D_GL_EXT_NONE }, {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXCOORD_INDEX), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), NULL }, WINED3D_GL_EXT_NONE }, diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 8e638033eb0..d32e95e98fa 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -62,6 +62,7 @@ struct wined3d_saved_states * translation from stateblock formats to wined3d_state formats. */ uint32_t ffp_ps_constants : 1; uint32_t texture_matrices : 1; + uint32_t modelview_matrices : 1; };
struct stage_state @@ -1580,6 +1581,10 @@ void CDECL wined3d_stateblock_set_render_state(struct wined3d_stateblock *stateb stateblock->changed.ffp_ps_constants = 1; break;
+ case WINED3D_RS_VERTEXBLEND: + stateblock->changed.modelview_matrices = 1; + break; + default: break; } @@ -1673,6 +1678,8 @@ void CDECL wined3d_stateblock_set_transform(struct wined3d_stateblock *statebloc
if (d3dts >= WINED3D_TS_TEXTURE0 && d3dts <= WINED3D_TS_TEXTURE7) stateblock->changed.texture_matrices = 1; + else if (d3dts == WINED3D_TS_VIEW || d3dts >= WINED3D_TS_WORLD) + stateblock->changed.modelview_matrices = 1; }
void CDECL wined3d_stateblock_multiply_transform(struct wined3d_stateblock *stateblock, @@ -2252,7 +2259,8 @@ static void wined3d_stateblock_invalidate_push_constants(struct wined3d_stateblo stateblock->changed.texture_matrices = 1; stateblock->changed.material = 1; stateblock->changed.transforms = 1; - wined3d_bitmap_set(stateblock->changed.transform, WINED3D_TS_PROJECTION); + memset(stateblock->changed.transform, 0xff, sizeof(stateblock->changed.transform)); + stateblock->changed.modelview_matrices = 1; }
static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, const struct wined3d_stateblock *device_state, @@ -3344,10 +3352,8 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, sizeof(state->transforms[idx]), &state->transforms[idx]); /* wined3d_ffp_vs_settings.ortho_fog still needs the * device state to be set. */ - } - - if (!(idx >= WINED3D_TS_TEXTURE0 && idx <= WINED3D_TS_TEXTURE7)) wined3d_device_set_transform(device, idx, &state->transforms[idx]); + } } }
@@ -3522,6 +3528,26 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, offsetof(struct wined3d_ffp_vs_constants, light), sizeof(constants), &constants); }
+ if (changed->modelview_matrices) + { + struct wined3d_matrix matrices[MAX_VERTEX_BLENDS]; + + get_modelview_matrix(state, 0, &matrices[0]); + wined3d_device_context_push_constants(context, + WINED3D_PUSH_CONSTANTS_VS_FFP, WINED3D_SHADER_CONST_FFP_MODELVIEW, + offsetof(struct wined3d_ffp_vs_constants, modelview_matrices[0]), sizeof(matrices[0]), &matrices[0]); + + if (state->rs[WINED3D_RS_VERTEXBLEND]) + { + for (i = 1; i < MAX_VERTEX_BLENDS; ++i) + get_modelview_matrix(state, i, &matrices[i]); + wined3d_device_context_push_constants(context, + WINED3D_PUSH_CONSTANTS_VS_FFP, WINED3D_SHADER_CONST_FFP_VERTEXBLEND, + offsetof(struct wined3d_ffp_vs_constants, modelview_matrices[1]), + sizeof(matrices) - sizeof(matrices[0]), &matrices[1]); + } + } + if (changed->texture_matrices) { struct wined3d_ffp_vs_constants constants; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index c7f2f6dcd90..20e7fd05e2c 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -5589,7 +5589,7 @@ void get_identity_matrix(struct wined3d_matrix *mat) *mat = identity; }
-void get_modelview_matrix(const struct wined3d_state *state, unsigned int index, struct wined3d_matrix *mat) +void get_modelview_matrix(const struct wined3d_stateblock_state *state, unsigned int index, struct wined3d_matrix *mat) { multiply_matrix(mat, &state->transforms[WINED3D_TS_VIEW], &state->transforms[WINED3D_TS_WORLD_MATRIX(index)]); } diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 7979c144a6a..191894bf95a 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2768,6 +2768,7 @@ BOOL wined3d_get_app_name(char *app_name, unsigned int app_name_size);
struct wined3d_ffp_vs_constants { + struct wined3d_matrix modelview_matrices[MAX_VERTEX_BLENDS]; struct wined3d_matrix projection_matrix; struct wined3d_matrix texture_matrices[WINED3D_MAX_FFP_TEXTURES]; struct wined3d_material material; @@ -4375,7 +4376,7 @@ static inline BOOL shader_sampler_is_shadow(const struct wined3d_shader *shader, }
void get_identity_matrix(struct wined3d_matrix *mat); -void get_modelview_matrix(const struct wined3d_state *state, unsigned int index, struct wined3d_matrix *mat); +void get_modelview_matrix(const struct wined3d_stateblock_state *state, unsigned int index, struct wined3d_matrix *mat); void get_texture_matrix(const struct wined3d_stream_info *si, const struct wined3d_stateblock_state *state, const unsigned int tex, struct wined3d_matrix *mat); void get_pointsize_minmax(const struct wined3d_context *context, const struct wined3d_state *state,