From: Józef Kucia Subject: [PATCH 09/11] wined3d: Recognize dynamic linking shader instructions. Message-Id: <1481110985-1006-9-git-send-email-jkucia@codeweavers.com> Date: Wed, 7 Dec 2016 12:43:03 +0100 In-Reply-To: <1481110985-1006-1-git-send-email-jkucia@codeweavers.com> References: <1481110985-1006-1-git-send-email-jkucia@codeweavers.com> Signed-off-by: Józef Kucia --- 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, "", 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 *)®->immconst_data[0], imm_str[0]); - wined3d_ftoa(*(const float *)®->immconst_data[1], imm_str[1]); - wined3d_ftoa(*(const float *)®->immconst_data[2], imm_str[2]); - wined3d_ftoa(*(const float *)®->immconst_data[3], imm_str[3]); + wined3d_ftoa(*(const float *)®->u.immconst_data[0], imm_str[0]); + wined3d_ftoa(*(const float *)®->u.immconst_data[1], imm_str[1]); + wined3d_ftoa(*(const float *)®->u.immconst_data[2], imm_str[2]); + wined3d_ftoa(*(const float *)®->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, "", 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, "", 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, "", 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 *)®->immconst_data[0], *(const float *)®->immconst_data[1], - *(const float *)®->immconst_data[2], *(const float *)®->immconst_data[3]); + *(const float *)®->u.immconst_data[0], *(const float *)®->u.immconst_data[1], + *(const float *)®->u.immconst_data[2], *(const float *)®->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, "", 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