From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Makefile.am b/Makefile.am index 494e3788b1a7..52b35859a546 100644 --- a/Makefile.am +++ b/Makefile.am @@ -71,7 +71,7 @@ libvkd3d_shader_la_SOURCES = \ libs/vkd3d-shader/vkd3d_shader.map \ libs/vkd3d-shader/vkd3d_shader_main.c \ libs/vkd3d-shader/vkd3d_shader_private.h -libvkd3d_shader_la_CFLAGS = @SPIRV_TOOLS_CFLAGS@ +libvkd3d_shader_la_CFLAGS = $(AM_CFLAGS) @SPIRV_TOOLS_CFLAGS@ libvkd3d_shader_la_LIBADD = @SPIRV_TOOLS_LIBS@ if HAVE_LD_VERSION_SCRIPT libvkd3d_shader_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libs/vkd3d-shader/vkd3d_shader.map @@ -130,7 +130,7 @@ tests_d3d12_LDADD = $(LDADD) @PTHREAD_LIBS@ tests_vkd3d_api_LDADD = libvkd3d.la @VULKAN_LIBS@
DEMOS_LDADD = $(LDADD) libvkd3d-shader.la @XCB_LIBS@ @VULKAN_LIBS@ -DEMOS_CFLAGS = @XCB_CFLAGS@ +DEMOS_CFLAGS = $(AM_CFLAGS) @XCB_CFLAGS@ noinst_PROGRAMS += $(vkd3d_demos) EXTRA_DIST += $(vkd3d_test_headers) $(vkd3d_demos_headers)
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- libs/vkd3d-shader/spirv.c | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index f4c942133db5..a59fdb6eab45 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2779,33 +2779,9 @@ static uint32_t vkd3d_spirv_front_facing_fixup(struct vkd3d_dxbc_compiler *compi return vkd3d_dxbc_compiler_emit_bool_to_int(compiler, 1, front_facing_id); }
-/* The Vulkan spec says: - * - * "The variable decorated with GlobalInvocationId must be declared as a - * three-component vector of 32-bit integers." - * - * "The variable decorated with LocalInvocationId must be declared as a - * three-component vector of 32-bit integers." - * - * "The variable decorated with WorkgroupId must be declared as a - * three-component vector of 32-bit integers." - * - * "The variable decorated with FragCoord must be declared as a - * four-component vector of 32-bit floating-point values." - * - * "The variable decorated with FragDepth must be declared as a scalar 32-bit - * floating-point value." - * - * "Any variable decorated with Position must be declared as a four-component - * vector of 32-bit floating-point values." - * - * "The variable decorated with VertexIndex must be declared as a scalar - * 32-bit integer." - * - * "The variable decorated with InstanceIndex must be declared as a scalar - * 32-bit integer." - * - * "The variable decorated with FrontFacing must be declared as a boolean." +/* + * The following table is based on the "14.6. Built-In Variables" section from + * the Vulkan spec. */ static const struct vkd3d_spirv_builtin { @@ -2835,6 +2811,8 @@ vkd3d_spirv_builtin_table[] = {VKD3D_SIV_VERTEX_ID, ~0u, VKD3D_TYPE_INT, 1, SpvBuiltInVertexIndex}, {VKD3D_SIV_INSTANCE_ID, ~0u, VKD3D_TYPE_INT, 1, SpvBuiltInInstanceIndex, vkd3d_spirv_instance_id_fixup},
+ {VKD3D_SIV_RENDER_TARGET_ARRAY_INDEX, ~0u, VKD3D_TYPE_INT, 1, SpvBuiltInLayer}, + {VKD3D_SIV_IS_FRONT_FACE, ~0u, VKD3D_TYPE_BOOL, 1, SpvBuiltInFrontFacing, vkd3d_spirv_front_facing_fixup}, };
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- libs/vkd3d-shader/dxbc.c | 7 ++++++- libs/vkd3d-shader/vkd3d_shader_private.h | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index 87b2d718ce78..c8e5b0802987 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -56,6 +56,9 @@ #define VKD3D_SM4_GLOBAL_FLAGS_SHIFT 11 #define VKD3D_SM4_GLOBAL_FLAGS_MASK (0xffu << VKD3D_SM4_GLOBAL_FLAGS_SHIFT)
+#define VKD3D_SM5_PRECISE_SHIFT 19 +#define VKD3D_SM5_PRECISE_MASK (0xfu << VKD3D_SM5_PRECISE_SHIFT) + #define VKD3D_SM5_CONTROL_POINT_COUNT_SHIFT 11 #define VKD3D_SM5_CONTROL_POINT_COUNT_MASK (0xffu << VKD3D_SM5_CONTROL_POINT_COUNT_SHIFT)
@@ -1641,6 +1644,7 @@ void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct vkd3d_sha unsigned int i, len; SIZE_T remaining; const DWORD *p; + DWORD precise;
list_move_head(&priv->src_free, &priv->src);
@@ -1703,12 +1707,13 @@ void shader_sm4_read_instruction(void *data, const DWORD **ptr, struct vkd3d_sha shader_sm4_read_instruction_modifier(previous_token = *p++, ins);
ins->flags = (opcode_token & VKD3D_SM4_INSTRUCTION_FLAGS_MASK) >> VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT; - if (ins->flags & VKD3D_SM4_INSTRUCTION_FLAG_SATURATE) { ins->flags &= ~VKD3D_SM4_INSTRUCTION_FLAG_SATURATE; instruction_dst_modifier = VKD3DSPDM_SATURATE; } + precise = (opcode_token & VKD3D_SM5_PRECISE_MASK) >> VKD3D_SM5_PRECISE_SHIFT; + ins->flags |= precise << VKD3DSI_PRECISE_SHIFT;
for (i = 0; i < ins->dst_count; ++i) { diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 4aeeb50e8817..1721977581df 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -480,6 +480,14 @@ enum vkd3d_tessellator_partitioning #define VKD3DSI_SAMPLE_INFO_UINT 0x1 #define VKD3DSI_SAMPLER_COMPARISON_MODE 0x1
+#define VKD3DSI_PRECISE_X 0x100 +#define VKD3DSI_PRECISE_Y 0x200 +#define VKD3DSI_PRECISE_Z 0x400 +#define VKD3DSI_PRECISE_W 0x800 +#define VKD3DSI_PRECISE_XYZW (VKD3DSI_PRECISE_X | VKD3DSI_PRECISE_Y \ + | VKD3DSI_PRECISE_Z | VKD3DSI_PRECISE_W) +#define VKD3DSI_PRECISE_SHIFT 8 + enum vkd3d_shader_rel_op { VKD3D_SHADER_REL_OP_GT = 1,
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- libs/vkd3d-shader/dxbc.c | 9 ++++++++- libs/vkd3d-shader/vkd3d_shader_private.h | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index c8e5b0802987..b8e22ac78081 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -295,6 +295,7 @@ enum vkd3d_sm4_opcode VKD3D_SM5_OP_IMM_ATOMIC_UMAX = 0xbc, VKD3D_SM5_OP_IMM_ATOMIC_UMIN = 0xbd, VKD3D_SM5_OP_SYNC = 0xbe, + VKD3D_SM5_OP_EVAL_SAMPLE_INDEX = 0xcc, VKD3D_SM5_OP_DCL_GS_INSTANCES = 0xce, };
@@ -312,6 +313,7 @@ enum vkd3d_sm4_register_type VKD3D_SM4_RT_PRIMID = 0x0b, VKD3D_SM4_RT_DEPTHOUT = 0x0c, VKD3D_SM4_RT_NULL = 0x0d, + VKD3D_SM4_RT_RASTERIZER = 0x0e, VKD3D_SM4_RT_OMASK = 0x0f, VKD3D_SM5_RT_STREAM = 0x10, VKD3D_SM5_RT_FUNCTION_BODY = 0x11, @@ -331,6 +333,8 @@ enum vkd3d_sm4_register_type VKD3D_SM5_RT_COVERAGE = 0x23, VKD3D_SM5_RT_LOCAL_THREAD_INDEX = 0x24, VKD3D_SM5_RT_GS_INSTANCE_ID = 0x25, + VKD3D_SM5_RT_DEPTHOUT_GREATER_EQUAL = 0x26, + VKD3D_SM5_RT_DEPTHOUT_LESS_EQUAL = 0x27, };
enum vkd3d_sm4_output_primitive_type @@ -1103,6 +1107,7 @@ static const struct vkd3d_sm4_opcode_info opcode_table[] = {VKD3D_SM5_OP_IMM_ATOMIC_UMIN, VKD3DSIH_IMM_ATOMIC_UMIN, "uU", "iu"}, {VKD3D_SM5_OP_SYNC, VKD3DSIH_SYNC, "", "", shader_sm5_read_sync}, + {VKD3D_SM5_OP_EVAL_SAMPLE_INDEX, VKD3DSIH_EVAL_SAMPLE_INDEX, "f", "fi"}, {VKD3D_SM5_OP_DCL_GS_INSTANCES, VKD3DSIH_DCL_GS_INSTANCES, "", "", shader_sm4_read_declaration_count}, }; @@ -1123,7 +1128,7 @@ static const enum vkd3d_shader_register_type register_type_table[] = /* VKD3D_SM4_RT_PRIMID */ VKD3DSPR_PRIMID, /* VKD3D_SM4_RT_DEPTHOUT */ VKD3DSPR_DEPTHOUT, /* VKD3D_SM4_RT_NULL */ VKD3DSPR_NULL, - /* UNKNOWN */ ~0u, + /* VKD3D_SM4_RT_RASTERIZER */ VKD3DSPR_RASTERIZER, /* VKD3D_SM4_RT_OMASK */ VKD3DSPR_SAMPLEMASK, /* VKD3D_SM5_RT_STREAM */ VKD3DSPR_STREAM, /* VKD3D_SM5_RT_FUNCTION_BODY */ VKD3DSPR_FUNCTIONBODY, @@ -1147,6 +1152,8 @@ static const enum vkd3d_shader_register_type register_type_table[] = /* VKD3D_SM5_RT_COVERAGE */ VKD3DSPR_COVERAGE, /* VKD3D_SM5_RT_LOCAL_THREAD_INDEX */ VKD3DSPR_LOCALTHREADINDEX, /* VKD3D_SM5_RT_GS_INSTANCE_ID */ VKD3DSPR_GSINSTID, + /* VKD3D_SM5_RT_DEPTHOUT_GREATER_EQUAL */ VKD3DSPR_DEPTHOUTGE, + /* VKD3D_SM5_RT_DEPTHOUT_LESS_EQUAL */ VKD3DSPR_DEPTHOUTLE, };
static const struct vkd3d_sm4_opcode_info *get_opcode_info(enum vkd3d_sm4_opcode opcode) diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 1721977581df..ba8c6c906958 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -156,6 +156,7 @@ enum VKD3D_SHADER_INSTRUCTION_HANDLER VKD3DSIH_ENDREP, VKD3DSIH_ENDSWITCH, VKD3DSIH_EQ, + VKD3DSIH_EVAL_SAMPLE_INDEX, VKD3DSIH_EXP, VKD3DSIH_EXPP, VKD3DSIH_F16TOF32, @@ -352,6 +353,9 @@ enum vkd3d_shader_register_type VKD3DSPR_COVERAGE, VKD3DSPR_SAMPLEMASK, VKD3DSPR_GSINSTID, + VKD3DSPR_DEPTHOUTGE, + VKD3DSPR_DEPTHOUTLE, + VKD3DSPR_RASTERIZER,
VKD3DSPR_INVALID = ~0u, }; @@ -436,6 +440,7 @@ enum vkd3d_shader_interpolation_mode enum vkd3d_shader_global_flags { VKD3DSGF_REFACTORING_ALLOWED = 0x1, + VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL = 0x4, VKD3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS = 0x8, };
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@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;
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com
From: Józef Kucia jkucia@codeweavers.com
Signed-off-by: Józef Kucia jkucia@codeweavers.com --- libs/vkd3d/resource.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index e37b03bc005f..acd3bada63ec 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -999,6 +999,11 @@ static bool vkd3d_create_buffer_view(struct d3d12_device *device, static void vkd3d_set_view_swizzle_for_format(VkComponentMapping *components, const struct vkd3d_format *format, bool allowed_swizzle) { + components->r = VK_COMPONENT_SWIZZLE_IDENTITY; + components->g = VK_COMPONENT_SWIZZLE_IDENTITY; + components->b = VK_COMPONENT_SWIZZLE_IDENTITY; + components->a = VK_COMPONENT_SWIZZLE_IDENTITY; + if (format->vk_aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) { if (allowed_swizzle) @@ -1007,7 +1012,6 @@ static void vkd3d_set_view_swizzle_for_format(VkComponentMapping *components, components->g = VK_COMPONENT_SWIZZLE_R; components->b = VK_COMPONENT_SWIZZLE_ZERO; components->a = VK_COMPONENT_SWIZZLE_ZERO; - return; } else { @@ -1024,18 +1028,12 @@ static void vkd3d_set_view_swizzle_for_format(VkComponentMapping *components, components->g = VK_COMPONENT_SWIZZLE_ZERO; components->b = VK_COMPONENT_SWIZZLE_ZERO; components->a = VK_COMPONENT_SWIZZLE_R; - return; } else { FIXME("Alpha swizzle is not supported.\n"); } } - - components->r = VK_COMPONENT_SWIZZLE_R; - components->g = VK_COMPONENT_SWIZZLE_G; - components->b = VK_COMPONENT_SWIZZLE_B; - components->a = VK_COMPONENT_SWIZZLE_A; }
static VkResult vkd3d_create_texture_view(struct d3d12_device *device,
Signed-off-by: Henri Verbeet hverbeet@codeweavers.com