From: Matteo Bruni Subject: [PATCH 6/6] wined3d: Don't use the builtin FFP uniforms for texture transformation matrices. (v2) Message-Id: <1427397142-13403-6-git-send-email-mbruni@codeweavers.com> Date: Thu, 26 Mar 2015 20:12:22 +0100 v2: Avoid the cast, don't use sprintf. --- dlls/wined3d/glsl_shader.c | 101 ++++++++++++++++++++++++++++------------- dlls/wined3d/state.c | 4 +- dlls/wined3d/wined3d_private.h | 7 +-- 3 files changed, 74 insertions(+), 38 deletions(-) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index e0577eb..dedf9ae 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -120,6 +120,7 @@ struct glsl_vs_program GLint modelview_matrix_location; GLint projection_matrix_location; GLint normal_matrix_location; + GLint texture_matrix_location[MAX_TEXTURES]; }; struct glsl_gs_program @@ -824,6 +825,22 @@ static void shader_glsl_ffp_vertex_normalmatrix_uniform(const struct wined3d_con checkGLcall("glUniformMatrix3fv"); } +static void shader_glsl_ffp_vertex_texmatrix_uniform(const struct wined3d_context *context, + const struct wined3d_state *state, unsigned int tex, struct glsl_shader_prog_link *prog) +{ + const struct wined3d_gl_info *gl_info = context->gl_info; + struct wined3d_matrix mat; + + if (tex >= MAX_TEXTURES) + return; + if (prog->vs.texture_matrix_location[tex] == -1) + return; + + get_texture_matrix(context, state, tex, &mat); + GL_EXTCALL(glUniformMatrix4fv(prog->vs.texture_matrix_location[tex], 1, FALSE, &mat._11)); + checkGLcall("glUniformMatrix4fv"); +} + /* Context activation is done by the caller (state handler). */ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context *context, const struct wined3d_state *state) @@ -886,6 +903,12 @@ static void shader_glsl_load_constants(void *shader_priv, struct wined3d_context checkGLcall("glUniformMatrix4fv"); } + if (update_mask & WINED3D_SHADER_CONST_FFP_TEXMATRIX) + { + for (i = 0; i < MAX_TEXTURES; ++i) + shader_glsl_ffp_vertex_texmatrix_uniform(context, state, i, prog); + } + if (update_mask & WINED3D_SHADER_CONST_PS_F) shader_glsl_load_constantsF(pshader, gl_info, state->ps_consts_f, prog->ps.uniform_f_locations, &priv->pconst_heap, priv->stack, constant_version); @@ -5104,6 +5127,7 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_buffe shader_addline(buffer, "uniform mat4 ffp_modelview_matrix;\n"); shader_addline(buffer, "uniform mat4 ffp_projection_matrix;\n"); shader_addline(buffer, "uniform mat3 ffp_normal_matrix;\n"); + shader_addline(buffer, "uniform mat4 ffp_texture_matrix[%u];\n", MAX_TEXTURES); shader_addline(buffer, "\nvoid main()\n{\n"); shader_addline(buffer, "float m;\n"); @@ -5139,27 +5163,27 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct wined3d_shader_buffe { case WINED3DTSS_TCI_PASSTHRU: if (settings->texcoords & (1 << i)) - shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u] * gl_MultiTexCoord%d;\n", + shader_addline(buffer, "gl_TexCoord[%u] = ffp_texture_matrix[%u] * gl_MultiTexCoord%d;\n", i, i, i); break; case WINED3DTSS_TCI_CAMERASPACENORMAL: - shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u] * vec4(normal, 1.0);\n", i, i); + shader_addline(buffer, "gl_TexCoord[%u] = ffp_texture_matrix[%u] * vec4(normal, 1.0);\n", i, i); break; case WINED3DTSS_TCI_CAMERASPACEPOSITION: - shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u] * ec_pos;\n", i, i); + shader_addline(buffer, "gl_TexCoord[%u] = ffp_texture_matrix[%u] * ec_pos;\n", i, i); break; case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR: - shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u]" + shader_addline(buffer, "gl_TexCoord[%u] = ffp_texture_matrix[%u]" " * vec4(reflect(normalize(ec_pos.xyz), normal), 1.0);\n", i, i); break; case WINED3DTSS_TCI_SPHEREMAP: shader_addline(buffer, "r = reflect(normalize(ec_pos.xyz), normal);\n"); shader_addline(buffer, "m = 2.0 * length(vec3(r.x, r.y, r.z + 1.0));\n"); - shader_addline(buffer, "gl_TexCoord[%u] = gl_TextureMatrix[%u]" + shader_addline(buffer, "gl_TexCoord[%u] = ffp_texture_matrix[%u]" " * vec4(r.x / m + 0.5, r.y / m + 0.5, 0.0, 1.0);\n", i, i); break; @@ -5888,6 +5912,11 @@ static void shader_glsl_init_vs_uniform_locations(const struct wined3d_gl_info * vs->modelview_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_modelview_matrix")); vs->projection_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_projection_matrix")); vs->normal_matrix_location = GL_EXTCALL(glGetUniformLocation(program_id, "ffp_normal_matrix")); + for (i = 0; i < MAX_TEXTURES; ++i) + { + shader_snprintf(name, sizeof(name), "ffp_texture_matrix[%u]", i); + vs->texture_matrix_location[i] = GL_EXTCALL(glGetUniformLocation(program_id, name)); + } } static void shader_glsl_init_ps_uniform_locations(const struct wined3d_gl_info *gl_info, @@ -6192,6 +6221,15 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const { entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW | WINED3D_SHADER_CONST_FFP_PROJ; + + for (i = 0; i < MAX_TEXTURES; ++i) + { + if (entry->vs.texture_matrix_location[i] != -1) + { + entry->constant_update_mask |= WINED3D_SHADER_CONST_FFP_TEXMATRIX; + break; + } + } } if (gshader) @@ -7110,11 +7148,7 @@ static void glsl_vertex_pipe_vdecl(struct wined3d_context *context, if (transformed != wasrhw) context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_PROJ; - for (i = 0; i < MAX_TEXTURES; ++i) - { - if (!isStateDirty(context, STATE_TRANSFORM(WINED3D_TS_TEXTURE0 + i))) - transform_texture(context, state, STATE_TEXTURESTAGE(i, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS)); - } + context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_TEXMATRIX; if (!isStateDirty(context, STATE_RENDER(WINED3D_RS_LIGHTING))) state_lighting(context, state, STATE_RENDER(WINED3D_RS_LIGHTING)); @@ -7214,6 +7248,12 @@ static void glsl_vertex_pipe_viewport(struct wined3d_context *context, context->constant_update_mask |= WINED3D_SHADER_CONST_VS_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 const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = { {STATE_VDECL, {STATE_VDECL, glsl_vertex_pipe_vdecl }, WINED3D_GL_EXT_NONE }, @@ -7277,14 +7317,14 @@ static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = {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_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(0, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(1, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(2, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(3, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(4, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(5, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(6, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, WINED3D_GL_EXT_NONE }, - {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), {STATE_TEXTURESTAGE(7, WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS), transform_texture }, 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 }, @@ -7325,35 +7365,34 @@ static const struct StateEntryTemplate glsl_vertex_pipe_vp_states[] = {STATE_RENDER(WINED3D_RS_POINTSIZE_MAX), {STATE_RENDER(WINED3D_RS_POINTSIZE_MIN), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_TWEENFACTOR), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), NULL }, WINED3D_GL_EXT_NONE }, {STATE_RENDER(WINED3D_RS_INDEXEDVERTEXBLENDENABLE), {STATE_SHADER(WINED3D_SHADER_TYPE_VERTEX), NULL }, WINED3D_GL_EXT_NONE }, - /* Samplers for NP2 texture matrix adjustions. They are not needed if - * GL_ARB_texture_non_power_of_two is supported, so register a NULL state - * handler in that case to get the vertex part of sampler() skipped (VTF - * is handled in the misc states). Otherwise, register - * sampler_texmatrix(), which takes care of updating the texture matrix. */ + /* NP2 texture matrix fixups. They are not needed if + * GL_ARB_texture_non_power_of_two is supported. Otherwise, register + * glsl_vertex_pipe_texmatrix(), which takes care of updating the texture + * matrix. */ {STATE_SAMPLER(0), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO }, {STATE_SAMPLER(0), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT}, - {STATE_SAMPLER(0), {STATE_SAMPLER(0), sampler_texmatrix }, WINED3D_GL_EXT_NONE }, + {STATE_SAMPLER(0), {STATE_SAMPLER(0), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, {STATE_SAMPLER(1), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO }, {STATE_SAMPLER(1), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT}, - {STATE_SAMPLER(1), {STATE_SAMPLER(1), sampler_texmatrix }, WINED3D_GL_EXT_NONE }, + {STATE_SAMPLER(1), {STATE_SAMPLER(1), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, {STATE_SAMPLER(2), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO }, {STATE_SAMPLER(2), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT}, - {STATE_SAMPLER(2), {STATE_SAMPLER(2), sampler_texmatrix }, WINED3D_GL_EXT_NONE }, + {STATE_SAMPLER(2), {STATE_SAMPLER(2), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, {STATE_SAMPLER(3), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO }, {STATE_SAMPLER(3), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT}, - {STATE_SAMPLER(3), {STATE_SAMPLER(3), sampler_texmatrix }, WINED3D_GL_EXT_NONE }, + {STATE_SAMPLER(3), {STATE_SAMPLER(3), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, {STATE_SAMPLER(4), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO }, {STATE_SAMPLER(4), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT}, - {STATE_SAMPLER(4), {STATE_SAMPLER(4), sampler_texmatrix }, WINED3D_GL_EXT_NONE }, + {STATE_SAMPLER(4), {STATE_SAMPLER(4), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, {STATE_SAMPLER(5), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO }, {STATE_SAMPLER(5), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT}, - {STATE_SAMPLER(5), {STATE_SAMPLER(5), sampler_texmatrix }, WINED3D_GL_EXT_NONE }, + {STATE_SAMPLER(5), {STATE_SAMPLER(5), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, {STATE_SAMPLER(6), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO }, {STATE_SAMPLER(6), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT}, - {STATE_SAMPLER(6), {STATE_SAMPLER(6), sampler_texmatrix }, WINED3D_GL_EXT_NONE }, + {STATE_SAMPLER(6), {STATE_SAMPLER(6), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, {STATE_SAMPLER(7), {0, NULL }, ARB_TEXTURE_NON_POWER_OF_TWO }, {STATE_SAMPLER(7), {0, NULL }, WINED3D_GL_NORMALIZED_TEXRECT}, - {STATE_SAMPLER(7), {STATE_SAMPLER(7), sampler_texmatrix }, WINED3D_GL_EXT_NONE }, + {STATE_SAMPLER(7), {STATE_SAMPLER(7), glsl_vertex_pipe_texmatrix}, WINED3D_GL_EXT_NONE }, {STATE_POINT_SIZE_ENABLE, {STATE_RENDER(WINED3D_RS_FOGENABLE), NULL }, WINED3D_GL_EXT_NONE }, {0 /* Terminate */, {0, NULL }, WINED3D_GL_EXT_NONE }, }; diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 69623af..266e15a 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3276,7 +3276,7 @@ void tex_alphaop(struct wined3d_context *context, const struct wined3d_state *st } } -void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void transform_texture(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const struct wined3d_gl_info *gl_info = context->gl_info; unsigned int tex = (state_id - STATE_TEXTURESTAGE(0, 0)) / (WINED3D_HIGHEST_TEXTURE_STATE + 1); @@ -3548,7 +3548,7 @@ static void tex_coordindex(struct wined3d_context *context, const struct wined3d } } -void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) +static void sampler_texmatrix(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { const DWORD sampler = state_id - STATE_SAMPLER(0); const struct wined3d_texture *texture = state->textures[sampler]; diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index a08fd29..0020778 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -308,7 +308,8 @@ enum wined3d_shader_resource_type #define WINED3D_SHADER_CONST_PS_NP2_FIXUP 0x00000200 #define WINED3D_SHADER_CONST_FFP_MODELVIEW 0x00000400 #define WINED3D_SHADER_CONST_FFP_PROJ 0x00000800 -#define WINED3D_SHADER_CONST_FFP_PS 0x00001000 +#define WINED3D_SHADER_CONST_FFP_TEXMATRIX 0x00001000 +#define WINED3D_SHADER_CONST_FFP_PS 0x00002000 enum wined3d_shader_register_type { @@ -2809,12 +2810,8 @@ void state_fog_fragpart(struct wined3d_context *context, void state_srgbwrite(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; -void sampler_texmatrix(struct wined3d_context *context, - const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; void state_specularenable(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; -void transform_texture(struct wined3d_context *context, - const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; void state_ambient(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) DECLSPEC_HIDDEN; void state_clipping(struct wined3d_context *context, -- 2.0.5