[PATCH vkd3d 5/6] libs/vkd3d-shader: Import shader tracing from wined3d.
Józef Kucia
joseph.kucia at gmail.com
Tue May 29 05:50:32 CDT 2018
From: Józef Kucia <jkucia at codeweavers.com>
Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
Makefile.am | 1 +
libs/vkd3d-shader/dxbc.c | 8 +-
libs/vkd3d-shader/spirv.c | 6 +-
libs/vkd3d-shader/trace.c | 1606 ++++++++++++++++++++++++++++++
libs/vkd3d-shader/vkd3d_shader_main.c | 3 +
libs/vkd3d-shader/vkd3d_shader_private.h | 10 +-
6 files changed, 1627 insertions(+), 7 deletions(-)
create mode 100644 libs/vkd3d-shader/trace.c
diff --git a/Makefile.am b/Makefile.am
index 52b35859a546..faefc679258e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -68,6 +68,7 @@ libvkd3d_shader_la_SOURCES = \
include/private/vkd3d_shader.h \
libs/vkd3d-shader/dxbc.c \
libs/vkd3d-shader/spirv.c \
+ libs/vkd3d-shader/trace.c \
libs/vkd3d-shader/vkd3d_shader.map \
libs/vkd3d-shader/vkd3d_shader_main.c \
libs/vkd3d-shader/vkd3d_shader_private.h
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index b8e22ac78081..1309b7e9ab7c 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -1485,18 +1485,18 @@ static BOOL shader_sm4_read_param(struct vkd3d_sm4_data *priv, const DWORD **ptr
WARN("Invalid ptr %p, end %p.\n", *ptr, end);
return FALSE;
}
- memcpy(param->u.immconst_data, *ptr, 1 * sizeof(DWORD));
+ memcpy(param->u.immconst_uint, *ptr, 1 * sizeof(DWORD));
*ptr += 1;
break;
case VKD3D_SM4_IMMCONST_VEC4:
param->immconst_type = VKD3D_IMMCONST_VEC4;
- if (end - *ptr < 4)
+ if (end - *ptr < VKD3D_VEC4_SIZE)
{
WARN("Invalid ptr %p, end %p.\n", *ptr, end);
return FALSE;
}
- memcpy(param->u.immconst_data, *ptr, 4 * sizeof(DWORD));
+ memcpy(param->u.immconst_uint, *ptr, VKD3D_VEC4_SIZE * sizeof(DWORD));
*ptr += 4;
break;
@@ -1692,6 +1692,8 @@ void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct vkd3d_sha
ins->handler_idx = opcode_info->handler_idx;
ins->flags = 0;
+ ins->coissue = false;
+ ins->predicate = NULL;
ins->dst_count = strlen(opcode_info->dst_info);
ins->dst = priv->dst_param;
ins->src_count = strlen(opcode_info->src_info);
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index a59fdb6eab45..10806a5a9a2f 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2386,14 +2386,14 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_constant(struct vkd3d_dxbc_compile
if (reg->immconst_type == VKD3D_IMMCONST_SCALAR)
{
assert(component_count == 1);
- values[0] = *reg->u.immconst_data;
+ values[0] = *reg->u.immconst_uint;
}
else
{
for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
- values[j++] = reg->u.immconst_data[vkd3d_swizzle_get_component(swizzle, i)];
+ values[j++] = reg->u.immconst_uint[vkd3d_swizzle_get_component(swizzle, i)];
}
}
@@ -4598,7 +4598,7 @@ static void vkd3d_dxbc_compiler_emit_control_flow_instruction(struct vkd3d_dxbc_
assert(cf_info->current_block == VKD3D_BLOCK_SWITCH);
assert(src->swizzle == VKD3D_NO_SWIZZLE && src->reg.type == VKD3DSPR_IMMCONST);
- value = *src->reg.u.immconst_data;
+ value = *src->reg.u.immconst_uint;
if (!vkd3d_array_reserve((void **)&cf_info->u.switch_.case_blocks, &cf_info->u.switch_.case_blocks_size,
2 * (cf_info->u.switch_.case_block_count + 1), sizeof(*cf_info->u.switch_.case_blocks)))
diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c
new file mode 100644
index 000000000000..faa009e03a4c
--- /dev/null
+++ b/libs/vkd3d-shader/trace.c
@@ -0,0 +1,1606 @@
+/*
+ * Copyright 2002-2003 Jason Edmeades
+ * Copyright 2002-2003 Raphael Junqueira
+ * Copyright 2004 Christian Costa
+ * Copyright 2005 Oliver Stieber
+ * Copyright 2006 Ivan Gyurdiev
+ * Copyright 2007-2008, 2013 Stefan Dösinger for CodeWeavers
+ * Copyright 2009-2011 Henri Verbeet for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "vkd3d_shader_private.h"
+
+#include <stdio.h>
+
+struct vkd3d_string_buffer
+{
+ struct list entry;
+ char *buffer;
+ unsigned int buffer_size;
+ unsigned int content_size;
+};
+
+static const char * const shader_opcode_names[] =
+{
+ /* VKD3DSIH_ABS */ "abs",
+ /* VKD3DSIH_ADD */ "add",
+ /* VKD3DSIH_AND */ "and",
+ /* 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_BREAK */ "break",
+ /* VKD3DSIH_BREAKC */ "breakc",
+ /* VKD3DSIH_BREAKP */ "breakp",
+ /* VKD3DSIH_BUFINFO */ "bufinfo",
+ /* VKD3DSIH_CALL */ "call",
+ /* VKD3DSIH_CALLNZ */ "callnz",
+ /* VKD3DSIH_CASE */ "case",
+ /* 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_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_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_maxOutputVertexCount",
+ /* VKD3DSIH_DEF */ "def",
+ /* VKD3DSIH_DEFAULT */ "default",
+ /* VKD3DSIH_DEFB */ "defb",
+ /* VKD3DSIH_DEFI */ "defi",
+ /* VKD3DSIH_DIV */ "div",
+ /* VKD3DSIH_DP2 */ "dp2",
+ /* VKD3DSIH_DP2ADD */ "dp2add",
+ /* VKD3DSIH_DP3 */ "dp3",
+ /* VKD3DSIH_DP4 */ "dp4",
+ /* 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_ELSE */ "else",
+ /* VKD3DSIH_EMIT */ "emit",
+ /* VKD3DSIH_EMIT_STREAM */ "emit_stream",
+ /* VKD3DSIH_ENDIF */ "endif",
+ /* VKD3DSIH_ENDLOOP */ "endloop",
+ /* VKD3DSIH_ENDREP */ "endrep",
+ /* VKD3DSIH_ENDSWITCH */ "endswitch",
+ /* VKD3DSIH_EQ */ "eq",
+ /* 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_FTOI */ "ftoi",
+ /* VKD3DSIH_FTOU */ "ftou",
+ /* VKD3DSIH_GATHER4 */ "gather4",
+ /* VKD3DSIH_GATHER4_C */ "gather4_c",
+ /* VKD3DSIH_GATHER4_PO */ "gather4_po",
+ /* VKD3DSIH_GATHER4_PO_C */ "gather4_po_c",
+ /* VKD3DSIH_GE */ "ge",
+ /* 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_IADD */ "iadd",
+ /* VKD3DSIH_IBFE */ "ibfe",
+ /* VKD3DSIH_IEQ */ "ieq",
+ /* VKD3DSIH_IF */ "if",
+ /* VKD3DSIH_IFC */ "ifc",
+ /* 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_ISHL */ "ishl",
+ /* VKD3DSIH_ISHR */ "ishr",
+ /* VKD3DSIH_ITOF */ "itof",
+ /* VKD3DSIH_LABEL */ "label",
+ /* VKD3DSIH_LD */ "ld",
+ /* VKD3DSIH_LD2DMS */ "ld2dms",
+ /* VKD3DSIH_LD_RAW */ "ld_raw",
+ /* VKD3DSIH_LD_STRUCTURED */ "ld_structured",
+ /* VKD3DSIH_LD_UAV_TYPED */ "ld_uav_typed",
+ /* VKD3DSIH_LIT */ "lit",
+ /* VKD3DSIH_LOD */ "lod",
+ /* VKD3DSIH_LOG */ "log",
+ /* VKD3DSIH_LOGP */ "logp",
+ /* VKD3DSIH_LOOP */ "loop",
+ /* VKD3DSIH_LRP */ "lrp",
+ /* VKD3DSIH_LT */ "lt",
+ /* 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_MUL */ "mul",
+ /* VKD3DSIH_NE */ "ne",
+ /* VKD3DSIH_NOP */ "nop",
+ /* VKD3DSIH_NOT */ "not",
+ /* VKD3DSIH_NRM */ "nrm",
+ /* VKD3DSIH_OR */ "or",
+ /* VKD3DSIH_PHASE */ "phase",
+ /* VKD3DSIH_POW */ "pow",
+ /* 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_C */ "sample_c",
+ /* VKD3DSIH_SAMPLE_C_LZ */ "sample_c_lz",
+ /* VKD3DSIH_SAMPLE_GRAD */ "sample_d",
+ /* VKD3DSIH_SAMPLE_INFO */ "sample_info",
+ /* VKD3DSIH_SAMPLE_LOD */ "sample_l",
+ /* 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_SYNC */ "sync",
+ /* VKD3DSIH_TEX */ "texld",
+ /* VKD3DSIH_TEXBEM */ "texbem",
+ /* VKD3DSIH_TEXBEML */ "texbeml",
+ /* VKD3DSIH_TEXCOORD */ "texcrd",
+ /* VKD3DSIH_TEXDEPTH */ "texdepth",
+ /* VKD3DSIH_TEXDP3 */ "texdp3",
+ /* VKD3DSIH_TEXDP3TEX */ "texdp3tex",
+ /* VKD3DSIH_TEXKILL */ "texkill",
+ /* 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_USHR */ "ushr",
+ /* VKD3DSIH_UTOF */ "utof",
+ /* VKD3DSIH_XOR */ "xor",
+};
+
+static const struct
+{
+ enum vkd3d_shader_input_sysval_semantic sysval_semantic;
+ const char *sysval_name;
+}
+shader_input_sysval_semantic_names[] =
+{
+ {VKD3D_SIV_POSITION, "position"},
+ {VKD3D_SIV_CLIP_DISTANCE, "clip_distance"},
+ {VKD3D_SIV_CULL_DISTANCE, "cull_distance"},
+ {VKD3D_SIV_RENDER_TARGET_ARRAY_INDEX, "render_target_array_index"},
+ {VKD3D_SIV_VIEWPORT_ARRAY_INDEX, "viewport_array_index"},
+ {VKD3D_SIV_VERTEX_ID, "vertex_id"},
+ {VKD3D_SIV_INSTANCE_ID, "instance_id"},
+ {VKD3D_SIV_PRIMITIVE_ID, "primitive_id"},
+ {VKD3D_SIV_IS_FRONT_FACE, "is_front_face"},
+ {VKD3D_SIV_SAMPLE_INDEX, "sample_index"},
+ {VKD3D_SIV_QUAD_U0_TESS_FACTOR, "finalQuadUeq0EdgeTessFactor"},
+ {VKD3D_SIV_QUAD_V0_TESS_FACTOR, "finalQuadVeq0EdgeTessFactor"},
+ {VKD3D_SIV_QUAD_U1_TESS_FACTOR, "finalQuadUeq1EdgeTessFactor"},
+ {VKD3D_SIV_QUAD_V1_TESS_FACTOR, "finalQuadVeq1EdgeTessFactor"},
+ {VKD3D_SIV_QUAD_U_INNER_TESS_FACTOR, "finalQuadUInsideTessFactor"},
+ {VKD3D_SIV_QUAD_V_INNER_TESS_FACTOR, "finalQuadVInsideTessFactor"},
+ {VKD3D_SIV_TRIANGLE_U_TESS_FACTOR, "finalTriUeq0EdgeTessFactor"},
+ {VKD3D_SIV_TRIANGLE_V_TESS_FACTOR, "finalTriVeq0EdgeTessFactor"},
+ {VKD3D_SIV_TRIANGLE_W_TESS_FACTOR, "finalTriWeq0EdgeTessFactor"},
+ {VKD3D_SIV_TRIANGLE_INNER_TESS_FACTOR, "finalTriInsideTessFactor"},
+ {VKD3D_SIV_LINE_DETAIL_TESS_FACTOR, "finalLineDetailTessFactor"},
+ {VKD3D_SIV_LINE_DENSITY_TESS_FACTOR, "finalLineDensityTessFactor"},
+};
+
+static void string_buffer_clear(struct vkd3d_string_buffer *buffer)
+{
+ buffer->buffer[0] = '\0';
+ buffer->content_size = 0;
+}
+
+static BOOL string_buffer_init(struct vkd3d_string_buffer *buffer)
+{
+ buffer->buffer_size = 32;
+ if (!(buffer->buffer = vkd3d_malloc(buffer->buffer_size)))
+ {
+ ERR("Failed to allocate shader buffer memory.\n");
+ return FALSE;
+ }
+
+ string_buffer_clear(buffer);
+ return TRUE;
+}
+
+static void string_buffer_free(struct vkd3d_string_buffer *buffer)
+{
+ vkd3d_free(buffer->buffer);
+}
+
+static BOOL string_buffer_resize(struct vkd3d_string_buffer *buffer, int rc)
+{
+ unsigned int new_buffer_size = buffer->buffer_size * 2;
+ char *new_buffer;
+
+ while (rc > 0 && (unsigned int)rc >= new_buffer_size - buffer->content_size)
+ new_buffer_size *= 2;
+ if (!(new_buffer = vkd3d_realloc(buffer->buffer, new_buffer_size)))
+ {
+ ERR("Failed to grow buffer.\n");
+ buffer->buffer[buffer->content_size] = '\0';
+ return FALSE;
+ }
+ buffer->buffer = new_buffer;
+ buffer->buffer_size = new_buffer_size;
+ return TRUE;
+}
+
+static int shader_vaddline(struct vkd3d_string_buffer *buffer, const char *format, va_list args)
+{
+ unsigned int rem;
+ int rc;
+
+ rem = buffer->buffer_size - buffer->content_size;
+ rc = vsnprintf(&buffer->buffer[buffer->content_size], rem, format, args);
+ if (rc < 0 || (unsigned int)rc >= rem)
+ return rc;
+
+ buffer->content_size += rc;
+ return 0;
+}
+
+static int shader_addline(struct vkd3d_string_buffer *buffer, const char *format, ...)
+{
+ va_list args;
+ int ret;
+
+ for (;;)
+ {
+ va_start(args, format);
+ ret = shader_vaddline(buffer, format, args);
+ va_end(args);
+ if (!ret)
+ return ret;
+ if (!string_buffer_resize(buffer, ret))
+ return -1;
+ }
+}
+
+/* Convert floating point offset relative to a register file to an absolute
+ * offset for float constants. */
+static unsigned int shader_get_float_offset(enum vkd3d_shader_register_type register_type, UINT register_idx)
+{
+ switch (register_type)
+ {
+ case VKD3DSPR_CONST: return register_idx;
+ case VKD3DSPR_CONST2: return 2048 + register_idx;
+ case VKD3DSPR_CONST3: return 4096 + register_idx;
+ case VKD3DSPR_CONST4: return 6144 + register_idx;
+ default:
+ FIXME("Unsupported register type: %u.\n", register_type);
+ return register_idx;
+ }
+}
+
+static void shader_dump_global_flags(struct vkd3d_string_buffer *buffer, DWORD global_flags)
+{
+ if (global_flags & VKD3DSGF_REFACTORING_ALLOWED)
+ {
+ shader_addline(buffer, "refactoringAllowed");
+ global_flags &= ~VKD3DSGF_REFACTORING_ALLOWED;
+ if (global_flags)
+ shader_addline(buffer, " | ");
+ }
+
+ if (global_flags & VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL)
+ {
+ shader_addline(buffer, "forceEarlyDepthStencil");
+ global_flags &= ~VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL;
+ if (global_flags)
+ shader_addline(buffer, " | ");
+ }
+
+ if (global_flags & VKD3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS)
+ {
+ shader_addline(buffer, "enableRawAndStructuredBuffers");
+ global_flags &= ~VKD3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS;
+ }
+
+ if (global_flags)
+ shader_addline(buffer, "unknown_flags(%#x)", global_flags);
+}
+
+static void shader_dump_sync_flags(struct vkd3d_string_buffer *buffer, DWORD sync_flags)
+{
+ if (sync_flags & VKD3DSSF_GROUP_SHARED_MEMORY)
+ {
+ shader_addline(buffer, "_g");
+ sync_flags &= ~VKD3DSSF_GROUP_SHARED_MEMORY;
+ }
+ if (sync_flags & VKD3DSSF_THREAD_GROUP)
+ {
+ shader_addline(buffer, "_t");
+ sync_flags &= ~VKD3DSSF_THREAD_GROUP;
+ }
+
+ if (sync_flags)
+ shader_addline(buffer, "_unknown_flags(%#x)", sync_flags);
+}
+
+static void shader_dump_precise_flags(struct vkd3d_string_buffer *buffer, DWORD flags)
+{
+ if (!(flags & VKD3DSI_PRECISE_XYZW))
+ return;
+
+ shader_addline(buffer, " [precise");
+ if (flags != VKD3DSI_PRECISE_XYZW)
+ {
+ shader_addline(buffer, "(%s%s%s%s)",
+ flags & VKD3DSI_PRECISE_X ? "x" : "",
+ flags & VKD3DSI_PRECISE_Y ? "y" : "",
+ flags & VKD3DSI_PRECISE_Z ? "z" : "",
+ flags & VKD3DSI_PRECISE_W ? "w" : "");
+ }
+ shader_addline(buffer, "]");
+}
+
+static void shader_dump_uav_flags(struct vkd3d_string_buffer *buffer, DWORD uav_flags)
+{
+ if (uav_flags & VKD3DSUF_GLOBALLY_COHERENT)
+ {
+ shader_addline(buffer, "_glc");
+ uav_flags &= ~VKD3DSUF_GLOBALLY_COHERENT;
+ }
+ if (uav_flags & VKD3DSUF_ORDER_PRESERVING_COUNTER)
+ {
+ shader_addline(buffer, "_opc");
+ uav_flags &= ~VKD3DSUF_ORDER_PRESERVING_COUNTER;
+ }
+
+ if (uav_flags)
+ shader_addline(buffer, "_unknown_flags(%#x)", uav_flags);
+}
+
+static void shader_dump_tessellator_domain(struct vkd3d_string_buffer *buffer,
+ enum vkd3d_tessellator_domain domain)
+{
+ switch (domain)
+ {
+ case VKD3D_TESSELLATOR_DOMAIN_LINE:
+ shader_addline(buffer, "line");
+ break;
+ case VKD3D_TESSELLATOR_DOMAIN_TRIANGLE:
+ shader_addline(buffer, "triangle");
+ break;
+ case VKD3D_TESSELLATOR_DOMAIN_QUAD:
+ shader_addline(buffer, "quad");
+ break;
+ default:
+ shader_addline(buffer, "unknown_tessellator_domain(%#x)", domain);
+ break;
+ }
+}
+
+static void shader_dump_tessellator_output_primitive(struct vkd3d_string_buffer *buffer,
+ enum vkd3d_tessellator_output_primitive output_primitive)
+{
+ switch (output_primitive)
+ {
+ case VKD3D_TESSELLATOR_OUTPUT_POINT:
+ shader_addline(buffer, "point");
+ break;
+ case VKD3D_TESSELLATOR_OUTPUT_LINE:
+ shader_addline(buffer, "line");
+ break;
+ case VKD3D_TESSELLATOR_OUTPUT_TRIANGLE_CW:
+ shader_addline(buffer, "triangle_cw");
+ break;
+ case VKD3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW:
+ shader_addline(buffer, "triangle_ccw");
+ break;
+ default:
+ shader_addline(buffer, "unknown_tessellator_output_primitive(%#x)", output_primitive);
+ break;
+ }
+}
+
+static void shader_dump_tessellator_partitioning(struct vkd3d_string_buffer *buffer,
+ enum vkd3d_tessellator_partitioning partitioning)
+{
+ switch (partitioning)
+ {
+ case VKD3D_TESSELLATOR_PARTITIONING_INTEGER:
+ shader_addline(buffer, "integer");
+ break;
+ case VKD3D_TESSELLATOR_PARTITIONING_POW2:
+ shader_addline(buffer, "pow2");
+ break;
+ case VKD3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD:
+ shader_addline(buffer, "fractional_odd");
+ break;
+ case VKD3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN:
+ shader_addline(buffer, "fractional_even");
+ break;
+ default:
+ shader_addline(buffer, "unknown_tessellator_partitioning(%#x)", partitioning);
+ break;
+ }
+}
+
+static void shader_dump_shader_input_sysval_semantic(struct vkd3d_string_buffer *buffer,
+ enum vkd3d_shader_input_sysval_semantic semantic)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(shader_input_sysval_semantic_names); ++i)
+ {
+ if (shader_input_sysval_semantic_names[i].sysval_semantic == semantic)
+ {
+ shader_addline(buffer, "%s", shader_input_sysval_semantic_names[i].sysval_name);
+ return;
+ }
+ }
+
+ shader_addline(buffer, "unknown_shader_input_sysval_semantic(%#x)", semantic);
+}
+
+static void shader_dump_decl_usage(struct vkd3d_string_buffer *buffer,
+ const struct vkd3d_shader_semantic *semantic, unsigned int flags,
+ const struct vkd3d_shader_version *shader_version)
+{
+ shader_addline(buffer, "dcl");
+
+ if (semantic->reg.reg.type == VKD3DSPR_SAMPLER)
+ {
+ switch (semantic->resource_type)
+ {
+ case VKD3D_SHADER_RESOURCE_TEXTURE_2D:
+ shader_addline(buffer, "_2d");
+ break;
+
+ case VKD3D_SHADER_RESOURCE_TEXTURE_3D:
+ shader_addline(buffer, "_3d");
+ break;
+
+ case VKD3D_SHADER_RESOURCE_TEXTURE_CUBE:
+ shader_addline(buffer, "_cube");
+ break;
+
+ default:
+ shader_addline(buffer, "_unknown_resource_type(%#x)", semantic->resource_type);
+ break;
+ }
+ }
+ else if (semantic->reg.reg.type == VKD3DSPR_RESOURCE || semantic->reg.reg.type == VKD3DSPR_UAV)
+ {
+ if (semantic->reg.reg.type == VKD3DSPR_RESOURCE)
+ shader_addline(buffer, "_resource_");
+ else
+ shader_addline(buffer, "_uav_");
+ switch (semantic->resource_type)
+ {
+ case VKD3D_SHADER_RESOURCE_BUFFER:
+ shader_addline(buffer, "buffer");
+ break;
+
+ case VKD3D_SHADER_RESOURCE_TEXTURE_1D:
+ shader_addline(buffer, "texture1d");
+ break;
+
+ case VKD3D_SHADER_RESOURCE_TEXTURE_2D:
+ shader_addline(buffer, "texture2d");
+ break;
+
+ case VKD3D_SHADER_RESOURCE_TEXTURE_2DMS:
+ shader_addline(buffer, "texture2dms");
+ break;
+
+ case VKD3D_SHADER_RESOURCE_TEXTURE_3D:
+ shader_addline(buffer, "texture3d");
+ break;
+
+ case VKD3D_SHADER_RESOURCE_TEXTURE_CUBE:
+ shader_addline(buffer, "texturecube");
+ break;
+
+ case VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY:
+ shader_addline(buffer, "texture1darray");
+ break;
+
+ case VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY:
+ shader_addline(buffer, "texture2darray");
+ break;
+
+ case VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY:
+ shader_addline(buffer, "texture2dmsarray");
+ break;
+
+ case VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY:
+ shader_addline(buffer, "texturecubearray");
+ break;
+
+ default:
+ shader_addline(buffer, "unknown");
+ break;
+ }
+ if (semantic->reg.reg.type == VKD3DSPR_UAV)
+ shader_dump_uav_flags(buffer, flags);
+ switch (semantic->resource_data_type)
+ {
+ case VKD3D_DATA_FLOAT:
+ shader_addline(buffer, " (float)");
+ break;
+
+ case VKD3D_DATA_INT:
+ shader_addline(buffer, " (int)");
+ break;
+
+ case VKD3D_DATA_UINT:
+ shader_addline(buffer, " (uint)");
+ break;
+
+ case VKD3D_DATA_UNORM:
+ shader_addline(buffer, " (unorm)");
+ break;
+
+ case VKD3D_DATA_SNORM:
+ shader_addline(buffer, " (snorm)");
+ break;
+
+ default:
+ shader_addline(buffer, " (unknown)");
+ break;
+ }
+ }
+ else
+ {
+ /* Pixel shaders 3.0 don't have usage semantics. */
+ if (shader_version->major < 3 && shader_version->type == VKD3D_SHADER_TYPE_PIXEL)
+ return;
+ else
+ shader_addline(buffer, "_");
+
+ switch (semantic->usage)
+ {
+ case VKD3D_DECL_USAGE_POSITION:
+ shader_addline(buffer, "position%u", semantic->usage_idx);
+ break;
+
+ case VKD3D_DECL_USAGE_BLEND_INDICES:
+ shader_addline(buffer, "blend");
+ break;
+
+ case VKD3D_DECL_USAGE_BLEND_WEIGHT:
+ shader_addline(buffer, "weight");
+ break;
+
+ case VKD3D_DECL_USAGE_NORMAL:
+ shader_addline(buffer, "normal%u", semantic->usage_idx);
+ break;
+
+ case VKD3D_DECL_USAGE_PSIZE:
+ shader_addline(buffer, "psize");
+ break;
+
+ case VKD3D_DECL_USAGE_COLOR:
+ if (!semantic->usage_idx)
+ shader_addline(buffer, "color");
+ else
+ shader_addline(buffer, "specular%u", (semantic->usage_idx - 1));
+ break;
+
+ case VKD3D_DECL_USAGE_TEXCOORD:
+ shader_addline(buffer, "texture%u", semantic->usage_idx);
+ break;
+
+ case VKD3D_DECL_USAGE_TANGENT:
+ shader_addline(buffer, "tangent");
+ break;
+
+ case VKD3D_DECL_USAGE_BINORMAL:
+ shader_addline(buffer, "binormal");
+ break;
+
+ case VKD3D_DECL_USAGE_TESS_FACTOR:
+ shader_addline(buffer, "tessfactor");
+ break;
+
+ case VKD3D_DECL_USAGE_POSITIONT:
+ shader_addline(buffer, "positionT%u", semantic->usage_idx);
+ break;
+
+ case VKD3D_DECL_USAGE_FOG:
+ shader_addline(buffer, "fog");
+ break;
+
+ case VKD3D_DECL_USAGE_DEPTH:
+ shader_addline(buffer, "depth");
+ break;
+
+ case VKD3D_DECL_USAGE_SAMPLE:
+ shader_addline(buffer, "sample");
+ break;
+
+ default:
+ shader_addline(buffer, "<unknown_semantic(%#x)>", semantic->usage);
+ FIXME("Unrecognised semantic usage %#x.\n", semantic->usage);
+ }
+ }
+}
+
+static void shader_dump_src_param(struct vkd3d_string_buffer *buffer,
+ const struct vkd3d_shader_src_param *param, const struct vkd3d_shader_version *shader_version);
+
+static void shader_dump_register(struct vkd3d_string_buffer *buffer,
+ const struct vkd3d_shader_register *reg, const struct vkd3d_shader_version *shader_version)
+{
+ static const char * const rastout_reg_names[] = {"oPos", "oFog", "oPts"};
+ static const char * const misctype_reg_names[] = {"vPos", "vFace"};
+ unsigned int offset = reg->idx[0].offset;
+
+ switch (reg->type)
+ {
+ case VKD3DSPR_TEMP:
+ shader_addline(buffer, "r");
+ break;
+
+ case VKD3DSPR_INPUT:
+ shader_addline(buffer, "v");
+ break;
+
+ case VKD3DSPR_CONST:
+ case VKD3DSPR_CONST2:
+ case VKD3DSPR_CONST3:
+ case VKD3DSPR_CONST4:
+ shader_addline(buffer, "c");
+ offset = shader_get_float_offset(reg->type, offset);
+ break;
+
+ case VKD3DSPR_TEXTURE: /* vs: case VKD3DSPR_ADDR */
+ shader_addline(buffer, "%c", shader_version->type == VKD3D_SHADER_TYPE_PIXEL ? 't' : 'a');
+ break;
+
+ case VKD3DSPR_RASTOUT:
+ shader_addline(buffer, "%s", rastout_reg_names[offset]);
+ break;
+
+ case VKD3DSPR_COLOROUT:
+ shader_addline(buffer, "oC");
+ break;
+
+ case VKD3DSPR_DEPTHOUT:
+ shader_addline(buffer, "oDepth");
+ break;
+
+ case VKD3DSPR_DEPTHOUTGE:
+ shader_addline(buffer, "oDepthGE");
+ break;
+
+ case VKD3DSPR_DEPTHOUTLE:
+ shader_addline(buffer, "oDepthLE");
+ break;
+
+ case VKD3DSPR_ATTROUT:
+ shader_addline(buffer, "oD");
+ break;
+
+ case VKD3DSPR_TEXCRDOUT:
+ /* Vertex shaders >= 3.0 use general purpose output registers
+ * (VKD3DSPR_OUTPUT), which can include an address token. */
+ if (shader_version->major >= 3)
+ shader_addline(buffer, "o");
+ else
+ shader_addline(buffer, "oT");
+ break;
+
+ case VKD3DSPR_CONSTINT:
+ shader_addline(buffer, "i");
+ break;
+
+ case VKD3DSPR_CONSTBOOL:
+ shader_addline(buffer, "b");
+ break;
+
+ case VKD3DSPR_LABEL:
+ shader_addline(buffer, "l");
+ break;
+
+ case VKD3DSPR_LOOP:
+ shader_addline(buffer, "aL");
+ break;
+
+ case VKD3DSPR_SAMPLER:
+ shader_addline(buffer, "s");
+ break;
+
+ case VKD3DSPR_MISCTYPE:
+ if (offset > 1)
+ {
+ FIXME("Unhandled misctype register %u.\n", offset);
+ shader_addline(buffer, "<unhandled misctype %#x>", offset);
+ }
+ else
+ {
+ shader_addline(buffer, "%s", misctype_reg_names[offset]);
+ }
+ break;
+
+ case VKD3DSPR_PREDICATE:
+ shader_addline(buffer, "p");
+ break;
+
+ case VKD3DSPR_IMMCONST:
+ shader_addline(buffer, "l");
+ break;
+
+ case VKD3DSPR_CONSTBUFFER:
+ shader_addline(buffer, "cb");
+ break;
+
+ case VKD3DSPR_IMMCONSTBUFFER:
+ shader_addline(buffer, "icb");
+ break;
+
+ case VKD3DSPR_PRIMID:
+ shader_addline(buffer, "primID");
+ break;
+
+ case VKD3DSPR_NULL:
+ shader_addline(buffer, "null");
+ break;
+
+ case VKD3DSPR_RASTERIZER:
+ shader_addline(buffer, "rasterizer");
+ break;
+
+ case VKD3DSPR_RESOURCE:
+ shader_addline(buffer, "t");
+ break;
+
+ case VKD3DSPR_UAV:
+ shader_addline(buffer, "u");
+ break;
+
+ case VKD3DSPR_OUTPOINTID:
+ shader_addline(buffer, "vOutputControlPointID");
+ break;
+
+ case VKD3DSPR_FORKINSTID:
+ shader_addline(buffer, "vForkInstanceId");
+ break;
+
+ case VKD3DSPR_JOININSTID:
+ shader_addline(buffer, "vJoinInstanceId");
+ break;
+
+ case VKD3DSPR_INCONTROLPOINT:
+ shader_addline(buffer, "vicp");
+ break;
+
+ case VKD3DSPR_OUTCONTROLPOINT:
+ shader_addline(buffer, "vocp");
+ break;
+
+ case VKD3DSPR_PATCHCONST:
+ shader_addline(buffer, "vpc");
+ break;
+
+ case VKD3DSPR_TESSCOORD:
+ shader_addline(buffer, "vDomainLocation");
+ break;
+
+ case VKD3DSPR_GROUPSHAREDMEM:
+ shader_addline(buffer, "g");
+ break;
+
+ case VKD3DSPR_THREADID:
+ shader_addline(buffer, "vThreadID");
+ break;
+
+ case VKD3DSPR_THREADGROUPID:
+ shader_addline(buffer, "vThreadGroupID");
+ break;
+
+ case VKD3DSPR_LOCALTHREADID:
+ shader_addline(buffer, "vThreadIDInGroup");
+ break;
+
+ case VKD3DSPR_LOCALTHREADINDEX:
+ shader_addline(buffer, "vThreadIDInGroupFlattened");
+ break;
+
+ case VKD3DSPR_IDXTEMP:
+ shader_addline(buffer, "x");
+ break;
+
+ case VKD3DSPR_STREAM:
+ shader_addline(buffer, "m");
+ break;
+
+ case VKD3DSPR_FUNCTIONBODY:
+ shader_addline(buffer, "fb");
+ break;
+
+ case VKD3DSPR_FUNCTIONPOINTER:
+ shader_addline(buffer, "fp");
+ break;
+
+ case VKD3DSPR_COVERAGE:
+ shader_addline(buffer, "vCoverage");
+ break;
+
+ case VKD3DSPR_SAMPLEMASK:
+ shader_addline(buffer, "oMask");
+ break;
+
+ case VKD3DSPR_GSINSTID:
+ shader_addline(buffer, "vGSInstanceID");
+ break;
+
+ default:
+ shader_addline(buffer, "<unhandled_rtype(%#x)>", reg->type);
+ break;
+ }
+
+ if (reg->type == VKD3DSPR_IMMCONST)
+ {
+ shader_addline(buffer, "(");
+ switch (reg->immconst_type)
+ {
+ case VKD3D_IMMCONST_SCALAR:
+ switch (reg->data_type)
+ {
+ case VKD3D_DATA_FLOAT:
+ shader_addline(buffer, "%.8e", reg->u.immconst_float[0]);
+ break;
+ case VKD3D_DATA_INT:
+ shader_addline(buffer, "%d", reg->u.immconst_uint[0]);
+ break;
+ case VKD3D_DATA_RESOURCE:
+ case VKD3D_DATA_SAMPLER:
+ case VKD3D_DATA_UINT:
+ shader_addline(buffer, "%u", reg->u.immconst_uint[0]);
+ break;
+ default:
+ shader_addline(buffer, "<unhandled data type %#x>", reg->data_type);
+ break;
+ }
+ break;
+
+ case VKD3D_IMMCONST_VEC4:
+ switch (reg->data_type)
+ {
+ case VKD3D_DATA_FLOAT:
+ shader_addline(buffer, "%.8e, %.8e, %.8e, %.8e",
+ reg->u.immconst_float[0], reg->u.immconst_float[1],
+ reg->u.immconst_float[2], reg->u.immconst_float[3]);
+ break;
+ case VKD3D_DATA_INT:
+ shader_addline(buffer, "%d, %d, %d, %d",
+ reg->u.immconst_uint[0], reg->u.immconst_uint[1],
+ reg->u.immconst_uint[2], reg->u.immconst_uint[3]);
+ break;
+ case VKD3D_DATA_RESOURCE:
+ case VKD3D_DATA_SAMPLER:
+ case VKD3D_DATA_UINT:
+ shader_addline(buffer, "%u, %u, %u, %u",
+ reg->u.immconst_uint[0], reg->u.immconst_uint[1],
+ reg->u.immconst_uint[2], reg->u.immconst_uint[3]);
+ break;
+ default:
+ shader_addline(buffer, "<unhandled data type %#x>", reg->data_type);
+ break;
+ }
+ break;
+
+ default:
+ shader_addline(buffer, "<unhandled immconst_type %#x>", reg->immconst_type);
+ break;
+ }
+ shader_addline(buffer, ")");
+ }
+ else if (reg->type != VKD3DSPR_RASTOUT
+ && reg->type != VKD3DSPR_MISCTYPE
+ && reg->type != VKD3DSPR_NULL)
+ {
+ if (offset != ~0u)
+ {
+ shader_addline(buffer, "[");
+ if (reg->idx[0].rel_addr)
+ {
+ shader_dump_src_param(buffer, reg->idx[0].rel_addr, shader_version);
+ shader_addline(buffer, " + ");
+ }
+ shader_addline(buffer, "%u]", offset);
+
+ if (reg->idx[1].offset != ~0u)
+ {
+ shader_addline(buffer, "[");
+ if (reg->idx[1].rel_addr)
+ {
+ shader_dump_src_param(buffer, reg->idx[1].rel_addr, shader_version);
+ shader_addline(buffer, " + ");
+ }
+ shader_addline(buffer, "%u]", reg->idx[1].offset);
+ }
+ }
+
+ if (reg->type == VKD3DSPR_FUNCTIONPOINTER)
+ shader_addline(buffer, "[%u]", reg->u.fp_body_idx);
+ }
+}
+
+static void shader_dump_dst_param(struct vkd3d_string_buffer *buffer,
+ const struct vkd3d_shader_dst_param *param, const struct vkd3d_shader_version *shader_version)
+{
+ DWORD write_mask = param->write_mask;
+
+ shader_dump_register(buffer, ¶m->reg, shader_version);
+
+ if (write_mask && write_mask != VKD3DSP_WRITEMASK_ALL)
+ {
+ static const char write_mask_chars[] = "xyzw";
+
+ shader_addline(buffer, ".");
+ if (write_mask & VKD3DSP_WRITEMASK_0)
+ shader_addline(buffer, "%c", write_mask_chars[0]);
+ if (write_mask & VKD3DSP_WRITEMASK_1)
+ shader_addline(buffer, "%c", write_mask_chars[1]);
+ if (write_mask & VKD3DSP_WRITEMASK_2)
+ shader_addline(buffer, "%c", write_mask_chars[2]);
+ if (write_mask & VKD3DSP_WRITEMASK_3)
+ shader_addline(buffer, "%c", write_mask_chars[3]);
+ }
+}
+
+static void shader_dump_src_param(struct vkd3d_string_buffer *buffer,
+ const struct vkd3d_shader_src_param *param, const struct vkd3d_shader_version *shader_version)
+{
+ enum vkd3d_shader_src_modifier src_modifier = param->modifiers;
+ DWORD swizzle = param->swizzle;
+
+ if (src_modifier == VKD3DSPSM_NEG
+ || src_modifier == VKD3DSPSM_BIASNEG
+ || src_modifier == VKD3DSPSM_SIGNNEG
+ || src_modifier == VKD3DSPSM_X2NEG
+ || src_modifier == VKD3DSPSM_ABSNEG)
+ shader_addline(buffer, "-");
+ else if (src_modifier == VKD3DSPSM_COMP)
+ shader_addline(buffer, "1-");
+ else if (src_modifier == VKD3DSPSM_NOT)
+ shader_addline(buffer, "!");
+
+ if (src_modifier == VKD3DSPSM_ABS || src_modifier == VKD3DSPSM_ABSNEG)
+ shader_addline(buffer, "abs(");
+
+ shader_dump_register(buffer, ¶m->reg, shader_version);
+
+ switch (src_modifier)
+ {
+ case VKD3DSPSM_NONE: break;
+ case VKD3DSPSM_NEG: break;
+ case VKD3DSPSM_NOT: break;
+ case VKD3DSPSM_BIAS: shader_addline(buffer, "_bias"); break;
+ case VKD3DSPSM_BIASNEG: shader_addline(buffer, "_bias"); break;
+ case VKD3DSPSM_SIGN: shader_addline(buffer, "_bx2"); break;
+ case VKD3DSPSM_SIGNNEG: shader_addline(buffer, "_bx2"); break;
+ case VKD3DSPSM_COMP: break;
+ case VKD3DSPSM_X2: shader_addline(buffer, "_x2"); break;
+ case VKD3DSPSM_X2NEG: shader_addline(buffer, "_x2"); break;
+ case VKD3DSPSM_DZ: shader_addline(buffer, "_dz"); break;
+ case VKD3DSPSM_DW: shader_addline(buffer, "_dw"); break;
+ case VKD3DSPSM_ABSNEG: shader_addline(buffer, ")"); break;
+ case VKD3DSPSM_ABS: shader_addline(buffer, ")"); break;
+ default: shader_addline(buffer, "_unknown_modifier(%#x)", src_modifier);
+ }
+
+ if (swizzle != VKD3D_NO_SWIZZLE)
+ {
+ static const char swizzle_chars[] = "xyzw";
+ DWORD swizzle_x = (swizzle >> VKD3D_SWIZZLE_SHIFT(0)) & VKD3D_SWIZZLE_MASK;
+ DWORD swizzle_y = (swizzle >> VKD3D_SWIZZLE_SHIFT(1)) & VKD3D_SWIZZLE_MASK;
+ DWORD swizzle_z = (swizzle >> VKD3D_SWIZZLE_SHIFT(2)) & VKD3D_SWIZZLE_MASK;
+ DWORD swizzle_w = (swizzle >> VKD3D_SWIZZLE_SHIFT(3)) & VKD3D_SWIZZLE_MASK;
+
+ if (swizzle_x == swizzle_y
+ && swizzle_x == swizzle_z
+ && swizzle_x == swizzle_w)
+ {
+ shader_addline(buffer, ".%c", swizzle_chars[swizzle_x]);
+ }
+ else
+ {
+ shader_addline(buffer, ".%c%c%c%c", swizzle_chars[swizzle_x], swizzle_chars[swizzle_y],
+ swizzle_chars[swizzle_z], swizzle_chars[swizzle_w]);
+ }
+ }
+}
+
+static void shader_dump_ins_modifiers(struct vkd3d_string_buffer *buffer,
+ const struct vkd3d_shader_dst_param *dst)
+{
+ DWORD mmask = dst->modifiers;
+
+ switch (dst->shift)
+ {
+ case 0: break;
+ case 13: shader_addline(buffer, "_d8"); break;
+ case 14: shader_addline(buffer, "_d4"); break;
+ case 15: shader_addline(buffer, "_d2"); break;
+ case 1: shader_addline(buffer, "_x2"); break;
+ case 2: shader_addline(buffer, "_x4"); break;
+ case 3: shader_addline(buffer, "_x8"); break;
+ default: shader_addline(buffer, "_unhandled_shift(%d)", dst->shift); break;
+ }
+
+ if (mmask & VKD3DSPDM_SATURATE) shader_addline(buffer, "_sat");
+ if (mmask & VKD3DSPDM_PARTIALPRECISION) shader_addline(buffer, "_pp");
+ if (mmask & VKD3DSPDM_MSAMPCENTROID) shader_addline(buffer, "_centroid");
+
+ mmask &= ~(VKD3DSPDM_SATURATE | VKD3DSPDM_PARTIALPRECISION | VKD3DSPDM_MSAMPCENTROID);
+ if (mmask) FIXME("Unrecognised modifier %#x.\n", mmask);
+}
+
+static void shader_dump_primitive_type(struct vkd3d_string_buffer *buffer,
+ const struct vkd3d_shader_primitive_type *primitive_type)
+{
+ switch (primitive_type->type)
+ {
+ case VKD3D_PT_UNDEFINED:
+ shader_addline(buffer, "undefined");
+ break;
+ case VKD3D_PT_POINTLIST:
+ shader_addline(buffer, "pointlist");
+ break;
+ case VKD3D_PT_LINELIST:
+ shader_addline(buffer, "linelist");
+ break;
+ case VKD3D_PT_LINESTRIP:
+ shader_addline(buffer, "linestrip");
+ break;
+ case VKD3D_PT_TRIANGLELIST:
+ shader_addline(buffer, "trianglelist");
+ break;
+ case VKD3D_PT_TRIANGLESTRIP:
+ shader_addline(buffer, "trianglestrip");
+ break;
+ case VKD3D_PT_TRIANGLEFAN:
+ shader_addline(buffer, "trianglefan");
+ break;
+ case VKD3D_PT_LINELIST_ADJ:
+ shader_addline(buffer, "linelist_adj");
+ break;
+ case VKD3D_PT_LINESTRIP_ADJ:
+ shader_addline(buffer, "linestrip_adj");
+ break;
+ case VKD3D_PT_TRIANGLELIST_ADJ:
+ shader_addline(buffer, "trianglelist_adj");
+ break;
+ case VKD3D_PT_TRIANGLESTRIP_ADJ:
+ shader_addline(buffer, "trianglestrip_adj");
+ break;
+ case VKD3D_PT_PATCH:
+ shader_addline(buffer, "patch%u", primitive_type->patch_vertex_count);
+ break;
+ default:
+ shader_addline(buffer, "<unrecognized_primitive_type %#x>", primitive_type->type);
+ break;
+ }
+}
+
+static void shader_dump_interpolation_mode(struct vkd3d_string_buffer *buffer,
+ enum vkd3d_shader_interpolation_mode interpolation_mode)
+{
+ switch (interpolation_mode)
+ {
+ case VKD3DSIM_CONSTANT:
+ shader_addline(buffer, "constant");
+ break;
+ case VKD3DSIM_LINEAR:
+ shader_addline(buffer, "linear");
+ break;
+ case VKD3DSIM_LINEAR_CENTROID:
+ shader_addline(buffer, "linear centroid");
+ break;
+ case VKD3DSIM_LINEAR_NOPERSPECTIVE:
+ shader_addline(buffer, "linear noperspective");
+ break;
+ case VKD3DSIM_LINEAR_SAMPLE:
+ shader_addline(buffer, "linear sample");
+ break;
+ case VKD3DSIM_LINEAR_NOPERSPECTIVE_CENTROID:
+ shader_addline(buffer, "linear noperspective centroid");
+ break;
+ case VKD3DSIM_LINEAR_NOPERSPECTIVE_SAMPLE:
+ shader_addline(buffer, "linear noperspective sample");
+ break;
+ default:
+ shader_addline(buffer, "<unrecognized_interpolation_mode %#x>", interpolation_mode);
+ break;
+ }
+}
+
+void vkd3d_shader_trace(void *data)
+{
+ struct vkd3d_shader_version shader_version;
+ struct vkd3d_string_buffer buffer;
+ const char *type_prefix;
+ const char *p, *q;
+ const DWORD *ptr;
+ DWORD i;
+
+ if (!string_buffer_init(&buffer))
+ {
+ ERR("Failed to initialize string buffer.\n");
+ return;
+ }
+
+ shader_sm4_read_header(data, &ptr, &shader_version);
+
+ TRACE("Parsing %p.\n", ptr);
+
+ switch (shader_version.type)
+ {
+ case VKD3D_SHADER_TYPE_VERTEX:
+ type_prefix = "vs";
+ break;
+
+ case VKD3D_SHADER_TYPE_HULL:
+ type_prefix = "hs";
+ break;
+
+ case VKD3D_SHADER_TYPE_DOMAIN:
+ type_prefix = "ds";
+ break;
+
+ case VKD3D_SHADER_TYPE_GEOMETRY:
+ type_prefix = "gs";
+ break;
+
+ case VKD3D_SHADER_TYPE_PIXEL:
+ type_prefix = "ps";
+ break;
+
+ case VKD3D_SHADER_TYPE_COMPUTE:
+ type_prefix = "cs";
+ break;
+
+ default:
+ FIXME("Unhandled shader type %#x.\n", shader_version.type);
+ type_prefix = "unknown";
+ break;
+ }
+
+ shader_addline(&buffer, "%s_%u_%u\n", type_prefix, shader_version.major, shader_version.minor);
+
+ while (!shader_sm4_is_end(data, &ptr))
+ {
+ struct vkd3d_shader_instruction ins;
+
+ shader_sm4_read_instruction(data, &ptr, &ins);
+ if (ins.handler_idx == VKD3DSIH_TABLE_SIZE)
+ {
+ WARN("Skipping unrecognized instruction.\n");
+ shader_addline(&buffer, "<unrecognized instruction>\n");
+ continue;
+ }
+
+ if (ins.handler_idx == VKD3DSIH_DCL || ins.handler_idx == VKD3DSIH_DCL_UAV_TYPED)
+ {
+ shader_dump_decl_usage(&buffer, &ins.declaration.semantic, ins.flags, &shader_version);
+ shader_dump_ins_modifiers(&buffer, &ins.declaration.semantic.reg);
+ shader_addline(&buffer, " ");
+ shader_dump_dst_param(&buffer, &ins.declaration.semantic.reg, &shader_version);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_CONSTANT_BUFFER)
+ {
+ shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_src_param(&buffer, &ins.declaration.src, &shader_version);
+ shader_addline(&buffer, ", %s",
+ ins.flags & VKD3DSI_INDEXED_DYNAMIC ? "dynamicIndexed" : "immediateIndexed");
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_FUNCTION_BODY)
+ {
+ shader_addline(&buffer, "%s fb%u",
+ shader_opcode_names[ins.handler_idx], ins.declaration.index);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_FUNCTION_TABLE)
+ {
+ shader_addline(&buffer, "%s ft%u = {...}",
+ shader_opcode_names[ins.handler_idx], ins.declaration.index);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_GLOBAL_FLAGS)
+ {
+ shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_global_flags(&buffer, ins.flags);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_HS_MAX_TESSFACTOR)
+ {
+ shader_addline(&buffer, "%s %.8e", shader_opcode_names[ins.handler_idx],
+ ins.declaration.max_tessellation_factor);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER)
+ {
+ shader_addline(&buffer, "%s {\n", shader_opcode_names[ins.handler_idx]);
+ for (i = 0; i < ins.declaration.icb->vec4_count; ++i)
+ {
+ shader_addline(&buffer, " {0x%08x, 0x%08x, 0x%08x, 0x%08x},\n",
+ ins.declaration.icb->data[4 * i + 0],
+ ins.declaration.icb->data[4 * i + 1],
+ ins.declaration.icb->data[4 * i + 2],
+ ins.declaration.icb->data[4 * i + 3]);
+ }
+ shader_addline(&buffer, "}");
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_INDEX_RANGE)
+ {
+ shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_dst_param(&buffer, &ins.declaration.index_range.first_register, &shader_version);
+ shader_addline(&buffer, " %u", ins.declaration.index_range.last_register);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_INDEXABLE_TEMP)
+ {
+ shader_addline(&buffer, "%s x[%u][%u], %u", shader_opcode_names[ins.handler_idx],
+ ins.declaration.indexable_temp.register_idx,
+ ins.declaration.indexable_temp.register_size,
+ ins.declaration.indexable_temp.component_count);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_INPUT_PS)
+ {
+ shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_interpolation_mode(&buffer, ins.flags);
+ shader_addline(&buffer, " ");
+ shader_dump_dst_param(&buffer, &ins.declaration.dst, &shader_version);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_INPUT_PS_SGV
+ || ins.handler_idx == VKD3DSIH_DCL_INPUT_SGV
+ || ins.handler_idx == VKD3DSIH_DCL_INPUT_SIV
+ || ins.handler_idx == VKD3DSIH_DCL_OUTPUT_SIV)
+ {
+ shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_dst_param(&buffer, &ins.declaration.register_semantic.reg, &shader_version);
+ shader_addline(&buffer, ", ");
+ shader_dump_shader_input_sysval_semantic(&buffer, ins.declaration.register_semantic.sysval_semantic);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_INPUT_PS_SIV)
+ {
+ shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_interpolation_mode(&buffer, ins.flags);
+ shader_addline(&buffer, " ");
+ shader_dump_dst_param(&buffer, &ins.declaration.register_semantic.reg, &shader_version);
+ shader_addline(&buffer, ", ");
+ shader_dump_shader_input_sysval_semantic(&buffer, ins.declaration.register_semantic.sysval_semantic);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_INPUT
+ || ins.handler_idx == VKD3DSIH_DCL_OUTPUT)
+ {
+ shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_dst_param(&buffer, &ins.declaration.dst, &shader_version);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_INPUT_PRIMITIVE
+ || ins.handler_idx == VKD3DSIH_DCL_OUTPUT_TOPOLOGY)
+ {
+ shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_primitive_type(&buffer, &ins.declaration.primitive_type);
+ }
+ else if (ins.handler_idx == VKD3DSIH_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 == VKD3DSIH_DCL_RESOURCE_RAW)
+ {
+ shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_dst_param(&buffer, &ins.declaration.dst, &shader_version);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_RESOURCE_STRUCTURED)
+ {
+ shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_dst_param(&buffer, &ins.declaration.structured_resource.reg, &shader_version);
+ shader_addline(&buffer, ", %u", ins.declaration.structured_resource.byte_stride);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_SAMPLER)
+ {
+ shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_dst_param(&buffer, &ins.declaration.dst, &shader_version);
+ if (ins.flags == VKD3DSI_SAMPLER_COMPARISON_MODE)
+ shader_addline(&buffer, ", comparisonMode");
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_TEMPS
+ || ins.handler_idx == VKD3DSIH_DCL_GS_INSTANCES
+ || ins.handler_idx == VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT
+ || ins.handler_idx == VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT
+ || ins.handler_idx == VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT
+ || ins.handler_idx == VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT
+ || ins.handler_idx == VKD3DSIH_DCL_VERTICES_OUT)
+ {
+ shader_addline(&buffer, "%s %u", shader_opcode_names[ins.handler_idx], ins.declaration.count);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_TESSELLATOR_DOMAIN)
+ {
+ shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_tessellator_domain(&buffer, ins.declaration.tessellator_domain);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE)
+ {
+ shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_tessellator_output_primitive(&buffer, ins.declaration.tessellator_output_primitive);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_TESSELLATOR_PARTITIONING)
+ {
+ shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_tessellator_partitioning(&buffer, ins.declaration.tessellator_partitioning);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_TGSM_RAW)
+ {
+ shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_dst_param(&buffer, &ins.declaration.tgsm_raw.reg, &shader_version);
+ shader_addline(&buffer, ", %u", ins.declaration.tgsm_raw.byte_count);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_TGSM_STRUCTURED)
+ {
+ shader_addline(&buffer, "%s ", shader_opcode_names[ins.handler_idx]);
+ shader_dump_dst_param(&buffer, &ins.declaration.tgsm_structured.reg, &shader_version);
+ shader_addline(&buffer, ", %u, %u", ins.declaration.tgsm_structured.byte_stride,
+ ins.declaration.tgsm_structured.structure_count);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_THREAD_GROUP)
+ {
+ shader_addline(&buffer, "%s %u, %u, %u", shader_opcode_names[ins.handler_idx],
+ ins.declaration.thread_group_size.x,
+ ins.declaration.thread_group_size.y,
+ ins.declaration.thread_group_size.z);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_UAV_RAW)
+ {
+ shader_addline(&buffer, "%s", shader_opcode_names[ins.handler_idx]);
+ shader_dump_uav_flags(&buffer, ins.flags);
+ shader_addline(&buffer, " ");
+ shader_dump_dst_param(&buffer, &ins.declaration.dst, &shader_version);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DCL_UAV_STRUCTURED)
+ {
+ shader_addline(&buffer, "%s", shader_opcode_names[ins.handler_idx]);
+ shader_dump_uav_flags(&buffer, ins.flags);
+ shader_addline(&buffer, " ");
+ shader_dump_dst_param(&buffer, &ins.declaration.structured_resource.reg, &shader_version);
+ shader_addline(&buffer, ", %u", ins.declaration.structured_resource.byte_stride);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DEF)
+ {
+ 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),
+ ins.src[0].reg.u.immconst_float[0], ins.src[0].reg.u.immconst_float[1],
+ ins.src[0].reg.u.immconst_float[2], ins.src[0].reg.u.immconst_float[3]);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DEFI)
+ {
+ shader_addline(&buffer, "defi i%u = %d, %d, %d, %d", ins.dst[0].reg.idx[0].offset,
+ ins.src[0].reg.u.immconst_uint[0], ins.src[0].reg.u.immconst_uint[1],
+ ins.src[0].reg.u.immconst_uint[2], ins.src[0].reg.u.immconst_uint[3]);
+ }
+ else if (ins.handler_idx == VKD3DSIH_DEFB)
+ {
+ shader_addline(&buffer, "defb b%u = %s",
+ ins.dst[0].reg.idx[0].offset, ins.src[0].reg.u.immconst_uint[0] ? "true" : "false");
+ }
+ else
+ {
+ if (ins.predicate)
+ {
+ shader_addline(&buffer, "(");
+ shader_dump_src_param(&buffer, ins.predicate, &shader_version);
+ shader_addline(&buffer, ") ");
+ }
+
+ /* PixWin marks instructions with the coissue flag with a '+' */
+ if (ins.coissue)
+ shader_addline(&buffer, "+");
+
+ shader_addline(&buffer, "%s", shader_opcode_names[ins.handler_idx]);
+
+ if (ins.handler_idx == VKD3DSIH_BREAKP
+ || ins.handler_idx == VKD3DSIH_CONTINUEP
+ || ins.handler_idx == VKD3DSIH_IF
+ || ins.handler_idx == VKD3DSIH_RETP
+ || ins.handler_idx == VKD3DSIH_TEXKILL)
+ {
+ switch (ins.flags)
+ {
+ case VKD3D_SHADER_CONDITIONAL_OP_NZ: shader_addline(&buffer, "_nz"); break;
+ case VKD3D_SHADER_CONDITIONAL_OP_Z: shader_addline(&buffer, "_z"); break;
+ default: shader_addline(&buffer, "_unrecognized(%#x)", ins.flags); break;
+ }
+ }
+ else if (ins.handler_idx == VKD3DSIH_IFC
+ || ins.handler_idx == VKD3DSIH_BREAKC)
+ {
+ switch (ins.flags)
+ {
+ case VKD3D_SHADER_REL_OP_GT: shader_addline(&buffer, "_gt"); break;
+ case VKD3D_SHADER_REL_OP_EQ: shader_addline(&buffer, "_eq"); break;
+ case VKD3D_SHADER_REL_OP_GE: shader_addline(&buffer, "_ge"); break;
+ case VKD3D_SHADER_REL_OP_LT: shader_addline(&buffer, "_lt"); break;
+ case VKD3D_SHADER_REL_OP_NE: shader_addline(&buffer, "_ne"); break;
+ case VKD3D_SHADER_REL_OP_LE: shader_addline(&buffer, "_le"); break;
+ default: shader_addline(&buffer, "_(%u)", ins.flags);
+ }
+ }
+ else if (ins.handler_idx == VKD3DSIH_TEX
+ && shader_version.major >= 2
+ && (ins.flags & VKD3DSI_TEXLD_PROJECT))
+ {
+ shader_addline(&buffer, "p");
+ }
+ else if (ins.handler_idx == VKD3DSIH_RESINFO && ins.flags)
+ {
+ switch (ins.flags)
+ {
+ case VKD3DSI_RESINFO_RCP_FLOAT: shader_addline(&buffer, "_rcpFloat"); break;
+ case VKD3DSI_RESINFO_UINT: shader_addline(&buffer, "_uint"); break;
+ default: shader_addline(&buffer, "_unrecognized(%#x)", ins.flags);
+ }
+ }
+ else if (ins.handler_idx == VKD3DSIH_SAMPLE_INFO && ins.flags)
+ {
+ switch (ins.flags)
+ {
+ case VKD3DSI_SAMPLE_INFO_UINT: shader_addline(&buffer, "_uint"); break;
+ default: shader_addline(&buffer, "_unrecognized(%#x)", ins.flags);
+ }
+ }
+ else if (ins.handler_idx == VKD3DSIH_SYNC)
+ {
+ shader_dump_sync_flags(&buffer, ins.flags);
+ }
+ else
+ {
+ shader_dump_precise_flags(&buffer, ins.flags);
+ }
+
+ if (vkd3d_shader_instruction_has_texel_offset(&ins))
+ shader_addline(&buffer, "(%d,%d,%d)", ins.texel_offset.u, ins.texel_offset.v, ins.texel_offset.w);
+
+ for (i = 0; i < ins.dst_count; ++i)
+ {
+ shader_dump_ins_modifiers(&buffer, &ins.dst[i]);
+ shader_addline(&buffer, !i ? " " : ", ");
+ shader_dump_dst_param(&buffer, &ins.dst[i], &shader_version);
+ }
+
+ /* Other source tokens */
+ for (i = ins.dst_count; i < (ins.dst_count + ins.src_count); ++i)
+ {
+ shader_addline(&buffer, !i ? " " : ", ");
+ shader_dump_src_param(&buffer, &ins.src[i - ins.dst_count], &shader_version);
+ }
+ }
+ shader_addline(&buffer, "\n");
+ }
+
+ for (p = buffer.buffer; *p; p = q)
+ {
+ if (!(q = strstr(p, "\n")))
+ q = p + strlen(p);
+ else
+ ++q;
+ TRACE(" %.*s", (int)(q - p), p);
+ }
+
+ string_buffer_free(&buffer);
+}
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 1de56ac935a2..f6bb96455771 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -76,6 +76,9 @@ int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc,
if ((ret = vkd3d_shader_parser_init(&parser, dxbc)) < 0)
return ret;
+ if (TRACE_ON())
+ vkd3d_shader_trace(parser.data);
+
if (!(spirv_compiler = vkd3d_dxbc_compiler_create(&parser.shader_version,
&parser.shader_desc, compiler_options, shader_interface, compile_args, &scan_info)))
{
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index ba8c6c906958..8ed700be3756 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -479,6 +479,9 @@ enum vkd3d_tessellator_partitioning
VKD3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = 4,
};
+
+#define VKD3DSI_TEXLD_PROJECT 0x1
+
#define VKD3DSI_INDEXED_DYNAMIC 0x4
#define VKD3DSI_RESINFO_RCP_FLOAT 0x1
#define VKD3DSI_RESINFO_UINT 0x2
@@ -573,7 +576,8 @@ struct vkd3d_shader_register
enum vkd3d_immconst_type immconst_type;
union
{
- DWORD immconst_data[VKD3D_VEC4_SIZE];
+ DWORD immconst_uint[VKD3D_VEC4_SIZE];
+ float immconst_float[VKD3D_VEC4_SIZE];
unsigned fp_body_idx;
} u;
};
@@ -743,6 +747,8 @@ struct vkd3d_shader_instruction
const struct vkd3d_shader_dst_param *dst;
const struct vkd3d_shader_src_param *src;
struct vkd3d_shader_texel_offset texel_offset;
+ bool coissue;
+ const struct vkd3d_shader_src_param *predicate;
union
{
struct vkd3d_shader_semantic semantic;
@@ -772,6 +778,8 @@ static inline BOOL vkd3d_shader_instruction_has_texel_offset(const struct vkd3d_
return ins->texel_offset.u || ins->texel_offset.v || ins->texel_offset.w;
}
+void vkd3d_shader_trace(void *data) DECLSPEC_HIDDEN;
+
void *shader_sm4_init(const DWORD *byte_code, size_t byte_code_size,
const struct vkd3d_shader_signature *output_signature) DECLSPEC_HIDDEN;
void shader_sm4_free(void *data) DECLSPEC_HIDDEN;
--
2.16.1
More information about the wine-devel
mailing list