[PATCH 1/2] wined3d: Implement SM5 bfi opcode in glsl.

Guillaume Charifi guillaume.charifi at sfr.fr
Fri Jul 15 06:53:12 CDT 2016


Signed-off-by: Guillaume Charifi <guillaume.charifi at sfr.fr>
---
 dlls/wined3d/glsl_shader.c | 72 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 71 insertions(+), 1 deletion(-)

diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index d8edfdc..b0d3a91 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -4380,6 +4380,76 @@ static void shader_glsl_f32tof16(const struct wined3d_shader_instruction *ins)
 #undef NB_COMPS
 }
 
+
+static void shader_glsl_bitfield_op(const struct wined3d_shader_instruction *ins)
+{
+#define NB_COMPS 4
+    const DWORD write_masks[NB_COMPS] = {
+        WINED3DSP_WRITEMASK_0,
+        WINED3DSP_WRITEMASK_1,
+        WINED3DSP_WRITEMASK_2,
+        WINED3DSP_WRITEMASK_3,
+    };
+    const char dst_masks[NB_COMPS] = { 'x', 'y', 'z', 'w' };
+    const char *prefix;
+    const char *suffix;
+    int nb_params;
+    struct glsl_src_param src_param;
+    DWORD write_mask;
+    char dst_mask[6];
+    char *dst_mask_ptr = dst_mask;
+
+    switch(ins->handler_idx)
+    {
+        case WINED3DSIH_BFI:
+            prefix = "bitfieldInsert(";
+            suffix = ")";
+            nb_params = 4;
+            break;
+
+        default:
+            prefix = "<unhandled opcode>";
+            suffix = "";
+            nb_params = 0;
+            FIXME("Can't handle opcode %s.\n", debug_d3dshaderinstructionhandler(ins->handler_idx));
+    }
+
+    write_mask = shader_glsl_append_dst(ins->ctx->buffer, ins);
+
+    *dst_mask_ptr++ = '.';
+    shader_addline(ins->ctx->buffer, "uvec4(\n");
+
+    for (int i = 0; i < NB_COMPS; i++)
+    {
+        if (write_mask & write_masks[i])
+        {
+            shader_addline(ins->ctx->buffer, "%s", prefix);
+            for(int j = nb_params - 1; j >= 0; j--)
+            {
+                shader_glsl_add_src_param(ins, &ins->src[j], write_masks[i], &src_param);
+                if(j <= 1)
+                    shader_addline(ins->ctx->buffer, "int(%s)", src_param.param_str);
+                else
+                    shader_addline(ins->ctx->buffer, "%s", src_param.param_str);
+
+                if(j)
+                    shader_addline(ins->ctx->buffer, ", ");
+            }
+            shader_addline(ins->ctx->buffer, "%s", suffix);
+            *dst_mask_ptr++ = dst_masks[i];
+        } else
+            shader_addline(ins->ctx->buffer, "0");
+
+        if(i != NB_COMPS - 1)
+            shader_addline(ins->ctx->buffer, ",");
+        shader_addline(ins->ctx->buffer, "\n");
+    }
+
+    *dst_mask_ptr++ = '\0';
+    shader_addline(ins->ctx->buffer, ")%s);\n", dst_mask);
+#undef NB_COMPS
+}
+
 static void shader_glsl_else(const struct wined3d_shader_instruction *ins)
 {
     shader_addline(ins->ctx->buffer, "} else {\n");
@@ -8669,7 +8739,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_ADD                              */ shader_glsl_binop,
     /* WINED3DSIH_AND                              */ shader_glsl_binop,
     /* WINED3DSIH_BEM                              */ shader_glsl_bem,
-    /* WINED3DSIH_BFI                              */ NULL,
+    /* WINED3DSIH_BFI                              */ shader_glsl_bitfield_op,
     /* WINED3DSIH_BFREV                            */ shader_glsl_map2gl,
     /* WINED3DSIH_BREAK                            */ shader_glsl_break,
     /* WINED3DSIH_BREAKC                           */ shader_glsl_breakc,
-- 
2.7.4




More information about the wine-patches mailing list