[PATCH 1/2] wined3d: Implement SM5 swapc instruction.

Józef Kucia jkucia at codeweavers.com
Wed Jul 12 17:35:46 CDT 2017


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 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 1bd3a667e8..650f8adcff 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,
-- 
2.13.0




More information about the wine-patches mailing list