Relative addressing doesn't necessarily work for SM3.
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- dlls/d3d11/tests/d3d11.c | 1 - dlls/wined3d/glsl_shader.c | 24 +++++++++++++++++++++--- dlls/wined3d/shader.c | 4 ++++ dlls/wined3d/wined3d_private.h | 3 ++- 4 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/dlls/d3d11/tests/d3d11.c b/dlls/d3d11/tests/d3d11.c index 96b3b05adae1..7d317dc1817c 100644 --- a/dlls/d3d11/tests/d3d11.c +++ b/dlls/d3d11/tests/d3d11.c @@ -12339,7 +12339,6 @@ static void test_vs_input_relative_addressing(void) ID3D11DeviceContext_UpdateSubresource(context, (ID3D11Resource *)cb, 0, NULL, index, 0, 0); ID3D11DeviceContext_ClearRenderTargetView(context, test_context.backbuffer_rtv, white); draw_quad(&test_context); - todo_wine_if(i > 0) check_texture_color(test_context.backbuffer, colors[i], 1); }
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 18822c50dfc8..32a75bf56288 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -2854,10 +2854,18 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register * struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
if (reg->idx[0].rel_addr) - FIXME("VS3+ input registers relative addressing.\n"); + FIXME("VS3 input registers relative addressing.\n"); if (priv->cur_vs_args->swizzle_map & (1u << reg->idx[0].offset)) *is_color = TRUE; - sprintf(register_name, "%s_in%u", prefix, reg->idx[0].offset); + if (reg->idx[0].rel_addr) + { + sprintf(register_name, "%s_in[%s + %u]", + prefix, rel_param0.param_str, reg->idx[0].offset); + } + else + { + sprintf(register_name, "%s_in%u", prefix, reg->idx[0].offset); + } break; }
@@ -7850,7 +7858,17 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context
shader_addline(buffer, "void main()\n{\n");
- /* Base Shader Body */ + if (reg_maps->input_rel_addressing) + { + unsigned int highest_input_register = wined3d_log2i(reg_maps->input_registers); + shader_addline(buffer, "vec4 vs_in[%u];\n", highest_input_register + 1); + for (i = 0; i < shader->input_signature.element_count; ++i) + { + const struct wined3d_shader_signature_element *e = &shader->input_signature.elements[i]; + shader_addline(buffer, "vs_in[%u] = vs_in%u;\n", e->register_idx, e->register_idx); + } + } + if (FAILED(shader_generate_code(shader, buffer, reg_maps, &priv_ctx, NULL, NULL))) return 0;
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c index d9765731abb1..04ced904481c 100644 --- a/dlls/wined3d/shader.c +++ b/dlls/wined3d/shader.c @@ -709,6 +709,8 @@ static BOOL shader_record_register_usage(struct wined3d_shader *shader, struct w break;
case WINED3DSPR_INPUT: + if (reg->idx[0].rel_addr) + reg_maps->input_rel_addressing = 1; if (shader_type == WINED3D_SHADER_TYPE_PIXEL) { /* If relative addressing is used, we must assume that all @@ -721,7 +723,9 @@ static BOOL shader_record_register_usage(struct wined3d_shader *shader, struct w shader->u.ps.input_reg_used |= 1u << reg->idx[0].offset; } else + { reg_maps->input_registers |= 1u << reg->idx[0].offset; + } break;
case WINED3DSPR_RASTOUT: diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index a79a68f1d0c2..3c6a347468ca 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1024,7 +1024,8 @@ struct wined3d_shader_reg_maps DWORD usespow : 1; DWORD point_size : 1; DWORD vocp : 1; - DWORD padding : 17; + DWORD input_rel_addressing : 1; + DWORD padding : 16;
DWORD rt_mask; /* Used render targets, 32 max. */