Module: wine Branch: master Commit: af80b7afdd51c89fd7423a687dd7213f32a1f87b URL: http://source.winehq.org/git/wine.git/?a=commit;h=af80b7afdd51c89fd7423a687d...
Author: Józef Kucia jkucia@codeweavers.com Date: Thu Jul 13 00:35:46 2017 +0200
wined3d: Implement SM5 swapc instruction.
Signed-off-by: Józef Kucia jkucia@codeweavers.com Signed-off-by: Henri Verbeet hverbeet@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/wined3d/glsl_shader.c | 54 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index 1bd3a66..650f8ad 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -4353,6 +4353,58 @@ static void shader_glsl_compare(const struct wined3d_shader_instruction *ins) } }
+static void shader_glsl_swapc(const struct wined3d_shader_instruction *ins) +{ + struct wined3d_string_buffer *buffer = ins->ctx->buffer; + struct wined3d_shader_dst_param dst[2]; + struct glsl_src_param src[3]; + unsigned int i, j, k; + char mask_char[6]; + DWORD write_mask; + BOOL tmp_dst[2]; + + for (i = 0; i < ins->dst_count; ++i) + { + tmp_dst[i] = FALSE; + for (j = 0; j < ins->src_count; ++j) + { + if (ins->dst[i].reg.idx[0].offset == ins->src[j].reg.idx[0].offset + && ins->dst[i].reg.type == ins->src[j].reg.type) + tmp_dst[i] = TRUE; + } + } + + dst[0] = ins->dst[0]; + dst[1] = ins->dst[1]; + for (i = 0; i < 4; ++i) + { + for (j = 0; j < ARRAY_SIZE(dst); ++j) + { + dst[j].write_mask = ins->dst[j].write_mask & (WINED3DSP_WRITEMASK_0 << i); + if (tmp_dst[j] && (write_mask = shader_glsl_get_write_mask(&dst[j], mask_char))) + shader_addline(buffer, "tmp%u%s = (", j, mask_char); + else if (!(write_mask = shader_glsl_append_dst_ext(buffer, ins, &dst[j], dst[j].reg.data_type))) + continue; + + for (k = 0; k < ARRAY_SIZE(src); ++k) + shader_glsl_add_src_param(ins, &ins->src[k], write_mask, &src[k]); + + shader_addline(buffer, "%sbool(%s) ? %s : %s);\n", !j ? "!" : "", + src[0].param_str, src[1].param_str, src[2].param_str); + } + } + + for (i = 0; i < ARRAY_SIZE(tmp_dst); ++i) + { + if (tmp_dst[i]) + { + shader_glsl_get_write_mask(&ins->dst[i], mask_char); + shader_glsl_append_dst_ext(buffer, ins, &ins->dst[i], ins->dst[i].reg.data_type); + shader_addline(ins->ctx->buffer, "tmp%u%s);\n", i, mask_char); + } + } +} + static void shader_glsl_conditional_move(const struct wined3d_shader_instruction *ins) { const char *condition_prefix, *condition_suffix; @@ -10805,7 +10857,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB /* WINED3DSIH_STORE_STRUCTURED */ shader_glsl_store_raw_structured, /* WINED3DSIH_STORE_UAV_TYPED */ shader_glsl_store_uav, /* WINED3DSIH_SUB */ shader_glsl_binop, - /* WINED3DSIH_SWAPC */ NULL, + /* WINED3DSIH_SWAPC */ shader_glsl_swapc, /* WINED3DSIH_SWITCH */ shader_glsl_switch, /* WINED3DSIH_SYNC */ shader_glsl_sync, /* WINED3DSIH_TEX */ shader_glsl_tex,