[PATCH 0/5] MR6111: wined3d: Feed FFP shader constants through push constant buffers, part 4.
From: Elizabeth Figura <zfigura(a)codeweavers.com> --- dlls/wined3d/ffp_gl.c | 50 ++++++++++++++++++++----------------- dlls/wined3d/glsl_shader.c | 51 +++++++++++--------------------------- dlls/wined3d/wined3d_gl.h | 2 ++ 3 files changed, 43 insertions(+), 60 deletions(-) diff --git a/dlls/wined3d/ffp_gl.c b/dlls/wined3d/ffp_gl.c index d0d82181c1e..a50f7c7a4b0 100644 --- a/dlls/wined3d/ffp_gl.c +++ b/dlls/wined3d/ffp_gl.c @@ -1035,35 +1035,39 @@ static void shader_bumpenv(struct wined3d_context *context, const struct wined3d void clipplane(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info; - UINT index = state_id - STATE_CLIPPLANE(0); - GLdouble plane[4]; + context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; +} - if (index >= gl_info->limits.user_clip_distances) - return; +void ffp_vertex_update_clip_plane_constants(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state) +{ + for (unsigned int i = 0; i < gl_info->limits.user_clip_distances; ++i) + { + GLdouble plane[4]; - gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW); - gl_info->gl_ops.gl.p_glPushMatrix(); + gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW); + gl_info->gl_ops.gl.p_glPushMatrix(); - /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */ - if (!use_vs(state)) - gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW]._11); - else - /* With vertex shaders, clip planes are not transformed in Direct3D, - * while in OpenGL they are still transformed by the model view matrix. */ - gl_info->gl_ops.gl.p_glLoadIdentity(); + /* Clip plane settings are affected by the model view in OpenGL, + * and the view transform in Direct3D. + * + * With vertex shaders, Direct3D clip planes are not transformed, + * whereas in OpenGL they are still transformed by the model view + * matrix. */ + if (!use_vs(state)) + gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW]._11); + else + gl_info->gl_ops.gl.p_glLoadIdentity(); - plane[0] = state->clip_planes[index].x; - plane[1] = state->clip_planes[index].y; - plane[2] = state->clip_planes[index].z; - plane[3] = state->clip_planes[index].w; + plane[0] = state->clip_planes[i].x; + plane[1] = state->clip_planes[i].y; + plane[2] = state->clip_planes[i].z; + plane[3] = state->clip_planes[i].w; - TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n", - plane[0], plane[1], plane[2], plane[3]); - gl_info->gl_ops.gl.p_glClipPlane(GL_CLIP_PLANE0 + index, plane); - checkGLcall("glClipPlane"); + gl_info->gl_ops.gl.p_glClipPlane(GL_CLIP_PLANE0 + i, plane); + checkGLcall("glClipPlane"); - gl_info->gl_ops.gl.p_glPopMatrix(); + gl_info->gl_ops.gl.p_glPopMatrix(); + } } static void streamsrc(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 6eb83ec3f2c..295867c32b1 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1688,8 +1688,15 @@ static void shader_glsl_load_constants(struct shader_glsl_priv *priv, if (update_mask & WINED3D_SHADER_CONST_VS_CLIP_PLANES) { - for (i = 0; i < gl_info->limits.user_clip_distances; ++i) - shader_glsl_clip_plane_uniform(context_gl, state, i, prog); + if (gl_info->supported[WINED3D_GLSL_130]) + { + for (i = 0; i < gl_info->limits.user_clip_distances; ++i) + shader_glsl_clip_plane_uniform(context_gl, state, i, prog); + } + else + { + ffp_vertex_update_clip_plane_constants(gl_info, state); + } } if (update_mask & WINED3D_SHADER_CONST_VS_POINTSIZE) @@ -11720,14 +11727,12 @@ static void glsl_vertex_pipe_vdecl(struct wined3d_context *context, const struct wined3d_vertex_declaration *vdecl = state->vertex_declaration; struct wined3d_context_gl *context_gl = wined3d_context_gl(context); const struct wined3d_gl_info *gl_info = context_gl->gl_info; - const BOOL legacy_clip_planes = needs_legacy_glsl_syntax(gl_info); BOOL transformed = context->stream_info.position_transformed; BOOL wasrhw = context->last_was_rhw; bool point_size = vdecl && vdecl->point_size; bool specular = vdecl && vdecl->specular; bool diffuse = vdecl && vdecl->diffuse; bool normal = vdecl && vdecl->normal; - unsigned int i; context->last_was_rhw = transformed; @@ -11743,13 +11748,7 @@ static void glsl_vertex_pipe_vdecl(struct wined3d_context *context, if (!use_vs(state)) { if (context->last_was_vshader) - { - if (legacy_clip_planes) - for (i = 0; i < gl_info->limits.user_clip_distances; ++i) - clipplane(context, state, STATE_CLIPPLANE(i)); - else - context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; - } + context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_TEXMATRIX; @@ -11772,15 +11771,9 @@ static void glsl_vertex_pipe_vdecl(struct wined3d_context *context, } else { + /* Vertex shader clipping ignores the view matrix. Update all clip planes. */ if (!context->last_was_vshader) - { - /* Vertex shader clipping ignores the view matrix. Update all clip planes. */ - if (legacy_clip_planes) - for (i = 0; i < gl_info->limits.user_clip_distances; ++i) - clipplane(context, state, STATE_CLIPPLANE(i)); - else - context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; - } + context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; } context->last_was_vshader = use_vs(state); @@ -11855,25 +11848,9 @@ static void glsl_vertex_pipe_vertexblend(struct wined3d_context *context, static void glsl_vertex_pipe_view(struct wined3d_context *context, const struct wined3d_state *state, DWORD state_id) { - struct wined3d_context_gl *context_gl = wined3d_context_gl(context); - const struct wined3d_gl_info *gl_info = context_gl->gl_info; - unsigned int k; - context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_MODELVIEW - | WINED3D_SHADER_CONST_FFP_VERTEXBLEND; - - if (needs_legacy_glsl_syntax(gl_info)) - { - for (k = 0; k < gl_info->limits.user_clip_distances; ++k) - { - if (!isStateDirty(context, STATE_CLIPPLANE(k))) - clipplane(context, state, STATE_CLIPPLANE(k)); - } - } - else - { - context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; - } + | WINED3D_SHADER_CONST_FFP_VERTEXBLEND + | WINED3D_SHADER_CONST_VS_CLIP_PLANES; } static void glsl_vertex_pipe_projection(struct wined3d_context *context, diff --git a/dlls/wined3d/wined3d_gl.h b/dlls/wined3d/wined3d_gl.h index ac875ce1fe7..039f652adb9 100644 --- a/dlls/wined3d/wined3d_gl.h +++ b/dlls/wined3d/wined3d_gl.h @@ -773,6 +773,8 @@ void wined3d_ffp_blitter_create(struct wined3d_blitter **next, const struct wine struct wined3d_blitter *wined3d_glsl_blitter_create(struct wined3d_blitter **next, const struct wined3d_device *device); void wined3d_raw_blitter_create(struct wined3d_blitter **next, const struct wined3d_gl_info *gl_info); +void ffp_vertex_update_clip_plane_constants(const struct wined3d_gl_info *gl_info, const struct wined3d_state *state); + struct wined3d_caps_gl_ctx { HDC dc; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6111
From: Elizabeth Figura <zfigura(a)codeweavers.com> --- dlls/wined3d/ffp_gl.c | 12 +------- dlls/wined3d/glsl_shader.c | 38 ++----------------------- dlls/wined3d/stateblock.c | 57 +++++++++++++++++++++++++++++++++++++- 3 files changed, 59 insertions(+), 48 deletions(-) diff --git a/dlls/wined3d/ffp_gl.c b/dlls/wined3d/ffp_gl.c index a50f7c7a4b0..f1f995f6e4c 100644 --- a/dlls/wined3d/ffp_gl.c +++ b/dlls/wined3d/ffp_gl.c @@ -1046,17 +1046,7 @@ void ffp_vertex_update_clip_plane_constants(const struct wined3d_gl_info *gl_inf gl_info->gl_ops.gl.p_glMatrixMode(GL_MODELVIEW); gl_info->gl_ops.gl.p_glPushMatrix(); - - /* Clip plane settings are affected by the model view in OpenGL, - * and the view transform in Direct3D. - * - * With vertex shaders, Direct3D clip planes are not transformed, - * whereas in OpenGL they are still transformed by the model view - * matrix. */ - if (!use_vs(state)) - gl_info->gl_ops.gl.p_glLoadMatrixf(&state->transforms[WINED3D_TS_VIEW]._11); - else - gl_info->gl_ops.gl.p_glLoadIdentity(); + gl_info->gl_ops.gl.p_glLoadIdentity(); plane[0] = state->clip_planes[i].x; plane[1] = state->clip_planes[i].y; diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 295867c32b1..b4308906e4c 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1477,18 +1477,6 @@ static void reset_program_constant_version(struct wine_rb_entry *entry, void *co WINE_RB_ENTRY_VALUE(entry, struct glsl_shader_prog_link, program_lookup_entry)->constant_version = 0; } -static void transpose_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m) -{ - struct wined3d_matrix temp; - unsigned int i, j; - - for (i = 0; i < 4; ++i) - for (j = 0; j < 4; ++j) - (&temp._11)[4 * j + i] = (&m->_11)[4 * i + j]; - - *out = temp; -} - 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) { @@ -1636,20 +1624,8 @@ static void shader_glsl_clip_plane_uniform(const struct wined3d_context_gl *cont const struct wined3d_state *state, unsigned int index, struct glsl_shader_prog_link *prog) { const struct wined3d_gl_info *gl_info = context_gl->gl_info; - struct wined3d_matrix matrix; - struct wined3d_vec4 plane; - - plane = state->clip_planes[index]; - /* Clip planes are affected by the view transform in d3d for FFP draws. */ - if (!use_vs(state)) - { - invert_matrix(&matrix, &state->transforms[WINED3D_TS_VIEW]); - transpose_matrix(&matrix, &matrix); - wined3d_vec4_transform(&plane, &plane, &matrix); - } - - GL_EXTCALL(glUniform4fv(prog->vs.clip_planes_location + index, 1, &plane.x)); + GL_EXTCALL(glUniform4fv(prog->vs.clip_planes_location + index, 1, &state->clip_planes[index].x)); } static void shader_glsl_load_constants(struct shader_glsl_priv *priv, @@ -11747,9 +11723,6 @@ static void glsl_vertex_pipe_vdecl(struct wined3d_context *context, if (!use_vs(state)) { - if (context->last_was_vshader) - context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; - context->constant_update_mask |= WINED3D_SHADER_CONST_FFP_TEXMATRIX; /* Because of settings->texcoords, we have to regenerate the vertex @@ -11769,12 +11742,6 @@ static void glsl_vertex_pipe_vdecl(struct wined3d_context *context, && state->shader[WINED3D_SHADER_TYPE_PIXEL]->reg_maps.shader_version.minor <= 3) context->shader_update_mask |= 1u << WINED3D_SHADER_TYPE_PIXEL; } - else - { - /* Vertex shader clipping ignores the view matrix. Update all clip planes. */ - if (!context->last_was_vshader) - context->constant_update_mask |= WINED3D_SHADER_CONST_VS_CLIP_PLANES; - } context->last_was_vshader = use_vs(state); context->last_was_diffuse = diffuse; @@ -11849,8 +11816,7 @@ static void glsl_vertex_pipe_vertexblend(struct wined3d_context *context, 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 - | WINED3D_SHADER_CONST_VS_CLIP_PLANES; + | WINED3D_SHADER_CONST_FFP_VERTEXBLEND; } static void glsl_vertex_pipe_projection(struct wined3d_context *context, diff --git a/dlls/wined3d/stateblock.c b/dlls/wined3d/stateblock.c index 5d275be1ae1..ed11babb1ab 100644 --- a/dlls/wined3d/stateblock.c +++ b/dlls/wined3d/stateblock.c @@ -249,6 +249,19 @@ static const DWORD vertex_states_sampler[] = WINED3D_SAMP_DMAP_OFFSET, }; +static void transpose_matrix(struct wined3d_matrix *out, const struct wined3d_matrix *m) +{ + struct wined3d_matrix temp; + + for (unsigned int i = 0; i < 4; ++i) + { + for (unsigned int j = 0; j < 4; ++j) + (&temp._11)[4 * j + i] = (&m->_11)[4 * i + j]; + } + + *out = temp; +} + static inline void stateblock_set_all_bits(uint32_t *map, UINT map_size) { DWORD mask = (1u << (map_size & 0x1f)) - 1; @@ -2709,7 +2722,12 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, TRACE("device %p, stateblock %p.\n", device, stateblock); if (changed->vertexShader) + { wined3d_device_context_set_shader(context, WINED3D_SHADER_TYPE_VERTEX, state->vs); + /* Clip planes are affected by the view matrix, but only if not using + * vertex shaders. */ + changed->clipplane = wined3d_mask_from_size(WINED3D_MAX_CLIP_DISTANCES); + } if (changed->pixelShader) wined3d_device_context_set_shader(context, WINED3D_SHADER_TYPE_PIXEL, state->ps); @@ -3296,11 +3314,17 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, idx = i * word_bit_count + j; if (idx == WINED3D_TS_VIEW) + { changed->lights = 1; + changed->clipplane = wined3d_mask_from_size(WINED3D_MAX_CLIP_DISTANCES); + } wined3d_device_set_transform(device, idx, &state->transforms[idx]); } } + + /* Clip planes are affected by the view matrix. */ + changed->clipplane = wined3d_mask_from_size(WINED3D_MAX_CLIP_DISTANCES); } if (changed->indices) @@ -3345,7 +3369,38 @@ void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device, while (map) { i = wined3d_bit_scan(&map); - wined3d_device_set_clip_plane(device, i, &state->clip_planes[i]); + + /* In Direct3D, clipping is done based on the position as transformed + * by the world (model) matrix, but not the view matrix. + * + * GL and Vulkan do not distinguish the world and view, so we pass them + * as a single uniform. That means, however, that we need to unapply the + * view matrix from the clip planes that we are applying. We do this by + * multiplying by the transpose of the inverse of the view matrix. + * + * This works mathematically (c = clip plane, p = position): + * + * clip distance = dot((V⁻¹)ᵀc, VMp) + * = ((V⁻¹)ᵀc)ᵀVMp + * = cᵀV⁻¹VMp + * = cᵀMp + * = dot(c, Mp) + */ + + if (!state->vs) + { + struct wined3d_matrix matrix; + struct wined3d_vec4 plane; + + invert_matrix(&matrix, &state->transforms[WINED3D_TS_VIEW]); + transpose_matrix(&matrix, &matrix); + wined3d_vec4_transform(&plane, &state->clip_planes[i], &matrix); + wined3d_device_set_clip_plane(device, i, &plane); + } + else + { + wined3d_device_set_clip_plane(device, i, &state->clip_planes[i]); + } } if (changed->lights) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6111
From: Elizabeth Figura <zfigura(a)codeweavers.com> --- dlls/wined3d/glsl_shader.c | 2 +- dlls/wined3d/utils.c | 15 +++++++++------ dlls/wined3d/wined3d_private.h | 4 ++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index b4308906e4c..49d8870bb88 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -1505,7 +1505,7 @@ static void shader_glsl_ffp_vertex_texmatrix_uniform(const struct wined3d_contex if (prog->vs.texture_matrix_location[tex] == -1) return; - get_texture_matrix(&context_gl->c, state, tex, &mat); + get_texture_matrix(&context_gl->c.stream_info, state, tex, &mat); GL_EXTCALL(glUniformMatrix4fv(prog->vs.texture_matrix_location[tex], 1, FALSE, &mat._11)); checkGLcall("glUniformMatrix4fv"); } diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 71b629da50e..3ec6ef40508 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -5746,20 +5746,23 @@ static void compute_texture_matrix(const struct wined3d_matrix *matrix, uint32_t *out_matrix = mat; } -void get_texture_matrix(const struct wined3d_context *context, const struct wined3d_state *state, - const unsigned int tex, 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) { BOOL generated = (state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX] & 0xffff0000) != WINED3DTSS_TCI_PASSTHRU; unsigned int coord_idx = min(state->texture_states[tex][WINED3D_TSS_TEXCOORD_INDEX] & 0x0000ffff, WINED3D_MAX_FFP_TEXTURES - 1); + enum wined3d_format_id attribute_format; + + if (si->use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx))) + attribute_format = si->elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->id; + else + attribute_format = WINED3DFMT_UNKNOWN; compute_texture_matrix(&state->transforms[WINED3D_TS_TEXTURE0 + tex], state->texture_states[tex][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS], - generated, context->stream_info.position_transformed, - context->stream_info.use_map & (1u << (WINED3D_FFP_TEXCOORD0 + coord_idx)) - ? context->stream_info.elements[WINED3D_FFP_TEXCOORD0 + coord_idx].format->id - : WINED3DFMT_UNKNOWN, mat); + generated, si->position_transformed, attribute_format, mat); } void get_pointsize_minmax(const struct wined3d_context *context, const struct wined3d_state *state, diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index c8b437aa524..58dacd4f5d2 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4381,8 +4381,8 @@ void get_modelview_matrix(const struct wined3d_context *context, const struct wi unsigned int index, struct wined3d_matrix *mat); 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_context *context, const struct wined3d_state *state, - unsigned int tex, 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); 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, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6111
From: Elizabeth Figura <zfigura(a)codeweavers.com> --- dlls/wined3d/glsl_shader.c | 32 +++++++++++++++++++------------- dlls/wined3d/utils.c | 6 +++--- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 49d8870bb88..5fe9ea8fc0c 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -9189,46 +9189,52 @@ static GLuint shader_glsl_generate_ffp_vertex_shader(struct shader_glsl_priv *pr for (i = 0; i < WINED3D_MAX_FFP_TEXTURES; ++i) { - BOOL output_legacy_texcoord = legacy_syntax; + struct wined3d_string_buffer *texcoord = string_buffer_get(&priv->string_buffers); + bool output_texcoord = true; + + if (!settings->transformed) + shader_addline(texcoord, "ffp_texture_matrix[%u] * ", i); switch (settings->texgen[i] & 0xffff0000) { case WINED3DTSS_TCI_PASSTHRU: if (settings->texcoords & (1u << i)) - shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u] * ffp_attrib_texcoord%u;\n", - i, i, i); + shader_addline(texcoord, "ffp_attrib_texcoord%u", i); else if (shader_glsl_full_ffp_varyings(gl_info)) - shader_addline(buffer, "ffp_varying_texcoord[%u] = vec4(0.0);\n", i); + shader_addline(texcoord, "vec4(0.0)"); else - output_legacy_texcoord = FALSE; + output_texcoord = false; break; case WINED3DTSS_TCI_CAMERASPACENORMAL: - shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u] * vec4(normal, 1.0);\n", i, i); + shader_addline(texcoord, "vec4(normal, 1.0)"); break; case WINED3DTSS_TCI_CAMERASPACEPOSITION: - shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u] * ec_pos;\n", i, i); + shader_addline(texcoord, "ec_pos"); break; case WINED3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR: - shader_addline(buffer, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u]" - " * vec4(reflect(ffp_normalize(ec_pos.xyz), normal), 1.0);\n", i, i); + shader_addline(texcoord, "vec4(reflect(ffp_normalize(ec_pos.xyz), normal), 1.0)"); break; case WINED3DTSS_TCI_SPHEREMAP: shader_addline(buffer, "r = reflect(ffp_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, "ffp_varying_texcoord[%u] = ffp_texture_matrix[%u]" - " * vec4(r.x / m + 0.5, r.y / m + 0.5, 0.0, 1.0);\n", i, i); + shader_addline(texcoord, "vec4(r.x / m + 0.5, r.y / m + 0.5, 0.0, 1.0)"); break; default: ERR("Unhandled texgen %#x.\n", settings->texgen[i]); break; } - if (output_legacy_texcoord) - shader_addline(buffer, "gl_TexCoord[%u] = ffp_varying_texcoord[%u];\n", i, i); + if (output_texcoord) + { + shader_addline(buffer, "ffp_varying_texcoord[%u] = %s;\n", i, texcoord->buffer); + if (legacy_syntax) + shader_addline(buffer, "gl_TexCoord[%u] = ffp_varying_texcoord[%u];\n", i, i); + } + string_buffer_release(&priv->string_buffers, texcoord); } switch (settings->fog_mode) diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 3ec6ef40508..e31d3d39cfc 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -5687,11 +5687,11 @@ void get_projection_matrix(const struct wined3d_context *context, const struct w /* Setup this textures matrix according to the texture flags. */ static void compute_texture_matrix(const struct wined3d_matrix *matrix, uint32_t flags, BOOL calculated_coords, - BOOL transformed, enum wined3d_format_id format_id, struct wined3d_matrix *out_matrix) + enum wined3d_format_id format_id, struct wined3d_matrix *out_matrix) { struct wined3d_matrix mat; - if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1 || transformed) + if (flags == WINED3D_TTFF_DISABLE || flags == WINED3D_TTFF_COUNT1) { get_identity_matrix(out_matrix); return; @@ -5762,7 +5762,7 @@ void get_texture_matrix(const struct wined3d_stream_info *si, compute_texture_matrix(&state->transforms[WINED3D_TS_TEXTURE0 + tex], state->texture_states[tex][WINED3D_TSS_TEXTURE_TRANSFORM_FLAGS], - generated, si->position_transformed, attribute_format, mat); + generated, attribute_format, mat); } void get_pointsize_minmax(const struct wined3d_context *context, const struct wined3d_state *state, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6111
From: Elizabeth Figura <zfigura(a)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, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/6111
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=147181 Your paranoid android. === debian11 (build log) === error: patch failed: dlls/wined3d/glsl_shader.c:11855 error: patch failed: dlls/wined3d/ffp_gl.c:1046 error: patch failed: dlls/wined3d/glsl_shader.c:1477 error: patch failed: dlls/wined3d/stateblock.c:249 error: patch failed: dlls/wined3d/glsl_shader.c:11729 error: patch failed: dlls/wined3d/stateblock.c:3319 Task: Patch failed to apply === debian11b (build log) === error: patch failed: dlls/wined3d/glsl_shader.c:11855 error: patch failed: dlls/wined3d/ffp_gl.c:1046 error: patch failed: dlls/wined3d/glsl_shader.c:1477 error: patch failed: dlls/wined3d/stateblock.c:249 error: patch failed: dlls/wined3d/glsl_shader.c:11729 error: patch failed: dlls/wined3d/stateblock.c:3319 Task: Patch failed to apply
This merge request was approved by Jan Sikorski. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/6111
participants (4)
-
Elizabeth Figura -
Elizabeth Figura (@zfigura) -
Jan Sikorski (@jsikorski) -
Marvin