From bc2380830ccf29787be590fd59ef4acae4bfd243 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 11 Jun 2025 07:52:20 +1000 Subject: [PATCH] Updated vkd3d to 14477b1066cfd4d12ce044f98fea09507f320251. --- libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 332 +---------------- libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 18 +- libs/vkd3d/libs/vkd3d-shader/dxil.c | 257 ++++++------- libs/vkd3d/libs/vkd3d-shader/fx.c | 153 ++++---- libs/vkd3d/libs/vkd3d-shader/glsl.c | 6 +- libs/vkd3d/libs/vkd3d-shader/ir.c | 342 +++++++++++++++++- libs/vkd3d/libs/vkd3d-shader/msl.c | 126 ++++++- .../libs/vkd3d-shader/vkd3d_shader_private.h | 9 +- 8 files changed, 701 insertions(+), 542 deletions(-) diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c index db60883f2a3..af5552635cb 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c @@ -27,336 +27,6 @@ #include #include -static const char * const shader_opcode_names[] = -{ - [VKD3DSIH_ABS ] = "abs", - [VKD3DSIH_ACOS ] = "acos", - [VKD3DSIH_ADD ] = "add", - [VKD3DSIH_AND ] = "and", - [VKD3DSIH_ASIN ] = "asin", - [VKD3DSIH_ATAN ] = "atan", - [VKD3DSIH_ATOMIC_AND ] = "atomic_and", - [VKD3DSIH_ATOMIC_CMP_STORE ] = "atomic_cmp_store", - [VKD3DSIH_ATOMIC_IADD ] = "atomic_iadd", - [VKD3DSIH_ATOMIC_IMAX ] = "atomic_imax", - [VKD3DSIH_ATOMIC_IMIN ] = "atomic_imin", - [VKD3DSIH_ATOMIC_OR ] = "atomic_or", - [VKD3DSIH_ATOMIC_UMAX ] = "atomic_umax", - [VKD3DSIH_ATOMIC_UMIN ] = "atomic_umin", - [VKD3DSIH_ATOMIC_XOR ] = "atomic_xor", - [VKD3DSIH_BEM ] = "bem", - [VKD3DSIH_BFI ] = "bfi", - [VKD3DSIH_BFREV ] = "bfrev", - [VKD3DSIH_BRANCH ] = "branch", - [VKD3DSIH_BREAK ] = "break", - [VKD3DSIH_BREAKC ] = "break", - [VKD3DSIH_BREAKP ] = "breakp", - [VKD3DSIH_BUFINFO ] = "bufinfo", - [VKD3DSIH_CALL ] = "call", - [VKD3DSIH_CALLNZ ] = "callnz", - [VKD3DSIH_CASE ] = "case", - [VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED ] = "check_access_fully_mapped", - [VKD3DSIH_CMP ] = "cmp", - [VKD3DSIH_CND ] = "cnd", - [VKD3DSIH_CONTINUE ] = "continue", - [VKD3DSIH_CONTINUEP ] = "continuec", - [VKD3DSIH_COUNTBITS ] = "countbits", - [VKD3DSIH_CRS ] = "crs", - [VKD3DSIH_CUT ] = "cut", - [VKD3DSIH_CUT_STREAM ] = "cut_stream", - [VKD3DSIH_DADD ] = "dadd", - [VKD3DSIH_DCL ] = "dcl", - [VKD3DSIH_DCL_CONSTANT_BUFFER ] = "dcl_constantBuffer", - [VKD3DSIH_DCL_FUNCTION_BODY ] = "dcl_function_body", - [VKD3DSIH_DCL_FUNCTION_TABLE ] = "dcl_function_table", - [VKD3DSIH_DCL_GLOBAL_FLAGS ] = "dcl_globalFlags", - [VKD3DSIH_DCL_GS_INSTANCES ] = "dcl_gs_instances", - [VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT] = "dcl_hs_fork_phase_instance_count", - [VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT] = "dcl_hs_join_phase_instance_count", - [VKD3DSIH_DCL_HS_MAX_TESSFACTOR ] = "dcl_hs_max_tessfactor", - [VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER ] = "dcl_immediateConstantBuffer", - [VKD3DSIH_DCL_INDEX_RANGE ] = "dcl_index_range", - [VKD3DSIH_DCL_INDEXABLE_TEMP ] = "dcl_indexableTemp", - [VKD3DSIH_DCL_INPUT ] = "dcl_input", - [VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT ] = "dcl_input_control_point_count", - [VKD3DSIH_DCL_INPUT_PRIMITIVE ] = "dcl_inputprimitive", - [VKD3DSIH_DCL_INPUT_PS ] = "dcl_input_ps", - [VKD3DSIH_DCL_INPUT_PS_SGV ] = "dcl_input_ps_sgv", - [VKD3DSIH_DCL_INPUT_PS_SIV ] = "dcl_input_ps_siv", - [VKD3DSIH_DCL_INPUT_SGV ] = "dcl_input_sgv", - [VKD3DSIH_DCL_INPUT_SIV ] = "dcl_input_siv", - [VKD3DSIH_DCL_INTERFACE ] = "dcl_interface", - [VKD3DSIH_DCL_OUTPUT ] = "dcl_output", - [VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT ] = "dcl_output_control_point_count", - [VKD3DSIH_DCL_OUTPUT_SGV ] = "dcl_output_sgv", - [VKD3DSIH_DCL_OUTPUT_SIV ] = "dcl_output_siv", - [VKD3DSIH_DCL_OUTPUT_TOPOLOGY ] = "dcl_outputtopology", - [VKD3DSIH_DCL_RESOURCE_RAW ] = "dcl_resource_raw", - [VKD3DSIH_DCL_RESOURCE_STRUCTURED ] = "dcl_resource_structured", - [VKD3DSIH_DCL_SAMPLER ] = "dcl_sampler", - [VKD3DSIH_DCL_STREAM ] = "dcl_stream", - [VKD3DSIH_DCL_TEMPS ] = "dcl_temps", - [VKD3DSIH_DCL_TESSELLATOR_DOMAIN ] = "dcl_tessellator_domain", - [VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = "dcl_tessellator_output_primitive", - [VKD3DSIH_DCL_TESSELLATOR_PARTITIONING ] = "dcl_tessellator_partitioning", - [VKD3DSIH_DCL_TGSM_RAW ] = "dcl_tgsm_raw", - [VKD3DSIH_DCL_TGSM_STRUCTURED ] = "dcl_tgsm_structured", - [VKD3DSIH_DCL_THREAD_GROUP ] = "dcl_thread_group", - [VKD3DSIH_DCL_UAV_RAW ] = "dcl_uav_raw", - [VKD3DSIH_DCL_UAV_STRUCTURED ] = "dcl_uav_structured", - [VKD3DSIH_DCL_UAV_TYPED ] = "dcl_uav_typed", - [VKD3DSIH_DCL_VERTICES_OUT ] = "dcl_maxout", - [VKD3DSIH_DDIV ] = "ddiv", - [VKD3DSIH_DEF ] = "def", - [VKD3DSIH_DEFAULT ] = "default", - [VKD3DSIH_DEFB ] = "defb", - [VKD3DSIH_DEFI ] = "defi", - [VKD3DSIH_DEQO ] = "deq", - [VKD3DSIH_DFMA ] = "dfma", - [VKD3DSIH_DGEO ] = "dge", - [VKD3DSIH_DISCARD ] = "discard", - [VKD3DSIH_DIV ] = "div", - [VKD3DSIH_DLT ] = "dlt", - [VKD3DSIH_DMAX ] = "dmax", - [VKD3DSIH_DMIN ] = "dmin", - [VKD3DSIH_DMOV ] = "dmov", - [VKD3DSIH_DMOVC ] = "dmovc", - [VKD3DSIH_DMUL ] = "dmul", - [VKD3DSIH_DNE ] = "dne", - [VKD3DSIH_DP2 ] = "dp2", - [VKD3DSIH_DP2ADD ] = "dp2add", - [VKD3DSIH_DP3 ] = "dp3", - [VKD3DSIH_DP4 ] = "dp4", - [VKD3DSIH_DRCP ] = "drcp", - [VKD3DSIH_DST ] = "dst", - [VKD3DSIH_DSX ] = "dsx", - [VKD3DSIH_DSX_COARSE ] = "deriv_rtx_coarse", - [VKD3DSIH_DSX_FINE ] = "deriv_rtx_fine", - [VKD3DSIH_DSY ] = "dsy", - [VKD3DSIH_DSY_COARSE ] = "deriv_rty_coarse", - [VKD3DSIH_DSY_FINE ] = "deriv_rty_fine", - [VKD3DSIH_DTOF ] = "dtof", - [VKD3DSIH_DTOI ] = "dtoi", - [VKD3DSIH_DTOU ] = "dtou", - [VKD3DSIH_ELSE ] = "else", - [VKD3DSIH_EMIT ] = "emit", - [VKD3DSIH_EMIT_STREAM ] = "emit_stream", - [VKD3DSIH_ENDIF ] = "endif", - [VKD3DSIH_ENDLOOP ] = "endloop", - [VKD3DSIH_ENDREP ] = "endrep", - [VKD3DSIH_ENDSWITCH ] = "endswitch", - [VKD3DSIH_EQO ] = "eq", - [VKD3DSIH_EQU ] = "eq_unord", - [VKD3DSIH_EVAL_CENTROID ] = "eval_centroid", - [VKD3DSIH_EVAL_SAMPLE_INDEX ] = "eval_sample_index", - [VKD3DSIH_EXP ] = "exp", - [VKD3DSIH_EXPP ] = "expp", - [VKD3DSIH_F16TOF32 ] = "f16tof32", - [VKD3DSIH_F32TOF16 ] = "f32tof16", - [VKD3DSIH_FCALL ] = "fcall", - [VKD3DSIH_FIRSTBIT_HI ] = "firstbit_hi", - [VKD3DSIH_FIRSTBIT_LO ] = "firstbit_lo", - [VKD3DSIH_FIRSTBIT_SHI ] = "firstbit_shi", - [VKD3DSIH_FRC ] = "frc", - [VKD3DSIH_FREM ] = "frem", - [VKD3DSIH_FTOD ] = "ftod", - [VKD3DSIH_FTOI ] = "ftoi", - [VKD3DSIH_FTOU ] = "ftou", - [VKD3DSIH_GATHER4 ] = "gather4", - [VKD3DSIH_GATHER4_C ] = "gather4_c", - [VKD3DSIH_GATHER4_C_S ] = "gather4_c_s", - [VKD3DSIH_GATHER4_PO ] = "gather4_po", - [VKD3DSIH_GATHER4_PO_C ] = "gather4_po_c", - [VKD3DSIH_GATHER4_PO_C_S ] = "gather4_po_c_s", - [VKD3DSIH_GATHER4_PO_S ] = "gather4_po_s", - [VKD3DSIH_GATHER4_S ] = "gather4_s", - [VKD3DSIH_GEO ] = "ge", - [VKD3DSIH_GEU ] = "ge_unord", - [VKD3DSIH_HCOS ] = "hcos", - [VKD3DSIH_HS_CONTROL_POINT_PHASE ] = "hs_control_point_phase", - [VKD3DSIH_HS_DECLS ] = "hs_decls", - [VKD3DSIH_HS_FORK_PHASE ] = "hs_fork_phase", - [VKD3DSIH_HS_JOIN_PHASE ] = "hs_join_phase", - [VKD3DSIH_HSIN ] = "hsin", - [VKD3DSIH_HTAN ] = "htan", - [VKD3DSIH_IADD ] = "iadd", - [VKD3DSIH_IBFE ] = "ibfe", - [VKD3DSIH_IDIV ] = "idiv", - [VKD3DSIH_IEQ ] = "ieq", - [VKD3DSIH_IF ] = "if", - [VKD3DSIH_IFC ] = "if", - [VKD3DSIH_IGE ] = "ige", - [VKD3DSIH_ILT ] = "ilt", - [VKD3DSIH_IMAD ] = "imad", - [VKD3DSIH_IMAX ] = "imax", - [VKD3DSIH_IMIN ] = "imin", - [VKD3DSIH_IMM_ATOMIC_ALLOC ] = "imm_atomic_alloc", - [VKD3DSIH_IMM_ATOMIC_AND ] = "imm_atomic_and", - [VKD3DSIH_IMM_ATOMIC_CMP_EXCH ] = "imm_atomic_cmp_exch", - [VKD3DSIH_IMM_ATOMIC_CONSUME ] = "imm_atomic_consume", - [VKD3DSIH_IMM_ATOMIC_EXCH ] = "imm_atomic_exch", - [VKD3DSIH_IMM_ATOMIC_IADD ] = "imm_atomic_iadd", - [VKD3DSIH_IMM_ATOMIC_IMAX ] = "imm_atomic_imax", - [VKD3DSIH_IMM_ATOMIC_IMIN ] = "imm_atomic_imin", - [VKD3DSIH_IMM_ATOMIC_OR ] = "imm_atomic_or", - [VKD3DSIH_IMM_ATOMIC_UMAX ] = "imm_atomic_umax", - [VKD3DSIH_IMM_ATOMIC_UMIN ] = "imm_atomic_umin", - [VKD3DSIH_IMM_ATOMIC_XOR ] = "imm_atomic_xor", - [VKD3DSIH_IMUL ] = "imul", - [VKD3DSIH_INE ] = "ine", - [VKD3DSIH_INEG ] = "ineg", - [VKD3DSIH_ISFINITE ] = "isfinite", - [VKD3DSIH_ISHL ] = "ishl", - [VKD3DSIH_ISHR ] = "ishr", - [VKD3DSIH_ISINF ] = "isinf", - [VKD3DSIH_ISNAN ] = "isnan", - [VKD3DSIH_ITOD ] = "itod", - [VKD3DSIH_ITOF ] = "itof", - [VKD3DSIH_ITOI ] = "itoi", - [VKD3DSIH_LABEL ] = "label", - [VKD3DSIH_LD ] = "ld", - [VKD3DSIH_LD2DMS ] = "ld2dms", - [VKD3DSIH_LD2DMS_S ] = "ld2dms_s", - [VKD3DSIH_LD_RAW ] = "ld_raw", - [VKD3DSIH_LD_RAW_S ] = "ld_raw_s", - [VKD3DSIH_LD_S ] = "ld_s", - [VKD3DSIH_LD_STRUCTURED ] = "ld_structured", - [VKD3DSIH_LD_STRUCTURED_S ] = "ld_structured_s", - [VKD3DSIH_LD_UAV_TYPED ] = "ld_uav_typed", - [VKD3DSIH_LD_UAV_TYPED_S ] = "ld_uav_typed_s", - [VKD3DSIH_LIT ] = "lit", - [VKD3DSIH_LOD ] = "lod", - [VKD3DSIH_LOG ] = "log", - [VKD3DSIH_LOGP ] = "logp", - [VKD3DSIH_LOOP ] = "loop", - [VKD3DSIH_LRP ] = "lrp", - [VKD3DSIH_LTO ] = "lt", - [VKD3DSIH_LTU ] = "lt_unord", - [VKD3DSIH_M3x2 ] = "m3x2", - [VKD3DSIH_M3x3 ] = "m3x3", - [VKD3DSIH_M3x4 ] = "m3x4", - [VKD3DSIH_M4x3 ] = "m4x3", - [VKD3DSIH_M4x4 ] = "m4x4", - [VKD3DSIH_MAD ] = "mad", - [VKD3DSIH_MAX ] = "max", - [VKD3DSIH_MIN ] = "min", - [VKD3DSIH_MOV ] = "mov", - [VKD3DSIH_MOVA ] = "mova", - [VKD3DSIH_MOVC ] = "movc", - [VKD3DSIH_MSAD ] = "msad", - [VKD3DSIH_MUL ] = "mul", - [VKD3DSIH_NEO ] = "ne_ord", - [VKD3DSIH_NEU ] = "ne", - [VKD3DSIH_NOP ] = "nop", - [VKD3DSIH_NOT ] = "not", - [VKD3DSIH_NRM ] = "nrm", - [VKD3DSIH_OR ] = "or", - [VKD3DSIH_ORD ] = "ord", - [VKD3DSIH_PHASE ] = "phase", - [VKD3DSIH_PHI ] = "phi", - [VKD3DSIH_POW ] = "pow", - [VKD3DSIH_QUAD_READ_ACROSS_D ] = "quad_read_across_d", - [VKD3DSIH_QUAD_READ_ACROSS_X ] = "quad_read_across_x", - [VKD3DSIH_QUAD_READ_ACROSS_Y ] = "quad_read_across_y", - [VKD3DSIH_QUAD_READ_LANE_AT ] = "quad_read_lane_at", - [VKD3DSIH_RCP ] = "rcp", - [VKD3DSIH_REP ] = "rep", - [VKD3DSIH_RESINFO ] = "resinfo", - [VKD3DSIH_RET ] = "ret", - [VKD3DSIH_RETP ] = "retp", - [VKD3DSIH_ROUND_NE ] = "round_ne", - [VKD3DSIH_ROUND_NI ] = "round_ni", - [VKD3DSIH_ROUND_PI ] = "round_pi", - [VKD3DSIH_ROUND_Z ] = "round_z", - [VKD3DSIH_RSQ ] = "rsq", - [VKD3DSIH_SAMPLE ] = "sample", - [VKD3DSIH_SAMPLE_B ] = "sample_b", - [VKD3DSIH_SAMPLE_B_CL_S ] = "sample_b_cl_s", - [VKD3DSIH_SAMPLE_C ] = "sample_c", - [VKD3DSIH_SAMPLE_C_CL_S ] = "sample_c_cl_s", - [VKD3DSIH_SAMPLE_C_LZ ] = "sample_c_lz", - [VKD3DSIH_SAMPLE_C_LZ_S ] = "sample_c_lz_s", - [VKD3DSIH_SAMPLE_CL_S ] = "sample_cl_s", - [VKD3DSIH_SAMPLE_GRAD ] = "sample_d", - [VKD3DSIH_SAMPLE_GRAD_CL_S ] = "sample_d_cl_s", - [VKD3DSIH_SAMPLE_INFO ] = "sample_info", - [VKD3DSIH_SAMPLE_LOD ] = "sample_l", - [VKD3DSIH_SAMPLE_LOD_S ] = "sample_l_s", - [VKD3DSIH_SAMPLE_POS ] = "sample_pos", - [VKD3DSIH_SETP ] = "setp", - [VKD3DSIH_SGE ] = "sge", - [VKD3DSIH_SGN ] = "sgn", - [VKD3DSIH_SINCOS ] = "sincos", - [VKD3DSIH_SLT ] = "slt", - [VKD3DSIH_SQRT ] = "sqrt", - [VKD3DSIH_STORE_RAW ] = "store_raw", - [VKD3DSIH_STORE_STRUCTURED ] = "store_structured", - [VKD3DSIH_STORE_UAV_TYPED ] = "store_uav_typed", - [VKD3DSIH_SUB ] = "sub", - [VKD3DSIH_SWAPC ] = "swapc", - [VKD3DSIH_SWITCH ] = "switch", - [VKD3DSIH_SWITCH_MONOLITHIC ] = "switch", - [VKD3DSIH_SYNC ] = "sync", - [VKD3DSIH_TAN ] = "tan", - [VKD3DSIH_TEX ] = "tex", - [VKD3DSIH_TEXBEM ] = "texbem", - [VKD3DSIH_TEXBEML ] = "texbeml", - [VKD3DSIH_TEXCOORD ] = "texcoord", - [VKD3DSIH_TEXCRD ] = "texcrd", - [VKD3DSIH_TEXDEPTH ] = "texdepth", - [VKD3DSIH_TEXDP3 ] = "texdp3", - [VKD3DSIH_TEXDP3TEX ] = "texdp3tex", - [VKD3DSIH_TEXKILL ] = "texkill", - [VKD3DSIH_TEXLD ] = "texld", - [VKD3DSIH_TEXLDD ] = "texldd", - [VKD3DSIH_TEXLDL ] = "texldl", - [VKD3DSIH_TEXM3x2DEPTH ] = "texm3x2depth", - [VKD3DSIH_TEXM3x2PAD ] = "texm3x2pad", - [VKD3DSIH_TEXM3x2TEX ] = "texm3x2tex", - [VKD3DSIH_TEXM3x3 ] = "texm3x3", - [VKD3DSIH_TEXM3x3DIFF ] = "texm3x3diff", - [VKD3DSIH_TEXM3x3PAD ] = "texm3x3pad", - [VKD3DSIH_TEXM3x3SPEC ] = "texm3x3spec", - [VKD3DSIH_TEXM3x3TEX ] = "texm3x3tex", - [VKD3DSIH_TEXM3x3VSPEC ] = "texm3x3vspec", - [VKD3DSIH_TEXREG2AR ] = "texreg2ar", - [VKD3DSIH_TEXREG2GB ] = "texreg2gb", - [VKD3DSIH_TEXREG2RGB ] = "texreg2rgb", - [VKD3DSIH_UBFE ] = "ubfe", - [VKD3DSIH_UDIV ] = "udiv", - [VKD3DSIH_UGE ] = "uge", - [VKD3DSIH_ULT ] = "ult", - [VKD3DSIH_UMAX ] = "umax", - [VKD3DSIH_UMIN ] = "umin", - [VKD3DSIH_UMUL ] = "umul", - [VKD3DSIH_UNO ] = "uno", - [VKD3DSIH_USHR ] = "ushr", - [VKD3DSIH_UTOD ] = "utod", - [VKD3DSIH_UTOF ] = "utof", - [VKD3DSIH_UTOU ] = "utou", - [VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL ] = "wave_active_all_equal", - [VKD3DSIH_WAVE_ACTIVE_BALLOT ] = "wave_active_ballot", - [VKD3DSIH_WAVE_ACTIVE_BIT_AND ] = "wave_active_bit_and", - [VKD3DSIH_WAVE_ACTIVE_BIT_OR ] = "wave_active_bit_or", - [VKD3DSIH_WAVE_ACTIVE_BIT_XOR ] = "wave_active_bit_xor", - [VKD3DSIH_WAVE_ALL_BIT_COUNT ] = "wave_all_bit_count", - [VKD3DSIH_WAVE_ALL_TRUE ] = "wave_all_true", - [VKD3DSIH_WAVE_ANY_TRUE ] = "wave_any_true", - [VKD3DSIH_WAVE_IS_FIRST_LANE ] = "wave_is_first_lane", - [VKD3DSIH_WAVE_OP_ADD ] = "wave_op_add", - [VKD3DSIH_WAVE_OP_IMAX ] = "wave_op_imax", - [VKD3DSIH_WAVE_OP_IMIN ] = "wave_op_imin", - [VKD3DSIH_WAVE_OP_MAX ] = "wave_op_max", - [VKD3DSIH_WAVE_OP_MIN ] = "wave_op_min", - [VKD3DSIH_WAVE_OP_MUL ] = "wave_op_mul", - [VKD3DSIH_WAVE_OP_UMAX ] = "wave_op_umax", - [VKD3DSIH_WAVE_OP_UMIN ] = "wave_op_umin", - [VKD3DSIH_WAVE_PREFIX_BIT_COUNT ] = "wave_prefix_bit_count", - [VKD3DSIH_WAVE_READ_LANE_AT ] = "wave_read_lane_at", - [VKD3DSIH_WAVE_READ_LANE_FIRST ] = "wave_read_lane_first", - [VKD3DSIH_XOR ] = "xor", -}; - static const char * const shader_register_names[] = { [VKD3DSPR_ADDR ] = "a", @@ -1750,7 +1420,7 @@ static void shader_dump_register_space(struct vkd3d_d3d_asm_compiler *compiler, static void shader_print_opcode(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_shader_opcode opcode) { vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%s", compiler->colours.opcode, - shader_opcode_names[opcode], compiler->colours.reset); + vsir_opcode_get_name(opcode, ""), compiler->colours.reset); } static void shader_dump_icb(struct vkd3d_d3d_asm_compiler *compiler, diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c index 05f46e264b9..c8291afcf6e 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -1681,7 +1681,8 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir_ if (!(info = shader_sm1_get_opcode_info_from_vsir(d3dbc, ins->opcode))) { vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE, - "Opcode %#x not supported for shader profile.", ins->opcode); + "Instruction \"%s\" (%#x) is not supported for the current target.", + vsir_opcode_get_name(ins->opcode, ""), ins->opcode); d3dbc->failed = true; return NULL; } @@ -1689,16 +1690,16 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir_ if (ins->dst_count != info->dst_count) { vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_COUNT, - "Invalid destination count %u for vsir instruction %#x (expected %u).", - ins->dst_count, ins->opcode, info->dst_count); + "Invalid destination parameter count %u for instruction \"%s\" (%#x); expected %u.", + ins->dst_count, vsir_opcode_get_name(ins->opcode, ""), ins->opcode, info->dst_count); d3dbc->failed = true; return NULL; } if (ins->src_count != info->src_count) { vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_COUNT, - "Invalid source count %u for vsir instruction %#x (expected %u).", - ins->src_count, ins->opcode, info->src_count); + "Invalid source parameter count %u for instruction \"%s\" (%#x); expected %u.", + ins->src_count, vsir_opcode_get_name(ins->opcode, ""), ins->opcode, info->src_count); d3dbc->failed = true; return NULL; } @@ -2029,8 +2030,8 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str { vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_WRITEMASK, - "writemask %#x for vsir instruction with opcode %#x is not single component.", - writemask, ins->opcode); + "Writemask %#x for instruction \"%s\" (%#x) is not single component.", + writemask, vsir_opcode_get_name(ins->opcode, ""), ins->opcode); d3dbc->failed = true; } d3dbc_write_instruction(d3dbc, ins); @@ -2038,7 +2039,8 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str default: vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE, - "vsir instruction with opcode %#x.", ins->opcode); + "Internal compiler error: Unhandled instruction \"%s\" (%#x).", + vsir_opcode_get_name(ins->opcode, ""), ins->opcode); d3dbc->failed = true; break; } diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c index 8c71176fb0b..1cbef387260 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c @@ -722,7 +722,6 @@ struct sm6_value struct sm6_groupsharedmem_data groupsharedmem; struct sm6_constant_data constant; } u; - struct vkd3d_shader_register reg; }; struct dxil_record @@ -2225,35 +2224,6 @@ static const char *sm6_parser_get_global_symbol_name(const struct sm6_parser *sm return NULL; } -static unsigned int register_get_uint_value(const struct vkd3d_shader_register *reg) -{ - if (!register_is_constant(reg) || (!data_type_is_integer(reg->data_type) && !data_type_is_bool(reg->data_type))) - return UINT_MAX; - - if (reg->dimension == VSIR_DIMENSION_VEC4) - WARN("Returning vec4.x.\n"); - - if (reg->type == VKD3DSPR_IMMCONST64) - { - if (reg->u.immconst_u64[0] > UINT_MAX) - FIXME("Truncating 64-bit value.\n"); - return reg->u.immconst_u64[0]; - } - - return reg->u.immconst_u32[0]; -} - -static uint64_t register_get_uint64_value(const struct vkd3d_shader_register *reg) -{ - if (!register_is_constant(reg) || !data_type_is_integer(reg->data_type)) - return UINT64_MAX; - - if (reg->dimension == VSIR_DIMENSION_VEC4) - WARN("Returning vec4.x.\n"); - - return (reg->type == VKD3DSPR_IMMCONST64) ? reg->u.immconst_u64[0] : reg->u.immconst_u32[0]; -} - static inline bool sm6_value_is_function_dcl(const struct sm6_value *value) { return value->value_type == VALUE_TYPE_FUNCTION; @@ -2296,18 +2266,31 @@ static bool sm6_value_is_handle(const struct sm6_value *value) static inline bool sm6_value_is_constant(const struct sm6_value *value) { - return sm6_value_is_register(value) && register_is_constant(&value->reg); + return value->value_type == VALUE_TYPE_CONSTANT; } static bool sm6_value_is_constant_zero(const struct sm6_value *value) { - /* Constant vectors do not occur. */ - return sm6_value_is_register(value) && register_is_scalar_constant_zero(&value->reg); + if (value->value_type != VALUE_TYPE_CONSTANT || value->type->class != TYPE_CLASS_INTEGER) + return false; + + if (value->type->u.width == 64) + return value->u.constant.immconst.immconst_u64[0] == 0; + else + return value->u.constant.immconst.immconst_u32[0] == 0; } static inline bool sm6_value_is_undef(const struct sm6_value *value) { - return sm6_value_is_register(value) && value->reg.type == VKD3DSPR_UNDEF; + switch (value->value_type) + { + case VALUE_TYPE_UNDEFINED: + case VALUE_TYPE_INVALID: + return true; + + default: + return false; + } } static bool sm6_value_vector_is_constant_or_undef(const struct sm6_value **values, unsigned int count) @@ -2326,7 +2309,7 @@ static bool sm6_value_is_data(const struct sm6_value *value) static bool sm6_value_is_ssa(const struct sm6_value *value) { - return sm6_value_is_register(value) && register_is_ssa(&value->reg); + return value->value_type == VALUE_TYPE_SSA; } static bool sm6_value_is_numeric_array(const struct sm6_value *value) @@ -2343,18 +2326,81 @@ static bool sm6_value_is_numeric_array(const struct sm6_value *value) } } -static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *value) +static unsigned int sm6_value_get_constant_uint(const struct sm6_value *value, struct sm6_parser *sm6) { if (!sm6_value_is_constant(value)) + { + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "Invalid non-constant value."); return UINT_MAX; - return register_get_uint_value(&value->reg); + } + + if (value->type->class != TYPE_CLASS_INTEGER) + { + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "Invalid non-integer constant value."); + return UINT_MAX; + } + + if (value->type->u.width == 64) + { + uint64_t val = value->u.constant.immconst.immconst_u64[0]; + if (val > UINT_MAX) + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "Invalid 64-bit constant %"PRIu64" will be truncated do %u.", val, (unsigned int)val); + return val; + } + + return value->u.constant.immconst.immconst_u32[0]; } -static uint64_t sm6_value_get_constant_uint64(const struct sm6_value *value) +static uint64_t sm6_value_get_constant_uint64(const struct sm6_value *value, struct sm6_parser *sm6) { if (!sm6_value_is_constant(value)) + { + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "Invalid non-constant value."); return UINT64_MAX; - return register_get_uint64_value(&value->reg); + } + + if (value->type->class != TYPE_CLASS_INTEGER) + { + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "Invalid non-integer constant value."); + return UINT64_MAX; + } + + if (value->type->u.width == 64) + return value->u.constant.immconst.immconst_u64[0]; + else + return value->u.constant.immconst.immconst_u32[0]; +} + +static float sm6_value_get_constant_float(const struct sm6_value *value, struct sm6_parser *sm6) +{ + if (!sm6_value_is_constant(value)) + { + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "Invalid non-constant value."); + return 0.0f; + } + + if (value->type->class != TYPE_CLASS_FLOAT) + { + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "Invalid non-floating-point constant value."); + return 0.0f; + } + + if (value->type->u.width == 64) + { + double val = value->u.constant.immconst.immconst_f64[0]; + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "Invalid double constant %lf will be truncated do float %f.", val, (float)val); + return val; + } + + return value->u.constant.immconst.immconst_f32[0]; } static unsigned int sm6_parser_alloc_ssa_id(struct sm6_parser *sm6) @@ -2517,9 +2563,9 @@ static void sm6_parser_init_ssa_value(struct sm6_parser *sm6, struct sm6_value * { unsigned int id; - if (register_is_ssa(&value->reg) && value->reg.idx[0].offset) + if (value->value_type == VALUE_TYPE_SSA && value->u.ssa.id) { - id = value->reg.idx[0].offset; + id = value->u.ssa.id; TRACE("Using forward-allocated id %u.\n", id); } else @@ -2529,7 +2575,6 @@ static void sm6_parser_init_ssa_value(struct sm6_parser *sm6, struct sm6_value * value->value_type = VALUE_TYPE_SSA; value->u.ssa.id = id; - sm6_register_from_value(&value->reg, value, sm6); } static void register_make_constant_uint(struct vkd3d_shader_register *reg, unsigned int value) @@ -2612,7 +2657,7 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, { if (address && sm6_value_is_constant(address)) { - idx->offset = sm6_value_get_constant_uint(address); + idx->offset = sm6_value_get_constant_uint(address, sm6); idx->rel_addr = NULL; } else if (!address || sm6_value_is_undef(address)) @@ -2966,7 +3011,6 @@ static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const stru value->type = fwd_type; value->value_type = VALUE_TYPE_SSA; value->u.ssa.id = sm6_parser_alloc_ssa_id(sm6); - sm6_register_from_value(&value->reg, value, sm6); } } @@ -3055,23 +3099,6 @@ static inline uint64_t decode_rotated_signed_value(uint64_t value) return value << 63; } -static float register_get_float_value(const struct vkd3d_shader_register *reg) -{ - if (!register_is_constant(reg) || !data_type_is_floating_point(reg->data_type)) - return 0.0; - - if (reg->dimension == VSIR_DIMENSION_VEC4) - WARN("Returning vec4.x.\n"); - - if (reg->type == VKD3DSPR_IMMCONST64) - { - WARN("Truncating double to float.\n"); - return reg->u.immconst_f64[0]; - } - - return reg->u.immconst_f32[0]; -} - static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, const struct sm6_type *type, const uint64_t *operands, struct sm6_parser *sm6) { @@ -3262,7 +3289,7 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c "Explicit pointee type for constexpr GEP does not match the element type."); } - offset = sm6_value_get_constant_uint(operands[2]); + offset = sm6_value_get_constant_uint(operands[2], sm6); if (!(gep_type = sm6_type_get_element_type_at_index(pointee_type, offset))) { WARN("Failed to get element type.\n"); @@ -3282,8 +3309,6 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c index->index = operands[2]; index->is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP; - sm6_register_from_value(&dst->reg, dst, sm6); - return VKD3D_OK; } @@ -3339,7 +3364,6 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const { dst->value_type = VALUE_TYPE_CONSTANT; memset(&dst->u.constant, 0, sizeof(dst->u.constant)); - sm6_register_from_value(&dst->reg, dst, sm6); } break; @@ -3361,8 +3385,6 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const else dst->u.constant.immconst.immconst_u64[0] = value; - sm6_register_from_value(&dst->reg, dst, sm6); - break; case CST_CODE_FLOAT: @@ -3383,8 +3405,6 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const else dst->u.constant.immconst.immconst_u64[0] = value; - sm6_register_from_value(&dst->reg, dst, sm6); - break; case CST_CODE_DATA: @@ -3418,14 +3438,12 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const case CST_CODE_UNDEF: dxil_record_validate_operand_max_count(record, 0, sm6); dst->value_type = VALUE_TYPE_UNDEFINED; - sm6_register_from_value(&dst->reg, dst, sm6); break; default: vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Constant code %u is unhandled.", record->code); dst->value_type = VALUE_TYPE_INVALID; - sm6_register_from_value(&dst->reg, dst, sm6); break; } @@ -3500,8 +3518,6 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const type = dst->type; *dst = *src; dst->type = type; - - sm6_register_from_value(&dst->reg, dst, sm6); break; } @@ -3580,7 +3596,6 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru dst->value_type = VALUE_TYPE_IDXTEMP; dst->u.idxtemp.id = ins->declaration.indexable_temp.register_idx; - sm6_register_from_value(&dst->reg, dst, sm6); } static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6_type *elem_type, @@ -3594,7 +3609,6 @@ static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6 dst->value_type = VALUE_TYPE_GROUPSHAREDMEM; dst->u.groupsharedmem.id = sm6->tgsm_count++; dst->structure_stride = 0; - sm6_register_from_value(&dst->reg, dst, sm6); sm6_register_from_value(&ins->declaration.tgsm_raw.reg.reg, dst, sm6); ins->declaration.tgsm_raw.alignment = alignment; byte_count = elem_type->u.width / 8u; @@ -3619,7 +3633,6 @@ static void sm6_parser_declare_tgsm_structured(struct sm6_parser *sm6, const str dst->value_type = VALUE_TYPE_GROUPSHAREDMEM; dst->u.groupsharedmem.id = sm6->tgsm_count++; dst->structure_stride = elem_type->u.width / 8u; - sm6_register_from_value(&dst->reg, dst, sm6); sm6_register_from_value(&ins->declaration.tgsm_structured.reg.reg, dst, sm6); if (dst->structure_stride != 4) { @@ -3933,7 +3946,6 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) value->u.icb.id = icb->register_idx; else value->u.icb.id = 0; - sm6_register_from_value(&value->reg, value, sm6); } return VKD3D_OK; @@ -4205,7 +4217,7 @@ static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_rec if (!(size = sm6_parser_get_value_safe(sm6, record->operands[2]))) return; /* A size of 1 means one instance of type[0], i.e. one array. */ - if (sm6_value_get_constant_uint(size) != 1) + if (sm6_value_get_constant_uint(size, sm6) != 1) { FIXME("Allocation size is not 1.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -4830,7 +4842,7 @@ static void sm6_parser_emit_dx_binary(struct sm6_parser *sm6, enum dx_intrinsic_ static enum vkd3d_shader_opcode map_dx_atomic_binop(const struct sm6_value *operand, struct sm6_parser *sm6) { - uint64_t code = sm6_value_get_constant_uint(operand); + uint64_t code = sm6_value_get_constant_uint(operand, sm6); switch (code) { @@ -4934,7 +4946,7 @@ static void sm6_parser_emit_dx_barrier(struct sm6_parser *sm6, enum dx_intrinsic enum dxil_sync_flags flags; vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SYNC); - flags = sm6_value_get_constant_uint(operands[0]); + flags = sm6_value_get_constant_uint(operands[0], sm6); ins->flags = flags & (SYNC_THREAD_GROUP | SYNC_THREAD_GROUP_UAV); if (flags & SYNC_GLOBAL_UAV) ins->flags |= VKD3DSSF_GLOBAL_UAV; @@ -4968,7 +4980,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu "A dynamic update value for a UAV counter operation is not supported."); return; } - i = sm6_value_get_constant_uint(operands[1]); + i = sm6_value_get_constant_uint(operands[1], sm6); if (i != 1 && i != 255) { WARN("Unexpected update value %#x.\n", i); @@ -5005,7 +5017,7 @@ static void sm6_parser_emit_dx_calculate_lod(struct sm6_parser *sm6, enum dx_int if (!sm6_parser_emit_coordinate_construct(sm6, &operands[2], 3, NULL, state, &coord)) return; - clamp = sm6_value_get_constant_uint(operands[5]); + clamp = sm6_value_get_constant_uint(operands[5], sm6); ins = state->ins; vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_LOD); @@ -5106,7 +5118,7 @@ static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_pa if (!sm6_value_is_constant(address)) return d; - register_index = sm6_value_get_constant_uint(address); + register_index = sm6_value_get_constant_uint(address, sm6); if (register_index >= d->range.first && register_index <= d->range.last) return d; } @@ -5123,8 +5135,8 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int struct sm6_value *dst; unsigned int id; - type = sm6_value_get_constant_uint(operands[0]); - id = sm6_value_get_constant_uint(operands[1]); + type = sm6_value_get_constant_uint(operands[0], sm6); + id = sm6_value_get_constant_uint(operands[1], sm6); if (!(d = sm6_parser_get_descriptor(sm6, type, id, operands[2]))) { WARN("Failed to find resource type %#x, id %#x.\n", type, id); @@ -5137,7 +5149,7 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int dst->value_type = VALUE_TYPE_HANDLE; dst->u.handle.d = d; dst->u.handle.index = operands[2]; - dst->u.handle.non_uniform = !!sm6_value_get_constant_uint(operands[3]); + dst->u.handle.non_uniform = !!sm6_value_get_constant_uint(operands[3], sm6); /* NOP is used to flag no instruction emitted. */ ins->opcode = VKD3DSIH_NOP; @@ -5155,7 +5167,7 @@ static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_ if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - i = sm6_value_get_constant_uint(operands[0]); + i = sm6_value_get_constant_uint(operands[0], sm6); if (i >= MAX_GS_OUTPUT_STREAMS) { WARN("Invalid stream index %u.\n", i); @@ -5196,7 +5208,7 @@ static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_i vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); - if ((component_idx = sm6_value_get_constant_uint(operands[0])) >= 3) + if ((component_idx = sm6_value_get_constant_uint(operands[0], sm6)) >= 3) { WARN("Invalid component index %u.\n", component_idx); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -5265,8 +5277,8 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri unsigned int row_index, column_index; const struct signature_element *e; - row_index = sm6_value_get_constant_uint(operands[0]); - column_index = sm6_value_get_constant_uint(operands[2]); + row_index = sm6_value_get_constant_uint(operands[0], sm6); + column_index = sm6_value_get_constant_uint(operands[2], sm6); signature = &sm6->p.program->input_signature; if (row_index >= signature->element_count) @@ -5353,7 +5365,7 @@ static void sm6_parser_emit_dx_compute_builtin(struct sm6_parser *sm6, enum dx_i if (component_count > 1) { src_param->reg.dimension = VSIR_DIMENSION_VEC4; - component_idx = sm6_value_get_constant_uint(operands[0]); + component_idx = sm6_value_get_constant_uint(operands[0], sm6); } src_param_init_scalar(src_param, component_idx); @@ -5508,8 +5520,8 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin const struct shader_signature *signature; const struct signature_element *e; - row_index = sm6_value_get_constant_uint(operands[0]); - column_index = sm6_value_get_constant_uint(operands[2]); + row_index = sm6_value_get_constant_uint(operands[0], sm6); + column_index = sm6_value_get_constant_uint(operands[2], sm6); if (is_control_point && operands[3]->value_type == VALUE_TYPE_UNDEFINED) { @@ -5618,7 +5630,7 @@ static void sm6_parser_emit_dx_quad_op(struct sm6_parser *sm6, enum dx_intrinsic enum vkd3d_shader_opcode opcode; enum dxil_quad_op_kind quad_op; - quad_op = sm6_value_get_constant_uint(operands[1]); + quad_op = sm6_value_get_constant_uint(operands[1], sm6); if ((opcode = dx_map_quad_op(quad_op)) == VKD3DSIH_INVALID) { FIXME("Unhandled quad op kind %u.\n", quad_op); @@ -5652,7 +5664,7 @@ static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_i if (op == DX_RAW_BUFFER_LOAD) { - write_mask = sm6_value_get_constant_uint(operands[3]); + write_mask = sm6_value_get_constant_uint(operands[3], sm6); if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) { WARN("Invalid write mask %#x.\n", write_mask); @@ -5695,7 +5707,7 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_ return; raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER; - write_mask = sm6_value_get_constant_uint(operands[7]); + write_mask = sm6_value_get_constant_uint(operands[7], sm6); if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) { WARN("Invalid write mask %#x.\n", write_mask); @@ -5721,7 +5733,7 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_ "Resource for a raw buffer store is not a raw or structured buffer."); } - alignment = sm6_value_get_constant_uint(operands[8]); + alignment = sm6_value_get_constant_uint(operands[8], sm6); if (alignment & (alignment - 1)) { FIXME("Invalid alignment %#x.\n", alignment); @@ -5818,7 +5830,7 @@ static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intr "Resource for a typed buffer store is not a typed buffer."); } - write_mask = sm6_value_get_constant_uint(operands[7]); + write_mask = sm6_value_get_constant_uint(operands[7], sm6); if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) { WARN("Invalid write mask %#x.\n", write_mask); @@ -5911,17 +5923,17 @@ static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_in instruction_dst_param_init_ssa_vector(ins, 2, sm6); } -static unsigned int sm6_value_get_texel_offset(const struct sm6_value *value) +static unsigned int sm6_value_get_texel_offset(const struct sm6_value *value, struct sm6_parser *sm6) { - return sm6_value_is_undef(value) ? 0 : sm6_value_get_constant_uint(value); + return sm6_value_is_undef(value) ? 0 : sm6_value_get_constant_uint(value, sm6); } static void instruction_set_texel_offset(struct vkd3d_shader_instruction *ins, const struct sm6_value **operands, struct sm6_parser *sm6) { - ins->texel_offset.u = sm6_value_get_texel_offset(operands[0]); - ins->texel_offset.v = sm6_value_get_texel_offset(operands[1]); - ins->texel_offset.w = sm6_value_get_texel_offset(operands[2]); + ins->texel_offset.u = sm6_value_get_texel_offset(operands[0], sm6); + ins->texel_offset.v = sm6_value_get_texel_offset(operands[1], sm6); + ins->texel_offset.w = sm6_value_get_texel_offset(operands[2], sm6); } static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, @@ -6102,8 +6114,8 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr const struct signature_element *e; const struct sm6_value *value; - row_index = sm6_value_get_constant_uint(operands[0]); - column_index = sm6_value_get_constant_uint(operands[2]); + row_index = sm6_value_get_constant_uint(operands[0], sm6); + column_index = sm6_value_get_constant_uint(operands[2], sm6); signature = is_patch_constant ? &program->patch_constant_signature : &program->output_signature; if (row_index >= signature->element_count) @@ -6203,7 +6215,7 @@ static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_in src_param_init_vector_from_handle(sm6, &src_params[1 + extended_offset], &resource->u.handle); src_param_init_vector_from_handle(sm6, &src_params[2 + extended_offset], &sampler->u.handle); /* Swizzle stored in the sampler parameter is the scalar component index to be gathered. */ - swizzle = sm6_value_get_constant_uint(operands[8]); + swizzle = sm6_value_get_constant_uint(operands[8], sm6); if (swizzle >= VKD3D_VEC4_SIZE) { WARN("Invalid swizzle %#x.\n", swizzle); @@ -6277,7 +6289,7 @@ static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_int if (!sm6_parser_emit_coordinate_construct(sm6, &operands[1], 3, NULL, state, &coord)) return; - write_mask = sm6_value_get_constant_uint(operands[8]); + write_mask = sm6_value_get_constant_uint(operands[8], sm6); if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) { WARN("Invalid write mask %#x.\n", write_mask); @@ -6351,7 +6363,7 @@ static void sm6_parser_emit_dx_wave_active_bit(struct sm6_parser *sm6, enum dx_i enum dxil_wave_bit_op_kind wave_op; enum vkd3d_shader_opcode opcode; - wave_op = sm6_value_get_constant_uint(operands[1]); + wave_op = sm6_value_get_constant_uint(operands[1], sm6); if ((opcode = sm6_dx_map_wave_bit_op(wave_op, sm6)) == VKD3DSIH_INVALID) return; @@ -6398,8 +6410,8 @@ static void sm6_parser_emit_dx_wave_op(struct sm6_parser *sm6, enum dx_intrinsic enum dxil_wave_op_kind wave_op; bool is_signed; - wave_op = sm6_value_get_constant_uint(operands[1]); - is_signed = !sm6_value_get_constant_uint(operands[2]); + wave_op = sm6_value_get_constant_uint(operands[1], sm6); + is_signed = !sm6_value_get_constant_uint(operands[2], sm6); opcode = sm6_dx_map_wave_op(wave_op, is_signed, sm6_type_is_floating_point(operands[0]->type), sm6); if (opcode == VKD3DSIH_INVALID) @@ -6687,7 +6699,6 @@ static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shade return; dst->value_type = VALUE_TYPE_INVALID; - sm6_register_from_value(&dst->reg, dst, sm6); } static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, @@ -6792,7 +6803,7 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor "Expected a constant integer dx intrinsic function id."); return; } - sm6_parser_decode_dx_op(sm6, sm6_value_get_constant_uint(op_value), + sm6_parser_decode_dx_op(sm6, sm6_value_get_constant_uint(op_value, sm6), fn_value->u.function.name, &operands[1], operand_count - 1, state, dst); } @@ -6947,7 +6958,6 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor { *dst = *value; dst->type = type; - sm6_register_from_value(&dst->reg, dst, sm6); return; } @@ -7298,7 +7308,7 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record return; /* The first index is always zero, to form a simple pointer dereference. */ - if (sm6_value_get_constant_uint(elem_value)) + if (sm6_value_get_constant_uint(elem_value, sm6)) { WARN("Expected constant zero.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -7318,7 +7328,7 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record return; /* If indexing is dynamic, just get the type at offset zero. */ - elem_idx = sm6_value_is_constant(elem_value) ? sm6_value_get_constant_uint(elem_value) : 0; + elem_idx = sm6_value_is_constant(elem_value) ? sm6_value_get_constant_uint(elem_value, sm6) : 0; type = sm6_type_get_element_type_at_index(pointee_type, elem_idx); if (!type) { @@ -7347,8 +7357,6 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record index->index = elem_value; index->is_in_bounds = record->operands[0]; - sm6_register_from_value(&dst->reg, dst, sm6); - ins->opcode = VKD3DSIH_NOP; } @@ -7698,7 +7706,7 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec "A switch case value is not a constant."); } - terminator->cases[i / 2u].value = sm6_value_get_constant_uint64(src); + terminator->cases[i / 2u].value = sm6_value_get_constant_uint64(src, sm6); } ins->opcode = VKD3DSIH_NOP; @@ -7761,7 +7769,7 @@ static bool sm6_metadata_value_is_zero_or_undef(const struct sm6_metadata_value && (sm6_value_is_undef(m->u.value) || sm6_value_is_constant_zero(m->u.value)); } -static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6, +static bool sm6_metadata_get_uint_value(struct sm6_parser *sm6, const struct sm6_metadata_value *m, unsigned int *u) { const struct sm6_value *value; @@ -7775,12 +7783,12 @@ static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6, if (!sm6_type_is_integer(value->type)) return false; - *u = sm6_value_get_constant_uint(value); + *u = sm6_value_get_constant_uint(value, sm6); return true; } -static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, +static bool sm6_metadata_get_uint64_value(struct sm6_parser *sm6, const struct sm6_metadata_value *m, uint64_t *u) { const struct sm6_value *value; @@ -7794,12 +7802,12 @@ static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, if (!sm6_type_is_integer(value->type)) return false; - *u = sm6_value_get_constant_uint(value); + *u = sm6_value_get_constant_uint(value, sm6); return true; } -static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6, +static bool sm6_metadata_get_float_value(struct sm6_parser *sm6, const struct sm6_metadata_value *m, float *f) { const struct sm6_value *value; @@ -7813,7 +7821,7 @@ static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6, if (!sm6_type_is_floating_point(value->type)) return false; - *f = register_get_float_value(&value->reg); + *f = sm6_value_get_constant_float(value, sm6); return true; } @@ -7999,7 +8007,6 @@ static void metadata_attachment_record_apply(const struct dxil_record *record, e else if (metadata_node_get_unary_uint(node, &operand, sm6)) { dst->non_uniform = !!operand; - sm6_register_from_value(&dst->reg, dst, sm6); } } else diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c index 90da8048b8e..9efaa0bc1fa 100644 --- a/libs/vkd3d/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d/libs/vkd3d-shader/fx.c @@ -289,15 +289,6 @@ static void set_status(struct fx_write_context *fx, int status) fx->status = status; } -static void fx_print_string(struct vkd3d_string_buffer *buffer, const char *prefix, - const char *s, size_t len) -{ - if (len) - --len; /* Trim terminating null. */ - vkd3d_string_buffer_printf(buffer, "%s", prefix); - vkd3d_string_buffer_print_string_escaped(buffer, s, len); -} - static uint32_t write_string(const char *string, struct fx_write_context *fx) { return fx->ops->write_string(string, fx); @@ -770,7 +761,7 @@ static const struct rhs_named_value fx_2_filter_values[] = { NULL } }; -static const struct fx_2_state +struct fx_2_state { const char *name; enum hlsl_type_class class; @@ -779,8 +770,9 @@ static const struct fx_2_state uint32_t array_size; uint32_t id; const struct rhs_named_value *values; -} -fx_2_states[] = +}; + +static const struct fx_2_state fx_2_pass_states[] = { { "ZEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 0, fx_2_zenable_values }, { "FillMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 1, fx_2_fillmode_values }, @@ -974,6 +966,23 @@ fx_2_states[] = { "ElementIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 176 }, }; +static const struct fx_2_state fx_2_sampler_states[] = +{ + { "Texture", HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 164 }, + { "AddressU", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 165, fx_2_address_values }, + { "AddressV", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 166, fx_2_address_values }, + { "AddressW", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 167, fx_2_address_values }, + { "BorderColor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 168 }, + { "MagFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 169, fx_2_filter_values }, + { "MinFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 170, fx_2_filter_values }, + { "MipFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 171, fx_2_filter_values }, + { "MipMapLodBias", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 172 }, + { "MaxMipLevel", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 173 }, + { "MaxAnisotropy", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 174 }, + { "SRGBTexture", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 175 }, + { "ElementIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 176 }, +}; + static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) { struct vkd3d_bytecode_buffer *buffer = &fx->structured; @@ -3648,20 +3657,43 @@ static void parse_fx_print_indent(struct fx_parser *parser) vkd3d_string_buffer_printf(&parser->buffer, "%*s", 4 * parser->indent, ""); } -static const char *fx_2_get_string(struct fx_parser *parser, uint32_t offset, uint32_t *size) +static void fx_2_print_string_literal(struct fx_parser *parser, const char *prefix, + const char *s, uint32_t max_len, const char *suffix) { - const char *ptr; + uint32_t len; + + if (s) + len = strnlen(s, max_len); + if (!s || len == max_len) + { + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, "Failed to parse a string entry."); + return; + } + + vkd3d_string_buffer_printf(&parser->buffer, "%s", prefix); + vkd3d_string_buffer_print_string_escaped(&parser->buffer, s, len); + vkd3d_string_buffer_printf(&parser->buffer, "%s", suffix); +} - fx_parser_read_unstructured(parser, size, offset, sizeof(*size)); - ptr = fx_parser_get_unstructured_ptr(parser, offset + 4, *size); +static void fx_2_parse_string_literal(struct fx_parser *parser, uint32_t offset, + bool unstructured, const char *prefix, const char *suffix) +{ + uint32_t max_len; + const char *s; - if (!ptr) + if (unstructured) { - parser->failed = true; - return ""; + fx_parser_read_unstructured(parser, &max_len, offset, sizeof(max_len)); + s = fx_parser_get_unstructured_ptr(parser, offset + 4, max_len); + } + else + { + max_len = fx_parser_read_u32(parser); + s = fx_parser_get_ptr(parser, max_len); + fx_parser_skip(parser, align(max_len, 4)); } - return ptr; + fx_2_print_string_literal(parser, prefix, s, max_len, suffix); } static unsigned int fx_get_fx_2_type_size(struct fx_parser *parser, uint32_t *offset) @@ -3818,15 +3850,12 @@ static void fx_parse_fx_2_parameter(struct fx_parser *parser, uint32_t offset) uint32_t semantic; uint32_t element_count; } var; - const char *name; - uint32_t size; fx_parser_read_unstructured(parser, &var, offset, sizeof(var)); fx_parse_fx_2_type(parser, offset); - name = fx_2_get_string(parser, var.name, &size); - fx_print_string(&parser->buffer, " ", name, size); + fx_2_parse_string_literal(parser, var.name, true, " ", ""); if (var.element_count) vkd3d_string_buffer_printf(&parser->buffer, "[%u]", var.element_count); } @@ -3840,7 +3869,8 @@ static bool is_fx_2_sampler(uint32_t type) || type == D3DXPT_SAMPLERCUBE; } -static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_assignment *entry); +static void fx_parse_fx_2_assignment(struct fx_parser *parser, enum hlsl_type_class container, + const struct fx_assignment *entry); static void parse_fx_2_sampler(struct fx_parser *parser, uint32_t element_count, uint32_t offset) @@ -3865,7 +3895,7 @@ static void parse_fx_2_sampler(struct fx_parser *parser, uint32_t element_count, fx_parser_read_unstructured(parser, &entry, offset, sizeof(entry)); parse_fx_print_indent(parser); - fx_parse_fx_2_assignment(parser, &entry); + fx_parse_fx_2_assignment(parser, HLSL_CLASS_SAMPLER, &entry); } parse_fx_end_indent(parser); parse_fx_print_indent(parser); @@ -3943,15 +3973,29 @@ static void fx_parse_fx_2_annotations(struct fx_parser *parser, uint32_t count) vkd3d_string_buffer_printf(&parser->buffer, ">"); } -static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_assignment *entry) +static const struct fx_2_state *fx_2_get_state_by_id(enum hlsl_type_class container, uint32_t id) +{ + const struct fx_2_state *table; + unsigned int count; + + count = container == HLSL_CLASS_PASS ? ARRAY_SIZE(fx_2_pass_states) : ARRAY_SIZE(fx_2_sampler_states); + table = container == HLSL_CLASS_PASS ? fx_2_pass_states : fx_2_sampler_states; + + /* State identifiers are sequential, no gaps */ + if (id >= table[0].id && id <= table[count - 1].id) + return &table[id - table[0].id]; + + return NULL; +} + +static void fx_parse_fx_2_assignment(struct fx_parser *parser, enum hlsl_type_class container, + const struct fx_assignment *entry) { const struct rhs_named_value *named_value = NULL; - const struct fx_2_state *state = NULL; + const struct fx_2_state *state; - if (entry->id <= ARRAY_SIZE(fx_2_states)) + if ((state = fx_2_get_state_by_id(container, entry->id))) { - state = &fx_2_states[entry->id]; - vkd3d_string_buffer_printf(&parser->buffer, "%s", state->name); if (state->array_size > 1) vkd3d_string_buffer_printf(&parser->buffer, "[%u]", entry->lhs_index); @@ -4028,18 +4072,14 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser) uint32_t annotation_count; uint32_t assignment_count; } pass; - const char *name; - uint32_t size; if (parser->failed) return; fx_parser_read_u32s(parser, &technique, sizeof(technique)); - name = fx_2_get_string(parser, technique.name, &size); - parse_fx_print_indent(parser); - fx_print_string(&parser->buffer, "technique ", name, size); + fx_2_parse_string_literal(parser, technique.name, true, "technique ", ""); fx_parse_fx_2_annotations(parser, technique.annotation_count); vkd3d_string_buffer_printf(&parser->buffer, "\n"); @@ -4050,10 +4090,9 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser) for (uint32_t i = 0; i < technique.pass_count; ++i) { fx_parser_read_u32s(parser, &pass, sizeof(pass)); - name = fx_2_get_string(parser, pass.name, &size); parse_fx_print_indent(parser); - fx_print_string(&parser->buffer, "pass ", name, size); + fx_2_parse_string_literal(parser, pass.name, true, "pass ", ""); fx_parse_fx_2_annotations(parser, pass.annotation_count); vkd3d_string_buffer_printf(&parser->buffer, "\n"); @@ -4067,7 +4106,7 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser) parse_fx_print_indent(parser); fx_parser_read_u32s(parser, &entry, sizeof(entry)); - fx_parse_fx_2_assignment(parser, &entry); + fx_parse_fx_2_assignment(parser, HLSL_CLASS_PASS, &entry); } parse_fx_end_indent(parser); @@ -4189,8 +4228,7 @@ static void fx_parse_fx_2_data_blob(struct fx_parser *parser) { parse_fx_start_indent(parser); parse_fx_print_indent(parser); - fx_print_string(&parser->buffer, "\"", (const char *)data, size); - vkd3d_string_buffer_printf(&parser->buffer, "\""); + fx_2_print_string_literal(parser, "\"", (const char *)data, size, "\""); parse_fx_end_indent(parser); } else if (type == D3DXPT_PIXELSHADER || type == D3DXPT_VERTEXSHADER) @@ -4230,20 +4268,16 @@ static void fx_dump_blob(struct fx_parser *parser, const void *blob, uint32_t si } } -static void fx_parse_fx_2_array_selector(struct fx_parser *parser, uint32_t size) +static void fx_parse_fx_2_array_selector(struct fx_parser *parser) { - const uint8_t *end = parser->ptr + size; - uint32_t name_size, blob_size = 0; + uint32_t size, blob_size = 0; const void *blob = NULL; - const char *name; + const uint8_t *end; - name_size = fx_parser_read_u32(parser); - name = fx_parser_get_ptr(parser, name_size); - fx_parser_skip(parser, name_size); + size = fx_parser_read_u32(parser); + end = parser->ptr + size; - if (!name || (uint8_t *)name >= end) - fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, - "Malformed name entry in the array selector."); + fx_2_parse_string_literal(parser, 0, false, "array \"", "\"\n"); if (parser->ptr <= end) { @@ -4257,11 +4291,6 @@ static void fx_parse_fx_2_array_selector(struct fx_parser *parser, uint32_t size "Malformed blob entry in the array selector."); } - if (name) - { - fx_print_string(&parser->buffer, "array \"", name, name_size); - vkd3d_string_buffer_printf(&parser->buffer, "\"\n"); - } if (blob) { parse_fx_print_indent(parser); @@ -4296,23 +4325,19 @@ static void fx_parse_fx_2_complex_state(struct fx_parser *parser) state.technique, state.index, state.state); } - size = fx_parser_read_u32(parser); - parse_fx_print_indent(parser); if (state.assignment_type == FX_2_ASSIGNMENT_PARAMETER) { - data = fx_parser_get_ptr(parser, size); - fx_print_string(&parser->buffer, "parameter \"", data, size); - vkd3d_string_buffer_printf(&parser->buffer, "\"\n"); - fx_parser_skip(parser, align(size, 4)); + fx_2_parse_string_literal(parser, 0, false, "parameter \"", "\"\n"); } else if (state.assignment_type == FX_2_ASSIGNMENT_ARRAY_SELECTOR) { - fx_parse_fx_2_array_selector(parser, size); + fx_parse_fx_2_array_selector(parser); } else { + size = fx_parser_read_u32(parser); vkd3d_string_buffer_printf(&parser->buffer, "blob size %u\n", size); data = fx_parser_get_ptr(parser, size); fx_dump_blob(parser, data, size); @@ -4718,6 +4743,8 @@ fx_4_fxlc_opcodes[] = { 0x13a, "ceil" }, { 0x200, "min" }, { 0x201, "max" }, + { 0x202, "lt" }, + { 0x203, "ge" }, { 0x204, "add" }, { 0x205, "mul" }, { 0x206, "atan2" }, diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c index 0a91024a8d1..214632c00eb 100644 --- a/libs/vkd3d/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c @@ -561,10 +561,12 @@ static void VKD3D_PRINTF_FUNC(4, 5) shader_glsl_print_assignment_ext(struct vkd3 static void shader_glsl_unhandled(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) { + const char *name = vsir_opcode_get_name(ins->opcode, ""); + shader_glsl_print_indent(gen->buffer, gen->indent); - vkd3d_string_buffer_printf(gen->buffer, "/* */\n", ins->opcode); + vkd3d_string_buffer_printf(gen->buffer, "/* */\n", name, ins->opcode); vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled instruction %#x.", ins->opcode); + "Internal compiler error: Unhandled instruction \"%s\" (%#x).", name, ins->opcode); } static void shader_glsl_binop(struct vkd3d_glsl_generator *gen, diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c index 4abf6a65dbb..1925e20c685 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -29,6 +29,344 @@ struct vsir_transformation_context struct vkd3d_shader_message_context *message_context; }; +const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) +{ + static const char * const names[] = + { + [VKD3DSIH_ABS ] = "abs", + [VKD3DSIH_ACOS ] = "acos", + [VKD3DSIH_ADD ] = "add", + [VKD3DSIH_AND ] = "and", + [VKD3DSIH_ASIN ] = "asin", + [VKD3DSIH_ATAN ] = "atan", + [VKD3DSIH_ATOMIC_AND ] = "atomic_and", + [VKD3DSIH_ATOMIC_CMP_STORE ] = "atomic_cmp_store", + [VKD3DSIH_ATOMIC_IADD ] = "atomic_iadd", + [VKD3DSIH_ATOMIC_IMAX ] = "atomic_imax", + [VKD3DSIH_ATOMIC_IMIN ] = "atomic_imin", + [VKD3DSIH_ATOMIC_OR ] = "atomic_or", + [VKD3DSIH_ATOMIC_UMAX ] = "atomic_umax", + [VKD3DSIH_ATOMIC_UMIN ] = "atomic_umin", + [VKD3DSIH_ATOMIC_XOR ] = "atomic_xor", + [VKD3DSIH_BEM ] = "bem", + [VKD3DSIH_BFI ] = "bfi", + [VKD3DSIH_BFREV ] = "bfrev", + [VKD3DSIH_BRANCH ] = "branch", + [VKD3DSIH_BREAK ] = "break", + [VKD3DSIH_BREAKC ] = "break", + [VKD3DSIH_BREAKP ] = "breakp", + [VKD3DSIH_BUFINFO ] = "bufinfo", + [VKD3DSIH_CALL ] = "call", + [VKD3DSIH_CALLNZ ] = "callnz", + [VKD3DSIH_CASE ] = "case", + [VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED ] = "check_access_fully_mapped", + [VKD3DSIH_CMP ] = "cmp", + [VKD3DSIH_CND ] = "cnd", + [VKD3DSIH_CONTINUE ] = "continue", + [VKD3DSIH_CONTINUEP ] = "continuec", + [VKD3DSIH_COUNTBITS ] = "countbits", + [VKD3DSIH_CRS ] = "crs", + [VKD3DSIH_CUT ] = "cut", + [VKD3DSIH_CUT_STREAM ] = "cut_stream", + [VKD3DSIH_DADD ] = "dadd", + [VKD3DSIH_DCL ] = "dcl", + [VKD3DSIH_DCL_CONSTANT_BUFFER ] = "dcl_constantBuffer", + [VKD3DSIH_DCL_FUNCTION_BODY ] = "dcl_function_body", + [VKD3DSIH_DCL_FUNCTION_TABLE ] = "dcl_function_table", + [VKD3DSIH_DCL_GLOBAL_FLAGS ] = "dcl_globalFlags", + [VKD3DSIH_DCL_GS_INSTANCES ] = "dcl_gs_instances", + [VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT] = "dcl_hs_fork_phase_instance_count", + [VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT] = "dcl_hs_join_phase_instance_count", + [VKD3DSIH_DCL_HS_MAX_TESSFACTOR ] = "dcl_hs_max_tessfactor", + [VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER ] = "dcl_immediateConstantBuffer", + [VKD3DSIH_DCL_INDEX_RANGE ] = "dcl_index_range", + [VKD3DSIH_DCL_INDEXABLE_TEMP ] = "dcl_indexableTemp", + [VKD3DSIH_DCL_INPUT ] = "dcl_input", + [VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT ] = "dcl_input_control_point_count", + [VKD3DSIH_DCL_INPUT_PRIMITIVE ] = "dcl_inputprimitive", + [VKD3DSIH_DCL_INPUT_PS ] = "dcl_input_ps", + [VKD3DSIH_DCL_INPUT_PS_SGV ] = "dcl_input_ps_sgv", + [VKD3DSIH_DCL_INPUT_PS_SIV ] = "dcl_input_ps_siv", + [VKD3DSIH_DCL_INPUT_SGV ] = "dcl_input_sgv", + [VKD3DSIH_DCL_INPUT_SIV ] = "dcl_input_siv", + [VKD3DSIH_DCL_INTERFACE ] = "dcl_interface", + [VKD3DSIH_DCL_OUTPUT ] = "dcl_output", + [VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT ] = "dcl_output_control_point_count", + [VKD3DSIH_DCL_OUTPUT_SGV ] = "dcl_output_sgv", + [VKD3DSIH_DCL_OUTPUT_SIV ] = "dcl_output_siv", + [VKD3DSIH_DCL_OUTPUT_TOPOLOGY ] = "dcl_outputtopology", + [VKD3DSIH_DCL_RESOURCE_RAW ] = "dcl_resource_raw", + [VKD3DSIH_DCL_RESOURCE_STRUCTURED ] = "dcl_resource_structured", + [VKD3DSIH_DCL_SAMPLER ] = "dcl_sampler", + [VKD3DSIH_DCL_STREAM ] = "dcl_stream", + [VKD3DSIH_DCL_TEMPS ] = "dcl_temps", + [VKD3DSIH_DCL_TESSELLATOR_DOMAIN ] = "dcl_tessellator_domain", + [VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = "dcl_tessellator_output_primitive", + [VKD3DSIH_DCL_TESSELLATOR_PARTITIONING ] = "dcl_tessellator_partitioning", + [VKD3DSIH_DCL_TGSM_RAW ] = "dcl_tgsm_raw", + [VKD3DSIH_DCL_TGSM_STRUCTURED ] = "dcl_tgsm_structured", + [VKD3DSIH_DCL_THREAD_GROUP ] = "dcl_thread_group", + [VKD3DSIH_DCL_UAV_RAW ] = "dcl_uav_raw", + [VKD3DSIH_DCL_UAV_STRUCTURED ] = "dcl_uav_structured", + [VKD3DSIH_DCL_UAV_TYPED ] = "dcl_uav_typed", + [VKD3DSIH_DCL_VERTICES_OUT ] = "dcl_maxout", + [VKD3DSIH_DDIV ] = "ddiv", + [VKD3DSIH_DEF ] = "def", + [VKD3DSIH_DEFAULT ] = "default", + [VKD3DSIH_DEFB ] = "defb", + [VKD3DSIH_DEFI ] = "defi", + [VKD3DSIH_DEQO ] = "deq", + [VKD3DSIH_DFMA ] = "dfma", + [VKD3DSIH_DGEO ] = "dge", + [VKD3DSIH_DISCARD ] = "discard", + [VKD3DSIH_DIV ] = "div", + [VKD3DSIH_DLT ] = "dlt", + [VKD3DSIH_DMAX ] = "dmax", + [VKD3DSIH_DMIN ] = "dmin", + [VKD3DSIH_DMOV ] = "dmov", + [VKD3DSIH_DMOVC ] = "dmovc", + [VKD3DSIH_DMUL ] = "dmul", + [VKD3DSIH_DNE ] = "dne", + [VKD3DSIH_DP2 ] = "dp2", + [VKD3DSIH_DP2ADD ] = "dp2add", + [VKD3DSIH_DP3 ] = "dp3", + [VKD3DSIH_DP4 ] = "dp4", + [VKD3DSIH_DRCP ] = "drcp", + [VKD3DSIH_DST ] = "dst", + [VKD3DSIH_DSX ] = "dsx", + [VKD3DSIH_DSX_COARSE ] = "deriv_rtx_coarse", + [VKD3DSIH_DSX_FINE ] = "deriv_rtx_fine", + [VKD3DSIH_DSY ] = "dsy", + [VKD3DSIH_DSY_COARSE ] = "deriv_rty_coarse", + [VKD3DSIH_DSY_FINE ] = "deriv_rty_fine", + [VKD3DSIH_DTOF ] = "dtof", + [VKD3DSIH_DTOI ] = "dtoi", + [VKD3DSIH_DTOU ] = "dtou", + [VKD3DSIH_ELSE ] = "else", + [VKD3DSIH_EMIT ] = "emit", + [VKD3DSIH_EMIT_STREAM ] = "emit_stream", + [VKD3DSIH_ENDIF ] = "endif", + [VKD3DSIH_ENDLOOP ] = "endloop", + [VKD3DSIH_ENDREP ] = "endrep", + [VKD3DSIH_ENDSWITCH ] = "endswitch", + [VKD3DSIH_EQO ] = "eq", + [VKD3DSIH_EQU ] = "eq_unord", + [VKD3DSIH_EVAL_CENTROID ] = "eval_centroid", + [VKD3DSIH_EVAL_SAMPLE_INDEX ] = "eval_sample_index", + [VKD3DSIH_EXP ] = "exp", + [VKD3DSIH_EXPP ] = "expp", + [VKD3DSIH_F16TOF32 ] = "f16tof32", + [VKD3DSIH_F32TOF16 ] = "f32tof16", + [VKD3DSIH_FCALL ] = "fcall", + [VKD3DSIH_FIRSTBIT_HI ] = "firstbit_hi", + [VKD3DSIH_FIRSTBIT_LO ] = "firstbit_lo", + [VKD3DSIH_FIRSTBIT_SHI ] = "firstbit_shi", + [VKD3DSIH_FRC ] = "frc", + [VKD3DSIH_FREM ] = "frem", + [VKD3DSIH_FTOD ] = "ftod", + [VKD3DSIH_FTOI ] = "ftoi", + [VKD3DSIH_FTOU ] = "ftou", + [VKD3DSIH_GATHER4 ] = "gather4", + [VKD3DSIH_GATHER4_C ] = "gather4_c", + [VKD3DSIH_GATHER4_C_S ] = "gather4_c_s", + [VKD3DSIH_GATHER4_PO ] = "gather4_po", + [VKD3DSIH_GATHER4_PO_C ] = "gather4_po_c", + [VKD3DSIH_GATHER4_PO_C_S ] = "gather4_po_c_s", + [VKD3DSIH_GATHER4_PO_S ] = "gather4_po_s", + [VKD3DSIH_GATHER4_S ] = "gather4_s", + [VKD3DSIH_GEO ] = "ge", + [VKD3DSIH_GEU ] = "ge_unord", + [VKD3DSIH_HCOS ] = "hcos", + [VKD3DSIH_HS_CONTROL_POINT_PHASE ] = "hs_control_point_phase", + [VKD3DSIH_HS_DECLS ] = "hs_decls", + [VKD3DSIH_HS_FORK_PHASE ] = "hs_fork_phase", + [VKD3DSIH_HS_JOIN_PHASE ] = "hs_join_phase", + [VKD3DSIH_HSIN ] = "hsin", + [VKD3DSIH_HTAN ] = "htan", + [VKD3DSIH_IADD ] = "iadd", + [VKD3DSIH_IBFE ] = "ibfe", + [VKD3DSIH_IDIV ] = "idiv", + [VKD3DSIH_IEQ ] = "ieq", + [VKD3DSIH_IF ] = "if", + [VKD3DSIH_IFC ] = "if", + [VKD3DSIH_IGE ] = "ige", + [VKD3DSIH_ILT ] = "ilt", + [VKD3DSIH_IMAD ] = "imad", + [VKD3DSIH_IMAX ] = "imax", + [VKD3DSIH_IMIN ] = "imin", + [VKD3DSIH_IMM_ATOMIC_ALLOC ] = "imm_atomic_alloc", + [VKD3DSIH_IMM_ATOMIC_AND ] = "imm_atomic_and", + [VKD3DSIH_IMM_ATOMIC_CMP_EXCH ] = "imm_atomic_cmp_exch", + [VKD3DSIH_IMM_ATOMIC_CONSUME ] = "imm_atomic_consume", + [VKD3DSIH_IMM_ATOMIC_EXCH ] = "imm_atomic_exch", + [VKD3DSIH_IMM_ATOMIC_IADD ] = "imm_atomic_iadd", + [VKD3DSIH_IMM_ATOMIC_IMAX ] = "imm_atomic_imax", + [VKD3DSIH_IMM_ATOMIC_IMIN ] = "imm_atomic_imin", + [VKD3DSIH_IMM_ATOMIC_OR ] = "imm_atomic_or", + [VKD3DSIH_IMM_ATOMIC_UMAX ] = "imm_atomic_umax", + [VKD3DSIH_IMM_ATOMIC_UMIN ] = "imm_atomic_umin", + [VKD3DSIH_IMM_ATOMIC_XOR ] = "imm_atomic_xor", + [VKD3DSIH_IMUL ] = "imul", + [VKD3DSIH_INE ] = "ine", + [VKD3DSIH_INEG ] = "ineg", + [VKD3DSIH_ISFINITE ] = "isfinite", + [VKD3DSIH_ISHL ] = "ishl", + [VKD3DSIH_ISHR ] = "ishr", + [VKD3DSIH_ISINF ] = "isinf", + [VKD3DSIH_ISNAN ] = "isnan", + [VKD3DSIH_ITOD ] = "itod", + [VKD3DSIH_ITOF ] = "itof", + [VKD3DSIH_ITOI ] = "itoi", + [VKD3DSIH_LABEL ] = "label", + [VKD3DSIH_LD ] = "ld", + [VKD3DSIH_LD2DMS ] = "ld2dms", + [VKD3DSIH_LD2DMS_S ] = "ld2dms_s", + [VKD3DSIH_LD_RAW ] = "ld_raw", + [VKD3DSIH_LD_RAW_S ] = "ld_raw_s", + [VKD3DSIH_LD_S ] = "ld_s", + [VKD3DSIH_LD_STRUCTURED ] = "ld_structured", + [VKD3DSIH_LD_STRUCTURED_S ] = "ld_structured_s", + [VKD3DSIH_LD_UAV_TYPED ] = "ld_uav_typed", + [VKD3DSIH_LD_UAV_TYPED_S ] = "ld_uav_typed_s", + [VKD3DSIH_LIT ] = "lit", + [VKD3DSIH_LOD ] = "lod", + [VKD3DSIH_LOG ] = "log", + [VKD3DSIH_LOGP ] = "logp", + [VKD3DSIH_LOOP ] = "loop", + [VKD3DSIH_LRP ] = "lrp", + [VKD3DSIH_LTO ] = "lt", + [VKD3DSIH_LTU ] = "lt_unord", + [VKD3DSIH_M3x2 ] = "m3x2", + [VKD3DSIH_M3x3 ] = "m3x3", + [VKD3DSIH_M3x4 ] = "m3x4", + [VKD3DSIH_M4x3 ] = "m4x3", + [VKD3DSIH_M4x4 ] = "m4x4", + [VKD3DSIH_MAD ] = "mad", + [VKD3DSIH_MAX ] = "max", + [VKD3DSIH_MIN ] = "min", + [VKD3DSIH_MOV ] = "mov", + [VKD3DSIH_MOVA ] = "mova", + [VKD3DSIH_MOVC ] = "movc", + [VKD3DSIH_MSAD ] = "msad", + [VKD3DSIH_MUL ] = "mul", + [VKD3DSIH_NEO ] = "ne_ord", + [VKD3DSIH_NEU ] = "ne", + [VKD3DSIH_NOP ] = "nop", + [VKD3DSIH_NOT ] = "not", + [VKD3DSIH_NRM ] = "nrm", + [VKD3DSIH_OR ] = "or", + [VKD3DSIH_ORD ] = "ord", + [VKD3DSIH_PHASE ] = "phase", + [VKD3DSIH_PHI ] = "phi", + [VKD3DSIH_POW ] = "pow", + [VKD3DSIH_QUAD_READ_ACROSS_D ] = "quad_read_across_d", + [VKD3DSIH_QUAD_READ_ACROSS_X ] = "quad_read_across_x", + [VKD3DSIH_QUAD_READ_ACROSS_Y ] = "quad_read_across_y", + [VKD3DSIH_QUAD_READ_LANE_AT ] = "quad_read_lane_at", + [VKD3DSIH_RCP ] = "rcp", + [VKD3DSIH_REP ] = "rep", + [VKD3DSIH_RESINFO ] = "resinfo", + [VKD3DSIH_RET ] = "ret", + [VKD3DSIH_RETP ] = "retp", + [VKD3DSIH_ROUND_NE ] = "round_ne", + [VKD3DSIH_ROUND_NI ] = "round_ni", + [VKD3DSIH_ROUND_PI ] = "round_pi", + [VKD3DSIH_ROUND_Z ] = "round_z", + [VKD3DSIH_RSQ ] = "rsq", + [VKD3DSIH_SAMPLE ] = "sample", + [VKD3DSIH_SAMPLE_B ] = "sample_b", + [VKD3DSIH_SAMPLE_B_CL_S ] = "sample_b_cl_s", + [VKD3DSIH_SAMPLE_C ] = "sample_c", + [VKD3DSIH_SAMPLE_C_CL_S ] = "sample_c_cl_s", + [VKD3DSIH_SAMPLE_C_LZ ] = "sample_c_lz", + [VKD3DSIH_SAMPLE_C_LZ_S ] = "sample_c_lz_s", + [VKD3DSIH_SAMPLE_CL_S ] = "sample_cl_s", + [VKD3DSIH_SAMPLE_GRAD ] = "sample_d", + [VKD3DSIH_SAMPLE_GRAD_CL_S ] = "sample_d_cl_s", + [VKD3DSIH_SAMPLE_INFO ] = "sample_info", + [VKD3DSIH_SAMPLE_LOD ] = "sample_l", + [VKD3DSIH_SAMPLE_LOD_S ] = "sample_l_s", + [VKD3DSIH_SAMPLE_POS ] = "sample_pos", + [VKD3DSIH_SETP ] = "setp", + [VKD3DSIH_SGE ] = "sge", + [VKD3DSIH_SGN ] = "sgn", + [VKD3DSIH_SINCOS ] = "sincos", + [VKD3DSIH_SLT ] = "slt", + [VKD3DSIH_SQRT ] = "sqrt", + [VKD3DSIH_STORE_RAW ] = "store_raw", + [VKD3DSIH_STORE_STRUCTURED ] = "store_structured", + [VKD3DSIH_STORE_UAV_TYPED ] = "store_uav_typed", + [VKD3DSIH_SUB ] = "sub", + [VKD3DSIH_SWAPC ] = "swapc", + [VKD3DSIH_SWITCH ] = "switch", + [VKD3DSIH_SWITCH_MONOLITHIC ] = "switch", + [VKD3DSIH_SYNC ] = "sync", + [VKD3DSIH_TAN ] = "tan", + [VKD3DSIH_TEX ] = "tex", + [VKD3DSIH_TEXBEM ] = "texbem", + [VKD3DSIH_TEXBEML ] = "texbeml", + [VKD3DSIH_TEXCOORD ] = "texcoord", + [VKD3DSIH_TEXCRD ] = "texcrd", + [VKD3DSIH_TEXDEPTH ] = "texdepth", + [VKD3DSIH_TEXDP3 ] = "texdp3", + [VKD3DSIH_TEXDP3TEX ] = "texdp3tex", + [VKD3DSIH_TEXKILL ] = "texkill", + [VKD3DSIH_TEXLD ] = "texld", + [VKD3DSIH_TEXLDD ] = "texldd", + [VKD3DSIH_TEXLDL ] = "texldl", + [VKD3DSIH_TEXM3x2DEPTH ] = "texm3x2depth", + [VKD3DSIH_TEXM3x2PAD ] = "texm3x2pad", + [VKD3DSIH_TEXM3x2TEX ] = "texm3x2tex", + [VKD3DSIH_TEXM3x3 ] = "texm3x3", + [VKD3DSIH_TEXM3x3DIFF ] = "texm3x3diff", + [VKD3DSIH_TEXM3x3PAD ] = "texm3x3pad", + [VKD3DSIH_TEXM3x3SPEC ] = "texm3x3spec", + [VKD3DSIH_TEXM3x3TEX ] = "texm3x3tex", + [VKD3DSIH_TEXM3x3VSPEC ] = "texm3x3vspec", + [VKD3DSIH_TEXREG2AR ] = "texreg2ar", + [VKD3DSIH_TEXREG2GB ] = "texreg2gb", + [VKD3DSIH_TEXREG2RGB ] = "texreg2rgb", + [VKD3DSIH_UBFE ] = "ubfe", + [VKD3DSIH_UDIV ] = "udiv", + [VKD3DSIH_UGE ] = "uge", + [VKD3DSIH_ULT ] = "ult", + [VKD3DSIH_UMAX ] = "umax", + [VKD3DSIH_UMIN ] = "umin", + [VKD3DSIH_UMUL ] = "umul", + [VKD3DSIH_UNO ] = "uno", + [VKD3DSIH_USHR ] = "ushr", + [VKD3DSIH_UTOD ] = "utod", + [VKD3DSIH_UTOF ] = "utof", + [VKD3DSIH_UTOU ] = "utou", + [VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL ] = "wave_active_all_equal", + [VKD3DSIH_WAVE_ACTIVE_BALLOT ] = "wave_active_ballot", + [VKD3DSIH_WAVE_ACTIVE_BIT_AND ] = "wave_active_bit_and", + [VKD3DSIH_WAVE_ACTIVE_BIT_OR ] = "wave_active_bit_or", + [VKD3DSIH_WAVE_ACTIVE_BIT_XOR ] = "wave_active_bit_xor", + [VKD3DSIH_WAVE_ALL_BIT_COUNT ] = "wave_all_bit_count", + [VKD3DSIH_WAVE_ALL_TRUE ] = "wave_all_true", + [VKD3DSIH_WAVE_ANY_TRUE ] = "wave_any_true", + [VKD3DSIH_WAVE_IS_FIRST_LANE ] = "wave_is_first_lane", + [VKD3DSIH_WAVE_OP_ADD ] = "wave_op_add", + [VKD3DSIH_WAVE_OP_IMAX ] = "wave_op_imax", + [VKD3DSIH_WAVE_OP_IMIN ] = "wave_op_imin", + [VKD3DSIH_WAVE_OP_MAX ] = "wave_op_max", + [VKD3DSIH_WAVE_OP_MIN ] = "wave_op_min", + [VKD3DSIH_WAVE_OP_MUL ] = "wave_op_mul", + [VKD3DSIH_WAVE_OP_UMAX ] = "wave_op_umax", + [VKD3DSIH_WAVE_OP_UMIN ] = "wave_op_umin", + [VKD3DSIH_WAVE_PREFIX_BIT_COUNT ] = "wave_prefix_bit_count", + [VKD3DSIH_WAVE_READ_LANE_AT ] = "wave_read_lane_at", + [VKD3DSIH_WAVE_READ_LANE_FIRST ] = "wave_read_lane_first", + [VKD3DSIH_XOR ] = "xor", + }; + + if ((uint32_t)op < ARRAY_SIZE(names)) + return names[op] ? names[op] : error; + + return error; +} + static int convert_parameter_info(const struct vkd3d_shader_compile_info *compile_info, unsigned int *ret_count, const struct vkd3d_shader_parameter1 **ret_parameters) { @@ -1078,8 +1416,8 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr case VKD3DSIH_TEXREG2GB: case VKD3DSIH_TEXREG2RGB: vkd3d_shader_error(ctx->message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, - "Aborting due to unimplemented feature: Combined sampler instruction %#x.", - ins->opcode); + "Aborting due to unimplemented feature: Combined sampler instruction \"%s\" (%#x).", + vsir_opcode_get_name(ins->opcode, ""), ins->opcode); return VKD3D_ERROR_NOT_IMPLEMENTED; default: diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c index b3e251eff28..47ea6ce1f4b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d/libs/vkd3d-shader/msl.c @@ -737,19 +737,36 @@ static void msl_begin_block(struct msl_generator *gen) ++gen->indent; } -static void msl_if(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +static void msl_print_condition(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, + enum vkd3d_shader_conditional_op op, const struct vkd3d_shader_src_param *arg) { const char *condition; struct msl_src src; - msl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0); + msl_src_init(&src, gen, arg, VKD3DSP_WRITEMASK_0); - msl_print_indent(gen->buffer, gen->indent); - condition = ins->flags == VKD3D_SHADER_CONDITIONAL_OP_NZ ? "bool" : "!bool"; - vkd3d_string_buffer_printf(gen->buffer, "if (%s(%s))\n", condition, src.str->buffer); + condition = op == VKD3D_SHADER_CONDITIONAL_OP_NZ ? "bool" : "!bool"; + vkd3d_string_buffer_printf(buffer, "if (%s(%s))\n", condition, src.str->buffer); msl_src_cleanup(&src, &gen->string_buffers); +} +static void msl_discard(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + /* Note that discard_fragment() in Metal 2.2 and earlier behaves like + * SPIR-V OpKill, while in Metal 2.3 and later it behaves like + * OpDemoteToHelperInvocationEXT. We assume we have at least Metal 3 + * here. */ + msl_print_indent(gen->buffer, gen->indent); + msl_print_condition(gen->buffer, gen, ins->flags, &ins->src[0]); + msl_print_indent(gen->buffer, gen->indent + 1); + vkd3d_string_buffer_printf(gen->buffer, "discard_fragment();\n"); +} + +static void msl_if(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + msl_print_indent(gen->buffer, gen->indent); + msl_print_condition(gen->buffer, gen, ins->flags, &ins->src[0]); msl_begin_block(gen); } @@ -761,6 +778,50 @@ static void msl_else(struct msl_generator *gen) msl_begin_block(gen); } +static void msl_loop(struct msl_generator *gen) +{ + msl_print_indent(gen->buffer, gen->indent); + vkd3d_string_buffer_printf(gen->buffer, "for (;;)\n"); + msl_begin_block(gen); +} + +static void msl_break(struct msl_generator *gen) +{ + msl_print_indent(gen->buffer, gen->indent); + vkd3d_string_buffer_printf(gen->buffer, "break;\n"); +} + +static void msl_switch(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + struct msl_src src; + + msl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0); + + msl_print_indent(gen->buffer, gen->indent); + vkd3d_string_buffer_printf(gen->buffer, "switch (%s)\n", src.str->buffer); + msl_begin_block(gen); + + msl_src_cleanup(&src, &gen->string_buffers); +} + +static void msl_case(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + struct msl_src src; + + msl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0); + + msl_print_indent(gen->buffer, gen->indent); + vkd3d_string_buffer_printf(gen->buffer, "case %s:\n", src.str->buffer); + + msl_src_cleanup(&src, &gen->string_buffers); +} + +static void msl_default(struct msl_generator *gen) +{ + msl_print_indent(gen->buffer, gen->indent); + vkd3d_string_buffer_printf(gen->buffer, "default:\n"); +} + static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) { const struct msl_resource_type_info *resource_type_info; @@ -908,6 +969,37 @@ static void msl_movc(struct msl_generator *gen, const struct vkd3d_shader_instru msl_dst_cleanup(&dst, &gen->string_buffers); } +static void msl_mul64(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + struct msl_src src[2]; + struct msl_dst dst; + uint32_t mask; + + if (ins->dst[0].reg.type != VKD3DSPR_NULL) + { + /* TODO: mulhi(). */ + mask = msl_dst_init(&dst, gen, ins, &ins->dst[0]); + msl_print_assignment(gen, &dst, ""); + msl_dst_cleanup(&dst, &gen->string_buffers); + + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled 64-bit integer multiplication."); + } + + if (ins->dst[1].reg.type != VKD3DSPR_NULL) + { + mask = msl_dst_init(&dst, gen, ins, &ins->dst[1]); + msl_src_init(&src[0], gen, &ins->src[0], mask); + msl_src_init(&src[1], gen, &ins->src[1], mask); + + msl_print_assignment(gen, &dst, "%s * %s", src[0].str->buffer, src[1].str->buffer); + + msl_src_cleanup(&src[1], &gen->string_buffers); + msl_src_cleanup(&src[0], &gen->string_buffers); + msl_dst_cleanup(&dst, &gen->string_buffers); + } +} + static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) { msl_print_indent(gen->buffer, gen->indent); @@ -935,11 +1027,23 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d case VKD3DSIH_AND: msl_binop(gen, ins, "&"); break; + case VKD3DSIH_BREAK: + msl_break(gen); + break; + case VKD3DSIH_CASE: + msl_case(gen, ins); + break; case VKD3DSIH_DCL_INDEXABLE_TEMP: msl_dcl_indexable_temp(gen, ins); break; case VKD3DSIH_NOP: break; + case VKD3DSIH_DEFAULT: + msl_default(gen); + break; + case VKD3DSIH_DISCARD: + msl_discard(gen, ins); + break; case VKD3DSIH_DIV: msl_binop(gen, ins, "/"); break; @@ -956,6 +1060,8 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d msl_else(gen); break; case VKD3DSIH_ENDIF: + case VKD3DSIH_ENDLOOP: + case VKD3DSIH_ENDSWITCH: msl_end_block(gen); break; case VKD3DSIH_EQO: @@ -988,6 +1094,7 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d case VKD3DSIH_USHR: msl_binop(gen, ins, ">>"); break; + case VKD3DSIH_ILT: case VKD3DSIH_LTO: msl_relop(gen, ins, "<"); break; @@ -1000,6 +1107,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d case VKD3DSIH_MIN: msl_intrinsic(gen, ins, "min"); break; + case VKD3DSIH_IMUL: + msl_mul64(gen, ins); + break; case VKD3DSIH_INE: case VKD3DSIH_NEU: msl_relop(gen, ins, "!="); @@ -1014,6 +1124,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d case VKD3DSIH_LOG: msl_intrinsic(gen, ins, "log2"); break; + case VKD3DSIH_LOOP: + msl_loop(gen); + break; case VKD3DSIH_MOV: msl_mov(gen, ins); break; @@ -1050,6 +1163,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d case VKD3DSIH_SQRT: msl_intrinsic(gen, ins, "sqrt"); break; + case VKD3DSIH_SWITCH: + msl_switch(gen, ins); + break; default: msl_unhandled(gen, ins); break; diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h index 5dd00f00fe8..a5d1b8f4e05 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -223,6 +223,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES = 8017, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES = 8018, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCE_HANDLE = 8019, + VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT = 8020, VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER = 8300, VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE = 8301, @@ -611,6 +612,8 @@ enum vkd3d_shader_opcode VKD3DSIH_COUNT, }; +const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error); + enum vkd3d_shader_register_type { VKD3DSPR_TEMP, @@ -1336,12 +1339,6 @@ static inline bool register_is_constant_or_undef(const struct vkd3d_shader_regis return register_is_constant(reg) || register_is_undef(reg); } -static inline bool register_is_scalar_constant_zero(const struct vkd3d_shader_register *reg) -{ - return register_is_constant(reg) && reg->dimension == VSIR_DIMENSION_SCALAR - && (data_type_is_64_bit(reg->data_type) ? !reg->u.immconst_u64[0] : !reg->u.immconst_u32[0]); -} - static inline bool register_is_numeric_array(const struct vkd3d_shader_register *reg) { return (reg->type == VKD3DSPR_IMMCONSTBUFFER || reg->type == VKD3DSPR_IDXTEMP -- 2.47.2