[PATCH 09/11] wined3d: Recognize dynamic linking shader instructions.

Józef Kucia jkucia at codeweavers.com
Wed Dec 7 05:43:03 CST 2016


Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---

This patch was written while testing the ret instruction in subroutines. Sets
of function bodies/tables are not parsed yet. If preferred, it can be split
into 5 patches (one for each instruction).

---
 dlls/wined3d/arb_program_shader.c |  4 +++
 dlls/wined3d/glsl_shader.c        | 32 +++++++++--------
 dlls/wined3d/shader.c             | 73 ++++++++++++++++++++++++++++-----------
 dlls/wined3d/shader_sm1.c         |  2 +-
 dlls/wined3d/shader_sm4.c         | 64 +++++++++++++++++++++++++++++++---
 dlls/wined3d/wined3d_private.h    | 25 ++++++++++++--
 6 files changed, 158 insertions(+), 42 deletions(-)

diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c
index 4b04490..54abcb8 100644
--- a/dlls/wined3d/arb_program_shader.c
+++ b/dlls/wined3d/arb_program_shader.c
@@ -5227,6 +5227,8 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
     /* WINED3DSIH_CUT_STREAM                       */ NULL,
     /* WINED3DSIH_DCL                              */ shader_hw_nop,
     /* WINED3DSIH_DCL_CONSTANT_BUFFER              */ shader_hw_nop,
+    /* WINED3DSIH_DCL_FUNCTION_BODY                */ NULL,
+    /* WINED3DSIH_DCL_FUNCTION_TABLE               */ NULL,
     /* WINED3DSIH_DCL_GLOBAL_FLAGS                 */ NULL,
     /* WINED3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT */ NULL,
     /* WINED3DSIH_DCL_HS_MAX_TESSFACTOR            */ NULL,
@@ -5240,6 +5242,7 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
     /* WINED3DSIH_DCL_INPUT_PS_SIV                 */ NULL,
     /* WINED3DSIH_DCL_INPUT_SGV                    */ NULL,
     /* WINED3DSIH_DCL_INPUT_SIV                    */ NULL,
+    /* WINED3DSIH_DCL_INTERFACE                    */ NULL,
     /* WINED3DSIH_DCL_OUTPUT                       */ NULL,
     /* WINED3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT   */ NULL,
     /* WINED3DSIH_DCL_OUTPUT_SIV                   */ NULL,
@@ -5284,6 +5287,7 @@ static const SHADER_HANDLER shader_arb_instruction_handler_table[WINED3DSIH_TABL
     /* WINED3DSIH_EQ                               */ NULL,
     /* WINED3DSIH_EXP                              */ shader_hw_scalar_op,
     /* WINED3DSIH_EXPP                             */ shader_hw_scalar_op,
+    /* WINED3DSIH_FCALL                            */ NULL,
     /* WINED3DSIH_FRC                              */ shader_hw_map2gl,
     /* WINED3DSIH_FTOI                             */ NULL,
     /* WINED3DSIH_FTOU                             */ NULL,
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 88f4465..627832c 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -2689,17 +2689,17 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
                     {
                         case WINED3D_DATA_FLOAT:
                             if (gl_info->supported[ARB_SHADER_BIT_ENCODING])
-                                sprintf(register_name, "uintBitsToFloat(%#xu)", reg->immconst_data[0]);
+                                sprintf(register_name, "uintBitsToFloat(%#xu)", reg->u.immconst_data[0]);
                             else
-                                wined3d_ftoa(*(const float *)reg->immconst_data, register_name);
+                                wined3d_ftoa(*(const float *)reg->u.immconst_data, register_name);
                             break;
                         case WINED3D_DATA_INT:
-                            sprintf(register_name, "%#x", reg->immconst_data[0]);
+                            sprintf(register_name, "%#x", reg->u.immconst_data[0]);
                             break;
                         case WINED3D_DATA_RESOURCE:
                         case WINED3D_DATA_SAMPLER:
                         case WINED3D_DATA_UINT:
-                            sprintf(register_name, "%#xu", reg->immconst_data[0]);
+                            sprintf(register_name, "%#xu", reg->u.immconst_data[0]);
                             break;
                         default:
                             sprintf(register_name, "<unhandled data type %#x>", reg->data_type);
@@ -2714,30 +2714,30 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
                             if (gl_info->supported[ARB_SHADER_BIT_ENCODING])
                             {
                                 sprintf(register_name, "uintBitsToFloat(uvec4(%#xu, %#xu, %#xu, %#xu))",
-                                        reg->immconst_data[0], reg->immconst_data[1],
-                                        reg->immconst_data[2], reg->immconst_data[3]);
+                                        reg->u.immconst_data[0], reg->u.immconst_data[1],
+                                        reg->u.immconst_data[2], reg->u.immconst_data[3]);
                             }
                             else
                             {
-                                wined3d_ftoa(*(const float *)&reg->immconst_data[0], imm_str[0]);
-                                wined3d_ftoa(*(const float *)&reg->immconst_data[1], imm_str[1]);
-                                wined3d_ftoa(*(const float *)&reg->immconst_data[2], imm_str[2]);
-                                wined3d_ftoa(*(const float *)&reg->immconst_data[3], imm_str[3]);
+                                wined3d_ftoa(*(const float *)&reg->u.immconst_data[0], imm_str[0]);
+                                wined3d_ftoa(*(const float *)&reg->u.immconst_data[1], imm_str[1]);
+                                wined3d_ftoa(*(const float *)&reg->u.immconst_data[2], imm_str[2]);
+                                wined3d_ftoa(*(const float *)&reg->u.immconst_data[3], imm_str[3]);
                                 sprintf(register_name, "vec4(%s, %s, %s, %s)",
                                         imm_str[0], imm_str[1], imm_str[2], imm_str[3]);
                             }
                             break;
                         case WINED3D_DATA_INT:
                             sprintf(register_name, "ivec4(%#x, %#x, %#x, %#x)",
-                                    reg->immconst_data[0], reg->immconst_data[1],
-                                    reg->immconst_data[2], reg->immconst_data[3]);
+                                    reg->u.immconst_data[0], reg->u.immconst_data[1],
+                                    reg->u.immconst_data[2], reg->u.immconst_data[3]);
                             break;
                         case WINED3D_DATA_RESOURCE:
                         case WINED3D_DATA_SAMPLER:
                         case WINED3D_DATA_UINT:
                             sprintf(register_name, "uvec4(%#xu, %#xu, %#xu, %#xu)",
-                                    reg->immconst_data[0], reg->immconst_data[1],
-                                    reg->immconst_data[2], reg->immconst_data[3]);
+                                    reg->u.immconst_data[0], reg->u.immconst_data[1],
+                                    reg->u.immconst_data[2], reg->u.immconst_data[3]);
                             break;
                         default:
                             sprintf(register_name, "<unhandled data type %#x>", reg->data_type);
@@ -8943,6 +8943,8 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_CUT_STREAM                       */ shader_glsl_cut,
     /* WINED3DSIH_DCL                              */ shader_glsl_nop,
     /* WINED3DSIH_DCL_CONSTANT_BUFFER              */ shader_glsl_nop,
+    /* WINED3DSIH_DCL_FUNCTION_BODY                */ NULL,
+    /* WINED3DSIH_DCL_FUNCTION_TABLE               */ NULL,
     /* WINED3DSIH_DCL_GLOBAL_FLAGS                 */ shader_glsl_nop,
     /* WINED3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT */ NULL,
     /* WINED3DSIH_DCL_HS_MAX_TESSFACTOR            */ NULL,
@@ -8956,6 +8958,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_DCL_INPUT_PS_SIV                 */ NULL,
     /* WINED3DSIH_DCL_INPUT_SGV                    */ shader_glsl_nop,
     /* WINED3DSIH_DCL_INPUT_SIV                    */ shader_glsl_nop,
+    /* WINED3DSIH_DCL_INTERFACE                    */ NULL,
     /* WINED3DSIH_DCL_OUTPUT                       */ shader_glsl_nop,
     /* WINED3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT   */ NULL,
     /* WINED3DSIH_DCL_OUTPUT_SIV                   */ shader_glsl_nop,
@@ -9000,6 +9003,7 @@ static const SHADER_HANDLER shader_glsl_instruction_handler_table[WINED3DSIH_TAB
     /* WINED3DSIH_EQ                               */ shader_glsl_relop,
     /* WINED3DSIH_EXP                              */ shader_glsl_scalar_op,
     /* WINED3DSIH_EXPP                             */ shader_glsl_expp,
+    /* WINED3DSIH_FCALL                            */ NULL,
     /* WINED3DSIH_FRC                              */ shader_glsl_map2gl,
     /* WINED3DSIH_FTOI                             */ shader_glsl_to_int,
     /* WINED3DSIH_FTOU                             */ shader_glsl_to_uint,
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index d434a64..24051cc 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -68,6 +68,8 @@ static const char * const shader_opcode_names[] =
     /* WINED3DSIH_CUT_STREAM                       */ "cut_stream",
     /* WINED3DSIH_DCL                              */ "dcl",
     /* WINED3DSIH_DCL_CONSTANT_BUFFER              */ "dcl_constantBuffer",
+    /* WINED3DSIH_DCL_FUNCTION_BODY                */ "dcl_function_body",
+    /* WINED3DSIH_DCL_FUNCTION_TABLE               */ "dcl_function_table",
     /* WINED3DSIH_DCL_GLOBAL_FLAGS                 */ "dcl_globalFlags",
     /* WINED3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT */ "dcl_hs_fork_phase_instance_count",
     /* WINED3DSIH_DCL_HS_MAX_TESSFACTOR            */ "dcl_hs_max_tessfactor",
@@ -81,6 +83,7 @@ static const char * const shader_opcode_names[] =
     /* WINED3DSIH_DCL_INPUT_PS_SIV                 */ "dcl_input_ps_siv",
     /* WINED3DSIH_DCL_INPUT_SGV                    */ "dcl_input_sgv",
     /* WINED3DSIH_DCL_INPUT_SIV                    */ "dcl_input_siv",
+    /* WINED3DSIH_DCL_INTERFACE                    */ "dcl_interface",
     /* WINED3DSIH_DCL_OUTPUT                       */ "dcl_output",
     /* WINED3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT   */ "dcl_output_control_point_count",
     /* WINED3DSIH_DCL_OUTPUT_SIV                   */ "dcl_output_siv",
@@ -125,6 +128,7 @@ static const char * const shader_opcode_names[] =
     /* WINED3DSIH_EQ                               */ "eq",
     /* WINED3DSIH_EXP                              */ "exp",
     /* WINED3DSIH_EXPP                             */ "expp",
+    /* WINED3DSIH_FCALL                            */ "fcall",
     /* WINED3DSIH_FRC                              */ "frc",
     /* WINED3DSIH_FTOI                             */ "ftoi",
     /* WINED3DSIH_FTOU                             */ "ftou",
@@ -1034,7 +1038,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
             if (!lconst) return E_OUTOFMEMORY;
 
             lconst->idx = ins.dst[0].reg.idx[0].offset;
-            memcpy(lconst->value, ins.src[0].reg.immconst_data, 4 * sizeof(DWORD));
+            memcpy(lconst->value, ins.src[0].reg.u.immconst_data, 4 * sizeof(DWORD));
             value = (float *)lconst->value;
 
             /* In pixel shader 1.X shaders, the constants are clamped between [-1;1] */
@@ -1064,7 +1068,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
             if (!lconst) return E_OUTOFMEMORY;
 
             lconst->idx = ins.dst[0].reg.idx[0].offset;
-            memcpy(lconst->value, ins.src[0].reg.immconst_data, 4 * sizeof(DWORD));
+            memcpy(lconst->value, ins.src[0].reg.u.immconst_data, 4 * sizeof(DWORD));
 
             list_add_head(&shader->constantsI, &lconst->entry);
             reg_maps->local_int_consts |= (1u << lconst->idx);
@@ -1075,7 +1079,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, const st
             if (!lconst) return E_OUTOFMEMORY;
 
             lconst->idx = ins.dst[0].reg.idx[0].offset;
-            memcpy(lconst->value, ins.src[0].reg.immconst_data, sizeof(DWORD));
+            memcpy(lconst->value, ins.src[0].reg.u.immconst_data, sizeof(DWORD));
 
             list_add_head(&shader->constantsB, &lconst->entry);
             reg_maps->local_bool_consts |= (1u << lconst->idx);
@@ -1919,6 +1923,14 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer,
             shader_addline(buffer, "m");
             break;
 
+        case WINED3DSPR_FUNCTIONBODY:
+            shader_addline(buffer, "fb");
+            break;
+
+        case WINED3DSPR_FUNCTIONPOINTER:
+            shader_addline(buffer, "fp");
+            break;
+
         default:
             shader_addline(buffer, "<unhandled_rtype(%#x)>", reg->type);
             break;
@@ -1933,15 +1945,15 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer,
                 switch (reg->data_type)
                 {
                     case WINED3D_DATA_FLOAT:
-                        shader_addline(buffer, "%.8e", *(const float *)reg->immconst_data);
+                        shader_addline(buffer, "%.8e", *(const float *)reg->u.immconst_data);
                         break;
                     case WINED3D_DATA_INT:
-                        shader_addline(buffer, "%d", reg->immconst_data[0]);
+                        shader_addline(buffer, "%d", reg->u.immconst_data[0]);
                         break;
                     case WINED3D_DATA_RESOURCE:
                     case WINED3D_DATA_SAMPLER:
                     case WINED3D_DATA_UINT:
-                        shader_addline(buffer, "%u", reg->immconst_data[0]);
+                        shader_addline(buffer, "%u", reg->u.immconst_data[0]);
                         break;
                     default:
                         shader_addline(buffer, "<unhandled data type %#x>", reg->data_type);
@@ -1954,20 +1966,20 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer,
                 {
                     case WINED3D_DATA_FLOAT:
                         shader_addline(buffer, "%.8e, %.8e, %.8e, %.8e",
-                                *(const float *)&reg->immconst_data[0], *(const float *)&reg->immconst_data[1],
-                                *(const float *)&reg->immconst_data[2], *(const float *)&reg->immconst_data[3]);
+                                *(const float *)&reg->u.immconst_data[0], *(const float *)&reg->u.immconst_data[1],
+                                *(const float *)&reg->u.immconst_data[2], *(const float *)&reg->u.immconst_data[3]);
                         break;
                     case WINED3D_DATA_INT:
                         shader_addline(buffer, "%d, %d, %d, %d",
-                                reg->immconst_data[0], reg->immconst_data[1],
-                                reg->immconst_data[2], reg->immconst_data[3]);
+                                reg->u.immconst_data[0], reg->u.immconst_data[1],
+                                reg->u.immconst_data[2], reg->u.immconst_data[3]);
                         break;
                     case WINED3D_DATA_RESOURCE:
                     case WINED3D_DATA_SAMPLER:
                     case WINED3D_DATA_UINT:
                         shader_addline(buffer, "%u, %u, %u, %u",
-                                reg->immconst_data[0], reg->immconst_data[1],
-                                reg->immconst_data[2], reg->immconst_data[3]);
+                                reg->u.immconst_data[0], reg->u.immconst_data[1],
+                                reg->u.immconst_data[2], reg->u.immconst_data[3]);
                         break;
                     default:
                         shader_addline(buffer, "<unhandled data type %#x>", reg->data_type);
@@ -2006,6 +2018,9 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer,
                 shader_addline(buffer, "%u]", reg->idx[1].offset);
             }
         }
+
+        if (reg->type == WINED3DSPR_FUNCTIONPOINTER)
+            shader_addline(buffer, "[%u]", reg->u.fp_body_idx);
     }
 }
 
@@ -2327,6 +2342,16 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe
             shader_addline(&buffer, ", %s",
                     ins.flags & WINED3DSI_INDEXED_DYNAMIC ? "dynamicIndexed" : "immediateIndexed");
         }
+        else if (ins.handler_idx == WINED3DSIH_DCL_FUNCTION_BODY)
+        {
+            shader_addline(&buffer, "%s fb%u",
+                    shader_opcode_names[ins.handler_idx], ins.declaration.index);
+        }
+        else if (ins.handler_idx == WINED3DSIH_DCL_FUNCTION_TABLE)
+        {
+            shader_addline(&buffer, "%s ft%u = {...}",
+                    shader_opcode_names[ins.handler_idx], ins.declaration.index);
+        }
         else if (ins.handler_idx == WINED3DSIH_DCL_GLOBAL_FLAGS)
         {
             shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
@@ -2395,6 +2420,12 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe
             shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
             shader_dump_primitive_type(&buffer, ins.declaration.primitive_type);
         }
+        else if (ins.handler_idx == WINED3DSIH_DCL_INTERFACE)
+        {
+            shader_addline(&buffer, "%s fp[%u][%u][%u] = {...}",
+                    shader_opcode_names[ins.handler_idx], ins.declaration.fp.index,
+                    ins.declaration.fp.array_size, ins.declaration.fp.body_count);
+        }
         else if (ins.handler_idx == WINED3DSIH_DCL_RESOURCE_STRUCTURED)
         {
             shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
@@ -2470,23 +2501,23 @@ static void shader_trace_init(const struct wined3d_shader_frontend *fe, void *fe
         {
             shader_addline(&buffer, "def c%u = %.8e, %.8e, %.8e, %.8e", shader_get_float_offset(ins.dst[0].reg.type,
                     ins.dst[0].reg.idx[0].offset),
-                    *(const float *)&ins.src[0].reg.immconst_data[0],
-                    *(const float *)&ins.src[0].reg.immconst_data[1],
-                    *(const float *)&ins.src[0].reg.immconst_data[2],
-                    *(const float *)&ins.src[0].reg.immconst_data[3]);
+                    *(const float *)&ins.src[0].reg.u.immconst_data[0],
+                    *(const float *)&ins.src[0].reg.u.immconst_data[1],
+                    *(const float *)&ins.src[0].reg.u.immconst_data[2],
+                    *(const float *)&ins.src[0].reg.u.immconst_data[3]);
         }
         else if (ins.handler_idx == WINED3DSIH_DEFI)
         {
             shader_addline(&buffer, "defi i%u = %d, %d, %d, %d", ins.dst[0].reg.idx[0].offset,
-                    ins.src[0].reg.immconst_data[0],
-                    ins.src[0].reg.immconst_data[1],
-                    ins.src[0].reg.immconst_data[2],
-                    ins.src[0].reg.immconst_data[3]);
+                    ins.src[0].reg.u.immconst_data[0],
+                    ins.src[0].reg.u.immconst_data[1],
+                    ins.src[0].reg.u.immconst_data[2],
+                    ins.src[0].reg.u.immconst_data[3]);
         }
         else if (ins.handler_idx == WINED3DSIH_DEFB)
         {
             shader_addline(&buffer, "defb b%u = %s",
-                    ins.dst[0].reg.idx[0].offset, ins.src[0].reg.immconst_data[0] ? "true" : "false");
+                    ins.dst[0].reg.idx[0].offset, ins.src[0].reg.u.immconst_data[0] ? "true" : "false");
         }
         else
         {
diff --git a/dlls/wined3d/shader_sm1.c b/dlls/wined3d/shader_sm1.c
index fc79f6b..3b6e1b4 100644
--- a/dlls/wined3d/shader_sm1.c
+++ b/dlls/wined3d/shader_sm1.c
@@ -657,7 +657,7 @@ static void shader_sm1_read_immconst(const DWORD **ptr, struct wined3d_shader_sr
     src_param->reg.idx[1].offset = ~0U;
     src_param->reg.idx[1].rel_addr = NULL;
     src_param->reg.immconst_type = type;
-    memcpy(src_param->reg.immconst_data, *ptr, count * sizeof(DWORD));
+    memcpy(src_param->reg.u.immconst_data, *ptr, count * sizeof(DWORD));
     src_param->swizzle = WINED3DSP_NOSWIZZLE;
     src_param->modifiers = 0;
 
diff --git a/dlls/wined3d/shader_sm4.c b/dlls/wined3d/shader_sm4.c
index d0497ce..00fb4c0 100644
--- a/dlls/wined3d/shader_sm4.c
+++ b/dlls/wined3d/shader_sm4.c
@@ -64,6 +64,9 @@ WINE_DECLARE_DEBUG_CHANNEL(d3d_bytecode);
 #define WINED3D_SM5_CONTROL_POINT_COUNT_SHIFT   11
 #define WINED3D_SM5_CONTROL_POINT_COUNT_MASK    (0xffu << WINED3D_SM5_CONTROL_POINT_COUNT_SHIFT)
 
+#define WINED3D_SM5_FP_ARRAY_SIZE_SHIFT         16
+#define WINED3D_SM5_FP_TABLE_COUNT_MASK         0xffffu
+
 #define WINED3D_SM5_UAV_FLAGS_SHIFT             11
 #define WINED3D_SM5_UAV_FLAGS_MASK              (0x8fffu << WINED3D_SM5_UAV_FLAGS_SHIFT)
 
@@ -153,6 +156,7 @@ enum wined3d_sm4_opcode
     WINED3D_SM4_OP_ISHL                             = 0x29,
     WINED3D_SM4_OP_ISHR                             = 0x2a,
     WINED3D_SM4_OP_ITOF                             = 0x2b,
+    WINED3D_SM4_OP_LABEL                            = 0x2c,
     WINED3D_SM4_OP_LD                               = 0x2d,
     WINED3D_SM4_OP_LD2DMS                           = 0x2e,
     WINED3D_SM4_OP_LOG                              = 0x2f,
@@ -219,6 +223,7 @@ enum wined3d_sm4_opcode
     WINED3D_SM5_OP_HS_JOIN_PHASE                    = 0x74,
     WINED3D_SM5_OP_EMIT_STREAM                      = 0x75,
     WINED3D_SM5_OP_CUT_STREAM                       = 0x76,
+    WINED3D_SM5_OP_FCALL                            = 0x78,
     WINED3D_SM5_OP_BUFINFO                          = 0x79,
     WINED3D_SM5_OP_DERIV_RTX_COARSE                 = 0x7a,
     WINED3D_SM5_OP_DERIV_RTX_FINE                   = 0x7b,
@@ -231,6 +236,9 @@ enum wined3d_sm4_opcode
     WINED3D_SM5_OP_BFREV                            = 0x8d,
     WINED3D_SM5_OP_SWAPC                            = 0x8e,
     WINED3D_SM5_OP_DCL_STREAM                       = 0x8f,
+    WINED3D_SM5_OP_DCL_FUNCTION_BODY                = 0x90,
+    WINED3D_SM5_OP_DCL_FUNCTION_TABLE               = 0x91,
+    WINED3D_SM5_OP_DCL_INTERFACE                    = 0x92,
     WINED3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT    = 0x93,
     WINED3D_SM5_OP_DCL_OUTPUT_CONTROL_POINT_COUNT   = 0x94,
     WINED3D_SM5_OP_DCL_TESSELLATOR_DOMAIN           = 0x95,
@@ -285,6 +293,8 @@ enum wined3d_sm4_register_type
     WINED3D_SM4_RT_DEPTHOUT                = 0x0c,
     WINED3D_SM4_RT_NULL                    = 0x0d,
     WINED3D_SM5_RT_STREAM                  = 0x10,
+    WINED3D_SM5_RT_FUNCTION_BODY           = 0x11,
+    WINED3D_SM5_RT_FUNCTION_POINTER        = 0x13,
     WINED3D_SM5_RT_OUTPUT_CONTROL_POINT_ID = 0x16,
     WINED3D_SM5_RT_FORK_INSTANCE_ID        = 0x17,
     WINED3D_SM5_RT_INPUT_CONTROL_POINT     = 0x19,
@@ -630,6 +640,40 @@ static void shader_sm4_read_dcl_global_flags(struct wined3d_shader_instruction *
     ins->flags = (opcode_token & WINED3D_SM4_GLOBAL_FLAGS_MASK) >> WINED3D_SM4_GLOBAL_FLAGS_SHIFT;
 }
 
+static void shader_sm5_read_fcall(struct wined3d_shader_instruction *ins,
+        DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
+        struct wined3d_sm4_data *priv)
+{
+    priv->src_param[0].reg.u.fp_body_idx = *tokens++;
+    shader_sm4_read_src_param(priv, &tokens, WINED3D_DATA_OPAQUE, &priv->src_param[0]);
+}
+
+static void shader_sm5_read_dcl_function_body(struct wined3d_shader_instruction *ins,
+        DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
+        struct wined3d_sm4_data *priv)
+{
+    ins->declaration.index = *tokens;
+}
+
+static void shader_sm5_read_dcl_function_table(struct wined3d_shader_instruction *ins,
+        DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
+        struct wined3d_sm4_data *priv)
+{
+    ins->declaration.index = *tokens++;
+    FIXME("Ignoring set of function bodies (count %u).\n", *tokens);
+}
+
+static void shader_sm5_read_dcl_interface(struct wined3d_shader_instruction *ins,
+        DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
+        struct wined3d_sm4_data *priv)
+{
+    ins->declaration.fp.index = *tokens++;
+    ins->declaration.fp.body_count = *tokens++;
+    ins->declaration.fp.array_size = *tokens >> WINED3D_SM5_FP_ARRAY_SIZE_SHIFT;
+    ins->declaration.fp.table_count = *tokens++ & WINED3D_SM5_FP_TABLE_COUNT_MASK;
+    FIXME("Ignoring set of function tables (count %u).\n", ins->declaration.fp.table_count);
+}
+
 static void shader_sm5_read_control_point_count(struct wined3d_shader_instruction *ins,
         DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
         struct wined3d_sm4_data *priv)
@@ -731,6 +775,7 @@ static void shader_sm5_read_sync(struct wined3d_shader_instruction *ins,
  * f -> WINED3D_DATA_FLOAT
  * i -> WINED3D_DATA_INT
  * u -> WINED3D_DATA_UINT
+ * O -> WINED3D_DATA_OPAQUE
  * R -> WINED3D_DATA_RESOURCE
  * S -> WINED3D_DATA_SAMPLER
  * U -> WINED3D_DATA_UAV
@@ -779,6 +824,7 @@ static const struct wined3d_sm4_opcode_info opcode_table[] =
     {WINED3D_SM4_OP_ISHL,                             WINED3DSIH_ISHL,                             "i",    "ii"},
     {WINED3D_SM4_OP_ISHR,                             WINED3DSIH_ISHR,                             "i",    "ii"},
     {WINED3D_SM4_OP_ITOF,                             WINED3DSIH_ITOF,                             "f",    "i"},
+    {WINED3D_SM4_OP_LABEL,                            WINED3DSIH_LABEL,                            "",     "O"},
     {WINED3D_SM4_OP_LD,                               WINED3DSIH_LD,                               "u",    "iR"},
     {WINED3D_SM4_OP_LD2DMS,                           WINED3DSIH_LD2DMS,                           "u",    "iRi"},
     {WINED3D_SM4_OP_LOG,                              WINED3DSIH_LOG,                              "f",    "f"},
@@ -863,6 +909,8 @@ static const struct wined3d_sm4_opcode_info opcode_table[] =
     {WINED3D_SM5_OP_HS_JOIN_PHASE,                    WINED3DSIH_HS_JOIN_PHASE,                    "",     ""},
     {WINED3D_SM5_OP_EMIT_STREAM,                      WINED3DSIH_EMIT_STREAM,                      "",     "f"},
     {WINED3D_SM5_OP_CUT_STREAM,                       WINED3DSIH_CUT_STREAM,                       "",     "f"},
+    {WINED3D_SM5_OP_FCALL,                            WINED3DSIH_FCALL,                            "",     "O",
+            shader_sm5_read_fcall},
     {WINED3D_SM5_OP_BUFINFO,                          WINED3DSIH_BUFINFO,                          "i",    "U"},
     {WINED3D_SM5_OP_DERIV_RTX_COARSE,                 WINED3DSIH_DSX_COARSE,                       "f",    "f"},
     {WINED3D_SM5_OP_DERIV_RTX_FINE,                   WINED3DSIH_DSX_FINE,                         "f",    "f"},
@@ -875,6 +923,12 @@ static const struct wined3d_sm4_opcode_info opcode_table[] =
     {WINED3D_SM5_OP_BFREV,                            WINED3DSIH_BFREV,                            "u",    "u"},
     {WINED3D_SM5_OP_SWAPC,                            WINED3DSIH_SWAPC,                            "ff",   "uff"},
     {WINED3D_SM5_OP_DCL_STREAM,                       WINED3DSIH_DCL_STREAM,                       "",     "f"},
+    {WINED3D_SM5_OP_DCL_FUNCTION_BODY,                WINED3DSIH_DCL_FUNCTION_BODY,                "",     "",
+            shader_sm5_read_dcl_function_body},
+    {WINED3D_SM5_OP_DCL_FUNCTION_TABLE,               WINED3DSIH_DCL_FUNCTION_TABLE,               "",     "",
+            shader_sm5_read_dcl_function_table},
+    {WINED3D_SM5_OP_DCL_INTERFACE,                    WINED3DSIH_DCL_INTERFACE,                    "",     "",
+            shader_sm5_read_dcl_interface},
     {WINED3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT,    WINED3DSIH_DCL_INPUT_CONTROL_POINT_COUNT,    "",     "",
             shader_sm5_read_control_point_count},
     {WINED3D_SM5_OP_DCL_OUTPUT_CONTROL_POINT_COUNT,   WINED3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT,   "",     "",
@@ -948,9 +1002,9 @@ static const enum wined3d_shader_register_type register_type_table[] =
     /* UNKNOWN */                                ~0u,
     /* UNKNOWN */                                ~0u,
     /* WINED3D_SM5_RT_STREAM */                  WINED3DSPR_STREAM,
+    /* WINED3D_SM5_RT_FUNCTION_BODY */           WINED3DSPR_FUNCTIONBODY,
     /* UNKNOWN */                                ~0u,
-    /* UNKNOWN */                                ~0u,
-    /* UNKNOWN */                                ~0u,
+    /* WINED3D_SM5_RT_FUNCTION_POINTER */        WINED3DSPR_FUNCTIONPOINTER,
     /* UNKNOWN */                                ~0u,
     /* UNKNOWN */                                ~0u,
     /* WINED3D_SM5_RT_OUTPUT_CONTROL_POINT_ID */ WINED3DSPR_OUTPOINTID,
@@ -1017,6 +1071,8 @@ static enum wined3d_data_type map_data_type(char t)
             return WINED3D_DATA_INT;
         case 'u':
             return WINED3D_DATA_UINT;
+        case 'O':
+            return WINED3D_DATA_OPAQUE;
         case 'R':
             return WINED3D_DATA_RESOURCE;
         case 'S':
@@ -1259,13 +1315,13 @@ static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **p
         {
             case WINED3D_SM4_IMMCONST_SCALAR:
                 param->immconst_type = WINED3D_IMMCONST_SCALAR;
-                memcpy(param->immconst_data, *ptr, 1 * sizeof(DWORD));
+                memcpy(param->u.immconst_data, *ptr, 1 * sizeof(DWORD));
                 *ptr += 1;
                 break;
 
             case WINED3D_SM4_IMMCONST_VEC4:
                 param->immconst_type = WINED3D_IMMCONST_VEC4;
-                memcpy(param->immconst_data, *ptr, 4 * sizeof(DWORD));
+                memcpy(param->u.immconst_data, *ptr, 4 * sizeof(DWORD));
                 *ptr += 4;
                 break;
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 859b89f..dd2754b 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -392,6 +392,8 @@ enum wined3d_shader_register_type
     WINED3DSPR_LOCALTHREADINDEX,
     WINED3DSPR_IDXTEMP,
     WINED3DSPR_STREAM,
+    WINED3DSPR_FUNCTIONBODY,
+    WINED3DSPR_FUNCTIONPOINTER,
 };
 
 enum wined3d_data_type
@@ -404,6 +406,7 @@ enum wined3d_data_type
     WINED3D_DATA_UINT,
     WINED3D_DATA_UNORM,
     WINED3D_DATA_SNORM,
+    WINED3D_DATA_OPAQUE,
 };
 
 enum wined3d_immconst_type
@@ -594,6 +597,8 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER
     WINED3DSIH_CUT_STREAM,
     WINED3DSIH_DCL,
     WINED3DSIH_DCL_CONSTANT_BUFFER,
+    WINED3DSIH_DCL_FUNCTION_BODY,
+    WINED3DSIH_DCL_FUNCTION_TABLE,
     WINED3DSIH_DCL_GLOBAL_FLAGS,
     WINED3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT,
     WINED3DSIH_DCL_HS_MAX_TESSFACTOR,
@@ -607,6 +612,7 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER
     WINED3DSIH_DCL_INPUT_PS_SIV,
     WINED3DSIH_DCL_INPUT_SGV,
     WINED3DSIH_DCL_INPUT_SIV,
+    WINED3DSIH_DCL_INTERFACE,
     WINED3DSIH_DCL_OUTPUT,
     WINED3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT,
     WINED3DSIH_DCL_OUTPUT_SIV,
@@ -651,6 +657,7 @@ enum WINED3D_SHADER_INSTRUCTION_HANDLER
     WINED3DSIH_EQ,
     WINED3DSIH_EXP,
     WINED3DSIH_EXPP,
+    WINED3DSIH_FCALL,
     WINED3DSIH_FRC,
     WINED3DSIH_FTOI,
     WINED3DSIH_FTOU,
@@ -930,7 +937,11 @@ struct wined3d_shader_register
     enum wined3d_data_type data_type;
     struct wined3d_shader_register_index idx[2];
     enum wined3d_immconst_type immconst_type;
-    DWORD immconst_data[4];
+    union
+    {
+        DWORD immconst_data[4];
+        unsigned fp_body_idx;
+    } u;
 };
 
 struct wined3d_shader_dst_param
@@ -987,6 +998,14 @@ struct wined3d_shader_thread_group_size
     unsigned int x, y, z;
 };
 
+struct wined3d_shader_function_table_pointer
+{
+    unsigned int index;
+    unsigned int array_size;
+    unsigned int body_count;
+    unsigned int table_count;
+};
+
 struct wined3d_shader_texel_offset
 {
     signed char u, v, w;
@@ -1011,7 +1030,8 @@ struct wined3d_shader_instruction
         enum wined3d_primitive_type primitive_type;
         struct wined3d_shader_dst_param dst;
         struct wined3d_shader_src_param src;
-        UINT count;
+        unsigned int count;
+        unsigned int index;
         const struct wined3d_shader_immediate_constant_buffer *icb;
         struct wined3d_shader_structured_resource structured_resource;
         struct wined3d_shader_tgsm_raw tgsm_raw;
@@ -1022,6 +1042,7 @@ struct wined3d_shader_instruction
         enum wined3d_tessellator_partitioning tessellator_partitioning;
         float max_tessellation_factor;
         struct wined3d_shader_indexable_temp indexable_temp;
+        struct wined3d_shader_function_table_pointer fp;
     } declaration;
 };
 
-- 
2.7.3




More information about the wine-patches mailing list