From: Elizabeth Figura zfigura@codeweavers.com
--- dlls/wined3d/glsl_shader.c | 37 ++++++---------------------- dlls/wined3d/stateblock.c | 45 +++++++++++++++++++++++++++++++--- dlls/wined3d/utils.c | 2 +- dlls/wined3d/wined3d_private.h | 3 ++- 4 files changed, 53 insertions(+), 34 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 5fe9ea8fc0c..3fe7640106f 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1495,18 +1495,17 @@ static void shader_glsl_ffp_vertex_normalmatrix_uniform(const struct wined3d_con }
static void shader_glsl_ffp_vertex_texmatrix_uniform(const struct wined3d_context_gl *context_gl, - const struct wined3d_state *state, unsigned int tex, struct glsl_shader_prog_link *prog) + const struct wined3d_ffp_vs_constants *constants, unsigned int tex, struct glsl_shader_prog_link *prog) { const struct wined3d_gl_info *gl_info = context_gl->gl_info; - struct wined3d_matrix mat;
if (tex >= WINED3D_MAX_FFP_TEXTURES) return; if (prog->vs.texture_matrix_location[tex] == -1) return;
- get_texture_matrix(&context_gl->c.stream_info, state, tex, &mat); - GL_EXTCALL(glUniformMatrix4fv(prog->vs.texture_matrix_location[tex], 1, FALSE, &mat._11)); + GL_EXTCALL(glUniformMatrix4fv(prog->vs.texture_matrix_location[tex], + 1, FALSE, &constants->texture_matrices[tex]._11)); checkGLcall("glUniformMatrix4fv"); }
@@ -1735,8 +1734,12 @@ static void shader_glsl_load_constants(struct shader_glsl_priv *priv,
if (update_mask & WINED3D_SHADER_CONST_FFP_TEXMATRIX) { + const struct wined3d_ffp_vs_constants *constants; + + constants = wined3d_buffer_load_sysmem(context->device->push_constants[WINED3D_PUSH_CONSTANTS_VS_FFP], context); + for (i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i) - shader_glsl_ffp_vertex_texmatrix_uniform(context_gl, state, i, prog); + shader_glsl_ffp_vertex_texmatrix_uniform(context_gl, constants, i, prog); }
if (update_mask & WINED3D_SHADER_CONST_FFP_MATERIAL) @@ -11729,8 +11732,6 @@ static void glsl_vertex_pipe_vdecl(struct wined3d_context *context,
if (!use_vs(state)) { - context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_TEXMATRIX; - /* Because of settings->texcoords, we have to regenerate the vertex * shader on a vdecl change if there aren't enough varyings to just * always output all the texture coordinates. @@ -11846,12 +11847,6 @@ static void glsl_vertex_pipe_viewport(struct wined3d_context *context, context->constant_update_mask |= WINED3D_SHADER_CONST_POS_FIXUP; }
-static void glsl_vertex_pipe_texmatrix(struct wined3d_context *context, - const struct wined3d_state *state, DWORD state_id) -{ - context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_TEXMATRIX; -} - static void glsl_vertex_pipe_material(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { @@ -11932,26 +11927,10 @@ static const struct wined3d_state_entry_template glsl_vertex_pipe_vp_states[] = /* 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_TEXTURE0), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_TEXTURE1), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_TEXTURE2), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_TEXTURE3), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_TEXTURE4), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_TEXTURE5), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_TEXTURE6), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, WINED3D_GL_EXT_NONE }, - {STATE_TRANSFORM(WINED3D_TS_TEXTURE7), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), NULL }, 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_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), glsl_vertex_pipe_texmatrix}, 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 ed11babb1ab..4453b989205 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -61,6 +61,7 @@ struct wined3d_saved_states /* Flags only consumed by wined3d_device_apply_stateblock(), concerned with * translation from stateblock formats to wined3d_state formats. */ uint32_t ffp_ps_constants : 1; + uint32_t texture_matrices : 1; };
struct stage_state @@ -1544,6 +1545,10 @@ void CDECL wined3d_stateblock_set_vertex_declaration(struct wined3d_stateblock * wined3d_vertex_declaration_decref(stateblock->stateblock_state.vertex_declaration); stateblock->stateblock_state.vertex_declaration = declaration; stateblock->changed.vertexDecl = TRUE; + /* Texture matrices depend on the format of the TEXCOORD attributes. */ + /* FIXME: They also depend on whether the draw is pretransformed, + * but that should go away. */ + stateblock->changed.texture_matrices = TRUE; }
void CDECL wined3d_stateblock_set_render_state(struct wined3d_stateblock *stateblock, @@ -1618,8 +1623,20 @@ void CDECL wined3d_stateblock_set_texture_stage_state(struct wined3d_stateblock stateblock->stateblock_state.texture_states[stage][state] = value; stateblock->changed.textureState[stage] |= 1u << state;
- if (state == WINED3D_TSS_CONSTANT) - stateblock->changed.ffp_ps_constants = 1; + switch (state) + { + case WINED3D_TSS_CONSTANT: + stateblock->changed.ffp_ps_constants = 1; + break; + + case WINED3D_TSS_TEXCOORD_INDEX: + case WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS: + stateblock->changed.texture_matrices = 1; + break; + + default: + break; + } }
void CDECL wined3d_stateblock_set_texture(struct wined3d_stateblock *stateblock, @@ -1653,6 +1670,9 @@ void CDECL wined3d_stateblock_set_transform(struct wined3d_stateblock *statebloc stateblock->stateblock_state.transforms[d3dts] = *matrix; stateblock->changed.transform[d3dts >> 5] |= 1u << (d3dts & 0x1f); stateblock->changed.transforms = 1; + + if (d3dts >= WINED3D_TS_TEXTURE0 && d3dts <= WINED3D_TS_TEXTURE7) + stateblock->changed.texture_matrices = 1; }
void CDECL wined3d_stateblock_multiply_transform(struct wined3d_stateblock *stateblock, @@ -2229,6 +2249,7 @@ static void wined3d_stateblock_invalidate_push_constants(struct wined3d_stateblo { stateblock->changed.ffp_ps_constants = 1; stateblock->changed.lights = 1; + stateblock->changed.texture_matrices = 1; }
static HRESULT stateblock_init(struct wined3d_stateblock *stateblock, const struct wined3d_stateblock *device_state, @@ -3319,7 +3340,8 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, changed->clipplane = wined3d_mask_from_size(WINED3D_MAX_CLIP_DISTANCES); }
- wined3d_device_set_transform(device, idx, &state->transforms[idx]); + if (!(idx >= WINED3D_TS_TEXTURE0 && idx <= WINED3D_TS_TEXTURE7)) + wined3d_device_set_transform(device, idx, &state->transforms[idx]); } }
@@ -3492,6 +3514,23 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, offsetof(struct wined3d_ffp_vs_constants, light), sizeof(constants), &constants); }
+ if (changed->texture_matrices) + { + struct wined3d_ffp_vs_constants constants; + struct wined3d_stream_info si; + + /* FIXME: This is a bit fragile. Ideally we should be calculating + * stream info from the stateblock state. */ + wined3d_stream_info_from_declaration(&si, context->state, &device->adapter->d3d_info); + + for (i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i) + get_texture_matrix(&si, state, i, &constants.texture_matrices[i]); + wined3d_device_context_push_constants(context, + WINED3D_PUSH_CONSTANTS_VS_FFP, WINED3D_SHADER_CONST_FFP_TEXMATRIX, + offsetof(struct wined3d_ffp_vs_constants, texture_matrices), + sizeof(constants.texture_matrices), constants.texture_matrices); + } + if (changed->ffp_ps_constants) { static const struct wined3d_color specular_enabled = {1.0f, 1.0f, 1.0f, 0.0f}; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index e31d3d39cfc..8e4f68e94ce 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -5747,7 +5747,7 @@ static void compute_texture_matrix(const struct wined3d_matrix *matrix, uint32_t }
void get_texture_matrix(const struct wined3d_stream_info *si, - const struct wined3d_state *state, const unsigned int tex, struct wined3d_matrix *mat) + const struct wined3d_stateblock_state *state, const unsigned int tex, struct wined3d_matrix *mat) { BOOL generated = (state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 58dacd4f5d2..4ac730a0290 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -2771,6 +2771,7 @@ BOOL wined3d_get_app_name(char *app_name, unsigned int app_name_size);
struct wined3d_ffp_vs_constants { + struct wined3d_matrix texture_matrices[WINED3D_MAX_FFP_TEXTURES]; struct wined3d_ffp_light_constants { struct wined3d_color ambient; @@ -4382,7 +4383,7 @@ void get_modelview_matrix(const struct wined3d_context *context, const struct wi void get_projection_matrix(const struct wined3d_context *context, const struct wined3d_state *state, struct wined3d_matrix *mat); void get_texture_matrix(const struct wined3d_stream_info *si, - const struct wined3d_state *state, const unsigned int tex, struct wined3d_matrix *mat); + 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, float *out_min, float *out_max); void get_pointsize(const struct wined3d_context *context, const struct wined3d_state *state,