[PATCH 4/5] wined3d: Merge most of the code for shader_glsl_cmp() and shader_glsl_cnd().

Henri Verbeet hverbeet at codeweavers.com
Thu Oct 18 15:12:52 CDT 2012


---
 dlls/wined3d/glsl_shader.c |  159 +++++++++++++++++++++-----------------------
 1 files changed, 77 insertions(+), 82 deletions(-)

diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 993b547..9ce89b3 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -2758,79 +2758,100 @@ static void shader_glsl_compare(const struct wined3d_shader_instruction *ins)
     }
 }
 
-/** Process CMP instruction in GLSL (dst = src0 >= 0.0 ? src1 : src2), per channel */
-static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins)
+static void shader_glsl_conditional_move(const struct wined3d_shader_instruction *ins)
 {
+    struct wined3d_shader_dst_param dst;
     struct glsl_src_param src0_param;
     struct glsl_src_param src1_param;
     struct glsl_src_param src2_param;
-    DWORD write_mask, cmp_channel = 0;
+    BOOL temp_destination = FALSE;
+    const char *condition_suffix;
+    DWORD cmp_channel = 0;
     unsigned int i, j;
     char mask_char[6];
-    BOOL temp_destination = FALSE;
+    DWORD write_mask;
+
+    switch (ins->handler_idx)
+    {
+        case WINED3DSIH_CMP:
+            condition_suffix = " >= 0.0";
+            break;
+
+        case WINED3DSIH_CND:
+            condition_suffix = " > 0.5";
+            break;
+
+        default:
+            FIXME("Unhandled instruction %#x.\n", ins->handler_idx);
+            condition_suffix = "<unhandled suffix>";
+            break;
+    }
 
     if (shader_is_scalar(&ins->src[0].reg))
     {
         write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
-
-        shader_glsl_add_src_param(ins, &ins->src[0], WINED3DSP_WRITEMASK_ALL, &src0_param);
+        shader_glsl_add_src_param(ins, &ins->src[0], write_mask, &src0_param);
         shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
         shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
 
-        shader_addline(ins->ctx->buffer, "%s >= 0.0 ? %s : %s);\n",
-                       src0_param.param_str, src1_param.param_str, src2_param.param_str);
-    } else {
-        DWORD dst_mask = ins->dst[0].write_mask;
-        struct wined3d_shader_dst_param dst = ins->dst[0];
-
-        /* Cycle through all source0 channels */
-        for (i=0; i<4; i++) {
-            write_mask = 0;
-            /* Find the destination channels which use the current source0 channel */
-            for (j=0; j<4; j++) {
-                if (((ins->src[0].swizzle >> (2 * j)) & 0x3) == i)
-                {
-                    write_mask |= WINED3DSP_WRITEMASK_0 << j;
-                    cmp_channel = WINED3DSP_WRITEMASK_0 << j;
-                }
-            }
-            dst.write_mask = dst_mask & write_mask;
-
-            /* Splitting the cmp instruction up in multiple lines imposes a problem:
-            * The first lines may overwrite source parameters of the following lines.
-            * Deal with that by using a temporary destination register if needed
-            */
-            if ((ins->src[0].reg.idx[0].offset == ins->dst[0].reg.idx[0].offset
-                    && ins->src[0].reg.type == ins->dst[0].reg.type)
-                    || (ins->src[1].reg.idx[0].offset == ins->dst[0].reg.idx[0].offset
-                    && ins->src[1].reg.type == ins->dst[0].reg.type)
-                    || (ins->src[2].reg.idx[0].offset == ins->dst[0].reg.idx[0].offset
-                    && ins->src[2].reg.type == ins->dst[0].reg.type))
-            {
-                write_mask = shader_glsl_get_write_mask(&dst, mask_char);
-                if (!write_mask) continue;
-                shader_addline(ins->ctx->buffer, "tmp0%s = (", mask_char);
-                temp_destination = TRUE;
-            } else {
-                write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &dst);
-                if (!write_mask) continue;
-            }
+        shader_addline(ins->ctx->buffer, "%s%s ? %s : %s);\n",
+                src0_param.param_str, condition_suffix,
+                src1_param.param_str, src2_param.param_str);
+        return;
+    }
 
-            shader_glsl_add_src_param(ins, &ins->src[0], cmp_channel, &src0_param);
-            shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
-            shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
+    dst = ins->dst[0];
 
-            shader_addline(ins->ctx->buffer, "%s >= 0.0 ? %s : %s);\n",
-                        src0_param.param_str, src1_param.param_str, src2_param.param_str);
+    /* Splitting the instruction up in multiple lines imposes a problem:
+     * The first lines may overwrite source parameters of the following lines.
+     * Deal with that by using a temporary destination register if needed. */
+    if ((ins->src[0].reg.idx[0].offset == dst.reg.idx[0].offset
+                && ins->src[0].reg.type == dst.reg.type)
+            || (ins->src[1].reg.idx[0].offset == dst.reg.idx[0].offset
+                && ins->src[1].reg.type == dst.reg.type)
+            || (ins->src[2].reg.idx[0].offset == dst.reg.idx[0].offset
+                && ins->src[2].reg.type == dst.reg.type))
+        temp_destination = TRUE;
+
+    /* Cycle through all source0 channels. */
+    for (i = 0; i < 4; ++i)
+    {
+        write_mask = 0;
+        /* Find the destination channels which use the current source0 channel. */
+        for (j = 0; j < 4; ++j)
+        {
+            if (((ins->src[0].swizzle >> (2 * j)) & 0x3) == i)
+            {
+                write_mask |= WINED3DSP_WRITEMASK_0 << j;
+                cmp_channel = WINED3DSP_WRITEMASK_0 << j;
+            }
         }
+        dst.write_mask = ins->dst[0].write_mask & write_mask;
 
-        if(temp_destination) {
-            shader_glsl_get_write_mask(&ins->dst[0], mask_char);
-            shader_glsl_append_dst(ins->ctx->buffer, ins);
-            shader_addline(ins->ctx->buffer, "tmp0%s);\n", mask_char);
+        if (temp_destination)
+        {
+            if (!(write_mask = shader_glsl_get_write_mask(&dst, mask_char)))
+                continue;
+            shader_addline(ins->ctx->buffer, "tmp0%s = (", mask_char);
         }
+        else if (!(write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &dst)))
+            continue;
+
+        shader_glsl_add_src_param(ins, &ins->src[0], cmp_channel, &src0_param);
+        shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
+        shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
+
+        shader_addline(ins->ctx->buffer, "%s%s ? %s : %s);\n",
+                src0_param.param_str, condition_suffix,
+                src1_param.param_str, src2_param.param_str);
     }
 
+    if (temp_destination)
+    {
+        shader_glsl_get_write_mask(&ins->dst[0], mask_char);
+        shader_glsl_append_dst(ins->ctx->buffer, ins);
+        shader_addline(ins->ctx->buffer, "tmp0%s);\n", mask_char);
+    }
 }
 
 /** Process the CND opcode in GLSL (dst = (src0 > 0.5) ? src1 : src2) */
@@ -2838,13 +2859,10 @@ static void shader_glsl_cmp(const struct wined3d_shader_instruction *ins)
  * the compare is done per component of src0. */
 static void shader_glsl_cnd(const struct wined3d_shader_instruction *ins)
 {
-    struct wined3d_shader_dst_param dst;
     struct glsl_src_param src0_param;
     struct glsl_src_param src1_param;
     struct glsl_src_param src2_param;
-    DWORD write_mask, cmp_channel = 0;
-    unsigned int i, j;
-    DWORD dst_mask;
+    DWORD write_mask;
     DWORD shader_version = WINED3D_SHADER_VERSION(ins->ctx->reg_maps->shader_version.major,
             ins->ctx->reg_maps->shader_version.minor);
 
@@ -2865,31 +2883,8 @@ static void shader_glsl_cnd(const struct wined3d_shader_instruction *ins)
         }
         return;
     }
-    /* Cycle through all source0 channels */
-    dst_mask = ins->dst[0].write_mask;
-    dst = ins->dst[0];
-    for (i=0; i<4; i++) {
-        write_mask = 0;
-        /* Find the destination channels which use the current source0 channel */
-        for (j=0; j<4; j++) {
-            if (((ins->src[0].swizzle >> (2 * j)) & 0x3) == i)
-            {
-                write_mask |= WINED3DSP_WRITEMASK_0 << j;
-                cmp_channel = WINED3DSP_WRITEMASK_0 << j;
-            }
-        }
-
-        dst.write_mask = dst_mask & write_mask;
-        write_mask = shader_glsl_append_dst_ext(ins->ctx->buffer, ins, &dst);
-        if (!write_mask) continue;
-
-        shader_glsl_add_src_param(ins, &ins->src[0], cmp_channel, &src0_param);
-        shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
-        shader_glsl_add_src_param(ins, &ins->src[2], write_mask, &src2_param);
 
-        shader_addline(ins->ctx->buffer, "%s > 0.5 ? %s : %s);\n",
-                src0_param.param_str, src1_param.param_str, src2_param.param_str);
-    }
+    shader_glsl_conditional_move(ins);
 }
 
 /** GLSL code generation for WINED3DSIO_MAD: Multiply the first 2 opcodes, then add the last */
@@ -5369,7 +5364,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_BREAKP                */ shader_glsl_breakp,
     /* WINED3DSIH_CALL                  */ shader_glsl_call,
     /* WINED3DSIH_CALLNZ                */ shader_glsl_callnz,
-    /* WINED3DSIH_CMP                   */ shader_glsl_cmp,
+    /* WINED3DSIH_CMP                   */ shader_glsl_conditional_move,
     /* WINED3DSIH_CND                   */ shader_glsl_cnd,
     /* WINED3DSIH_CRS                   */ shader_glsl_cross,
     /* WINED3DSIH_CUT                   */ shader_glsl_cut,
-- 
1.7.8.6




More information about the wine-patches mailing list