Files
wine-staging/patches/vkd3d-latest/0001-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch
Alistair Leslie-Hughes 7cd95e9f79 Updated vkd3d-latest patchset
Squashed.

Updated to vkd3d 1.17+
2025-08-22 08:09:57 +10:00

28498 lines
1.2 MiB

From 900a91b2b7e2260fe4eefb78e1db3dffa2360d23 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Mon, 26 May 2025 07:03:34 +1000
Subject: [PATCH] Updated vkd3d to 44fffee5e1331e1c7e10489d84723c3b9dad7e17.
---
dlls/msado15/tests/msado15.c | 2 +-
libs/vkd3d/include/private/vkd3d_common.h | 3 +-
.../include/private/vkd3d_shader_utils.h | 4 -
libs/vkd3d/include/private/vkd3d_version.h | 2 +-
libs/vkd3d/include/vkd3d_shader.h | 7 +
libs/vkd3d/libs/vkd3d-common/blob.c | 1 +
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 626 +--
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 459 +-
libs/vkd3d/libs/vkd3d-shader/dxbc.c | 10 +-
libs/vkd3d/libs/vkd3d-shader/dxil.c | 1752 ++++----
libs/vkd3d/libs/vkd3d-shader/fx.c | 1381 ++++--
libs/vkd3d/libs/vkd3d-shader/glsl.c | 320 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 289 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 47 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.l | 1 +
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 128 +-
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 1917 +++++---
libs/vkd3d/libs/vkd3d-shader/ir.c | 4000 +++++++++++++----
libs/vkd3d/libs/vkd3d-shader/msl.c | 1064 ++++-
libs/vkd3d/libs/vkd3d-shader/preproc.h | 2 +-
libs/vkd3d/libs/vkd3d-shader/preproc.l | 39 +-
libs/vkd3d/libs/vkd3d-shader/spirv.c | 1477 +++---
libs/vkd3d/libs/vkd3d-shader/tpf.c | 1045 +++--
.../libs/vkd3d-shader/vkd3d_shader_main.c | 462 +-
.../libs/vkd3d-shader/vkd3d_shader_private.h | 964 ++--
.../vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c | 2 +
libs/vkd3d/libs/vkd3d/command.c | 21 +-
libs/vkd3d/libs/vkd3d/device.c | 7 +-
libs/vkd3d/libs/vkd3d/resource.c | 73 +-
libs/vkd3d/libs/vkd3d/state.c | 36 +-
libs/vkd3d/libs/vkd3d/vkd3d_private.h | 13 +-
31 files changed, 10162 insertions(+), 5992 deletions(-)
diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c
index 03eaab92b39..3f4b55d2916 100644
--- a/dlls/msado15/tests/msado15.c
+++ b/dlls/msado15/tests/msado15.c
@@ -2023,8 +2023,8 @@ START_TEST(msado15)
setup_database();
test_Connection();
- test_Connection_Open();
test_ConnectionPoint();
+ test_Connection_Open();
test_ADORecordsetConstruction(FALSE);
test_ADORecordsetConstruction(TRUE);
test_Fields();
diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h
index beb23257fb7..0501e6a06c2 100644
--- a/libs/vkd3d/include/private/vkd3d_common.h
+++ b/libs/vkd3d/include/private/vkd3d_common.h
@@ -66,6 +66,7 @@
#define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9')
#define TAG_CLI4 VKD3D_MAKE_TAG('C', 'L', 'I', '4')
+#define TAG_CLIT VKD3D_MAKE_TAG('C', 'L', 'I', 'T')
#define TAG_CTAB VKD3D_MAKE_TAG('C', 'T', 'A', 'B')
#define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C')
#define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L')
@@ -278,7 +279,7 @@ static inline unsigned int vkd3d_popcount(unsigned int v)
{
#ifdef _MSC_VER
return __popcnt(v);
-#elif defined(__MINGW32__)
+#elif defined(HAVE_BUILTIN_POPCOUNT)
return __builtin_popcount(v);
#else
v -= (v >> 1) & 0x55555555;
diff --git a/libs/vkd3d/include/private/vkd3d_shader_utils.h b/libs/vkd3d/include/private/vkd3d_shader_utils.h
index 00052a89988..465734dfbff 100644
--- a/libs/vkd3d/include/private/vkd3d_shader_utils.h
+++ b/libs/vkd3d/include/private/vkd3d_shader_utils.h
@@ -21,10 +21,6 @@
#include "vkd3d_shader.h"
-#define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L')
-#define TAG_SHDR VKD3D_MAKE_TAG('S', 'H', 'D', 'R')
-#define TAG_SHEX VKD3D_MAKE_TAG('S', 'H', 'E', 'X')
-
static inline enum vkd3d_result vkd3d_shader_parse_dxbc_source_type(const struct vkd3d_shader_code *dxbc,
enum vkd3d_shader_source_type *type, char **messages)
{
diff --git a/libs/vkd3d/include/private/vkd3d_version.h b/libs/vkd3d/include/private/vkd3d_version.h
index 0edc4428022..687751d6a5f 100644
--- a/libs/vkd3d/include/private/vkd3d_version.h
+++ b/libs/vkd3d/include/private/vkd3d_version.h
@@ -1 +1 @@
-#define VKD3D_VCS_ID " (Wine bundled)"
+#define VKD3D_VCS_ID " (git a8ca1f95)"
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
index 30b6a070018..0fd3c67b7e0 100644
--- a/libs/vkd3d/include/vkd3d_shader.h
+++ b/libs/vkd3d/include/vkd3d_shader.h
@@ -1431,6 +1431,11 @@ enum vkd3d_shader_source_type
* Input is a raw FX section without container. \since 1.14
*/
VKD3D_SHADER_SOURCE_FX,
+ /**
+ * A D3DX texture shader. This is the format used for the 'tx_1_0' HLSL
+ * target profile. \since 1.17
+ */
+ VKD3D_SHADER_SOURCE_TX,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SOURCE_TYPE),
};
@@ -2761,6 +2766,7 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported
* - VKD3D_SHADER_SOURCE_HLSL to VKD3D_SHADER_TARGET_DXBC_TPF
* - VKD3D_SHADER_SOURCE_HLSL to VKD3D_SHADER_TARGET_FX
* - VKD3D_SHADER_SOURCE_FX to VKD3D_SHADER_TARGET_D3D_ASM
+ * - VKD3D_SHADER_SOURCE_TX to VKD3D_SHADER_TARGET_D3D_ASM
*
* Supported transformations can also be detected at runtime with the functions
* vkd3d_shader_get_supported_source_types() and
@@ -2960,6 +2966,7 @@ VKD3D_SHADER_API int vkd3d_shader_convert_root_signature(struct vkd3d_shader_ver
* - VKD3D_SHADER_SOURCE_DXBC_DXIL
* - VKD3D_SHADER_SOURCE_DXBC_TPF
* - VKD3D_SHADER_SOURCE_D3D_BYTECODE
+ * - VKD3D_SHADER_SOURCE_HLSL
*
* \param compile_info A chained structure containing scan parameters.
* \n
diff --git a/libs/vkd3d/libs/vkd3d-common/blob.c b/libs/vkd3d/libs/vkd3d-common/blob.c
index f60ef7db769..c2c6ad67804 100644
--- a/libs/vkd3d/libs/vkd3d-common/blob.c
+++ b/libs/vkd3d/libs/vkd3d-common/blob.c
@@ -20,6 +20,7 @@
#define WIDL_C_INLINE_WRAPPERS
#endif
#define COBJMACROS
+
#define CONST_VTABLE
#include "vkd3d.h"
#include "vkd3d_blob.h"
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
index 4521bfabd8e..6425a8f62d2 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
@@ -27,333 +27,6 @@
#include <stdio.h>
#include <math.h>
-static const char * const shader_opcode_names[] =
-{
- [VKD3DSIH_ABS ] = "abs",
- [VKD3DSIH_ACOS ] = "acos",
- [VKD3DSIH_ADD ] = "add",
- [VKD3DSIH_AND ] = "and",
- [VKD3DSIH_ASIN ] = "asin",
- [VKD3DSIH_ATAN ] = "atan",
- [VKD3DSIH_ATOMIC_AND ] = "atomic_and",
- [VKD3DSIH_ATOMIC_CMP_STORE ] = "atomic_cmp_store",
- [VKD3DSIH_ATOMIC_IADD ] = "atomic_iadd",
- [VKD3DSIH_ATOMIC_IMAX ] = "atomic_imax",
- [VKD3DSIH_ATOMIC_IMIN ] = "atomic_imin",
- [VKD3DSIH_ATOMIC_OR ] = "atomic_or",
- [VKD3DSIH_ATOMIC_UMAX ] = "atomic_umax",
- [VKD3DSIH_ATOMIC_UMIN ] = "atomic_umin",
- [VKD3DSIH_ATOMIC_XOR ] = "atomic_xor",
- [VKD3DSIH_BEM ] = "bem",
- [VKD3DSIH_BFI ] = "bfi",
- [VKD3DSIH_BFREV ] = "bfrev",
- [VKD3DSIH_BRANCH ] = "branch",
- [VKD3DSIH_BREAK ] = "break",
- [VKD3DSIH_BREAKC ] = "break",
- [VKD3DSIH_BREAKP ] = "breakp",
- [VKD3DSIH_BUFINFO ] = "bufinfo",
- [VKD3DSIH_CALL ] = "call",
- [VKD3DSIH_CALLNZ ] = "callnz",
- [VKD3DSIH_CASE ] = "case",
- [VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED ] = "check_access_fully_mapped",
- [VKD3DSIH_CMP ] = "cmp",
- [VKD3DSIH_CND ] = "cnd",
- [VKD3DSIH_CONTINUE ] = "continue",
- [VKD3DSIH_CONTINUEP ] = "continuec",
- [VKD3DSIH_COUNTBITS ] = "countbits",
- [VKD3DSIH_CRS ] = "crs",
- [VKD3DSIH_CUT ] = "cut",
- [VKD3DSIH_CUT_STREAM ] = "cut_stream",
- [VKD3DSIH_DADD ] = "dadd",
- [VKD3DSIH_DCL ] = "dcl",
- [VKD3DSIH_DCL_CONSTANT_BUFFER ] = "dcl_constantBuffer",
- [VKD3DSIH_DCL_FUNCTION_BODY ] = "dcl_function_body",
- [VKD3DSIH_DCL_FUNCTION_TABLE ] = "dcl_function_table",
- [VKD3DSIH_DCL_GLOBAL_FLAGS ] = "dcl_globalFlags",
- [VKD3DSIH_DCL_GS_INSTANCES ] = "dcl_gs_instances",
- [VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT] = "dcl_hs_fork_phase_instance_count",
- [VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT] = "dcl_hs_join_phase_instance_count",
- [VKD3DSIH_DCL_HS_MAX_TESSFACTOR ] = "dcl_hs_max_tessfactor",
- [VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER ] = "dcl_immediateConstantBuffer",
- [VKD3DSIH_DCL_INDEX_RANGE ] = "dcl_index_range",
- [VKD3DSIH_DCL_INDEXABLE_TEMP ] = "dcl_indexableTemp",
- [VKD3DSIH_DCL_INPUT ] = "dcl_input",
- [VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT ] = "dcl_input_control_point_count",
- [VKD3DSIH_DCL_INPUT_PRIMITIVE ] = "dcl_inputprimitive",
- [VKD3DSIH_DCL_INPUT_PS ] = "dcl_input_ps",
- [VKD3DSIH_DCL_INPUT_PS_SGV ] = "dcl_input_ps_sgv",
- [VKD3DSIH_DCL_INPUT_PS_SIV ] = "dcl_input_ps_siv",
- [VKD3DSIH_DCL_INPUT_SGV ] = "dcl_input_sgv",
- [VKD3DSIH_DCL_INPUT_SIV ] = "dcl_input_siv",
- [VKD3DSIH_DCL_INTERFACE ] = "dcl_interface",
- [VKD3DSIH_DCL_OUTPUT ] = "dcl_output",
- [VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT ] = "dcl_output_control_point_count",
- [VKD3DSIH_DCL_OUTPUT_SIV ] = "dcl_output_siv",
- [VKD3DSIH_DCL_OUTPUT_TOPOLOGY ] = "dcl_outputtopology",
- [VKD3DSIH_DCL_RESOURCE_RAW ] = "dcl_resource_raw",
- [VKD3DSIH_DCL_RESOURCE_STRUCTURED ] = "dcl_resource_structured",
- [VKD3DSIH_DCL_SAMPLER ] = "dcl_sampler",
- [VKD3DSIH_DCL_STREAM ] = "dcl_stream",
- [VKD3DSIH_DCL_TEMPS ] = "dcl_temps",
- [VKD3DSIH_DCL_TESSELLATOR_DOMAIN ] = "dcl_tessellator_domain",
- [VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = "dcl_tessellator_output_primitive",
- [VKD3DSIH_DCL_TESSELLATOR_PARTITIONING ] = "dcl_tessellator_partitioning",
- [VKD3DSIH_DCL_TGSM_RAW ] = "dcl_tgsm_raw",
- [VKD3DSIH_DCL_TGSM_STRUCTURED ] = "dcl_tgsm_structured",
- [VKD3DSIH_DCL_THREAD_GROUP ] = "dcl_thread_group",
- [VKD3DSIH_DCL_UAV_RAW ] = "dcl_uav_raw",
- [VKD3DSIH_DCL_UAV_STRUCTURED ] = "dcl_uav_structured",
- [VKD3DSIH_DCL_UAV_TYPED ] = "dcl_uav_typed",
- [VKD3DSIH_DCL_VERTICES_OUT ] = "dcl_maxout",
- [VKD3DSIH_DDIV ] = "ddiv",
- [VKD3DSIH_DEF ] = "def",
- [VKD3DSIH_DEFAULT ] = "default",
- [VKD3DSIH_DEFB ] = "defb",
- [VKD3DSIH_DEFI ] = "defi",
- [VKD3DSIH_DEQO ] = "deq",
- [VKD3DSIH_DFMA ] = "dfma",
- [VKD3DSIH_DGEO ] = "dge",
- [VKD3DSIH_DISCARD ] = "discard",
- [VKD3DSIH_DIV ] = "div",
- [VKD3DSIH_DLT ] = "dlt",
- [VKD3DSIH_DMAX ] = "dmax",
- [VKD3DSIH_DMIN ] = "dmin",
- [VKD3DSIH_DMOV ] = "dmov",
- [VKD3DSIH_DMOVC ] = "dmovc",
- [VKD3DSIH_DMUL ] = "dmul",
- [VKD3DSIH_DNE ] = "dne",
- [VKD3DSIH_DP2 ] = "dp2",
- [VKD3DSIH_DP2ADD ] = "dp2add",
- [VKD3DSIH_DP3 ] = "dp3",
- [VKD3DSIH_DP4 ] = "dp4",
- [VKD3DSIH_DRCP ] = "drcp",
- [VKD3DSIH_DST ] = "dst",
- [VKD3DSIH_DSX ] = "dsx",
- [VKD3DSIH_DSX_COARSE ] = "deriv_rtx_coarse",
- [VKD3DSIH_DSX_FINE ] = "deriv_rtx_fine",
- [VKD3DSIH_DSY ] = "dsy",
- [VKD3DSIH_DSY_COARSE ] = "deriv_rty_coarse",
- [VKD3DSIH_DSY_FINE ] = "deriv_rty_fine",
- [VKD3DSIH_DTOF ] = "dtof",
- [VKD3DSIH_DTOI ] = "dtoi",
- [VKD3DSIH_DTOU ] = "dtou",
- [VKD3DSIH_ELSE ] = "else",
- [VKD3DSIH_EMIT ] = "emit",
- [VKD3DSIH_EMIT_STREAM ] = "emit_stream",
- [VKD3DSIH_ENDIF ] = "endif",
- [VKD3DSIH_ENDLOOP ] = "endloop",
- [VKD3DSIH_ENDREP ] = "endrep",
- [VKD3DSIH_ENDSWITCH ] = "endswitch",
- [VKD3DSIH_EQO ] = "eq",
- [VKD3DSIH_EQU ] = "eq_unord",
- [VKD3DSIH_EVAL_CENTROID ] = "eval_centroid",
- [VKD3DSIH_EVAL_SAMPLE_INDEX ] = "eval_sample_index",
- [VKD3DSIH_EXP ] = "exp",
- [VKD3DSIH_EXPP ] = "expp",
- [VKD3DSIH_F16TOF32 ] = "f16tof32",
- [VKD3DSIH_F32TOF16 ] = "f32tof16",
- [VKD3DSIH_FCALL ] = "fcall",
- [VKD3DSIH_FIRSTBIT_HI ] = "firstbit_hi",
- [VKD3DSIH_FIRSTBIT_LO ] = "firstbit_lo",
- [VKD3DSIH_FIRSTBIT_SHI ] = "firstbit_shi",
- [VKD3DSIH_FRC ] = "frc",
- [VKD3DSIH_FREM ] = "frem",
- [VKD3DSIH_FTOD ] = "ftod",
- [VKD3DSIH_FTOI ] = "ftoi",
- [VKD3DSIH_FTOU ] = "ftou",
- [VKD3DSIH_GATHER4 ] = "gather4",
- [VKD3DSIH_GATHER4_C ] = "gather4_c",
- [VKD3DSIH_GATHER4_C_S ] = "gather4_c_s",
- [VKD3DSIH_GATHER4_PO ] = "gather4_po",
- [VKD3DSIH_GATHER4_PO_C ] = "gather4_po_c",
- [VKD3DSIH_GATHER4_PO_C_S ] = "gather4_po_c_s",
- [VKD3DSIH_GATHER4_PO_S ] = "gather4_po_s",
- [VKD3DSIH_GATHER4_S ] = "gather4_s",
- [VKD3DSIH_GEO ] = "ge",
- [VKD3DSIH_GEU ] = "ge_unord",
- [VKD3DSIH_HCOS ] = "hcos",
- [VKD3DSIH_HS_CONTROL_POINT_PHASE ] = "hs_control_point_phase",
- [VKD3DSIH_HS_DECLS ] = "hs_decls",
- [VKD3DSIH_HS_FORK_PHASE ] = "hs_fork_phase",
- [VKD3DSIH_HS_JOIN_PHASE ] = "hs_join_phase",
- [VKD3DSIH_HSIN ] = "hsin",
- [VKD3DSIH_HTAN ] = "htan",
- [VKD3DSIH_IADD ] = "iadd",
- [VKD3DSIH_IBFE ] = "ibfe",
- [VKD3DSIH_IDIV ] = "idiv",
- [VKD3DSIH_IEQ ] = "ieq",
- [VKD3DSIH_IF ] = "if",
- [VKD3DSIH_IFC ] = "if",
- [VKD3DSIH_IGE ] = "ige",
- [VKD3DSIH_ILT ] = "ilt",
- [VKD3DSIH_IMAD ] = "imad",
- [VKD3DSIH_IMAX ] = "imax",
- [VKD3DSIH_IMIN ] = "imin",
- [VKD3DSIH_IMM_ATOMIC_ALLOC ] = "imm_atomic_alloc",
- [VKD3DSIH_IMM_ATOMIC_AND ] = "imm_atomic_and",
- [VKD3DSIH_IMM_ATOMIC_CMP_EXCH ] = "imm_atomic_cmp_exch",
- [VKD3DSIH_IMM_ATOMIC_CONSUME ] = "imm_atomic_consume",
- [VKD3DSIH_IMM_ATOMIC_EXCH ] = "imm_atomic_exch",
- [VKD3DSIH_IMM_ATOMIC_IADD ] = "imm_atomic_iadd",
- [VKD3DSIH_IMM_ATOMIC_IMAX ] = "imm_atomic_imax",
- [VKD3DSIH_IMM_ATOMIC_IMIN ] = "imm_atomic_imin",
- [VKD3DSIH_IMM_ATOMIC_OR ] = "imm_atomic_or",
- [VKD3DSIH_IMM_ATOMIC_UMAX ] = "imm_atomic_umax",
- [VKD3DSIH_IMM_ATOMIC_UMIN ] = "imm_atomic_umin",
- [VKD3DSIH_IMM_ATOMIC_XOR ] = "imm_atomic_xor",
- [VKD3DSIH_IMUL ] = "imul",
- [VKD3DSIH_INE ] = "ine",
- [VKD3DSIH_INEG ] = "ineg",
- [VKD3DSIH_ISFINITE ] = "isfinite",
- [VKD3DSIH_ISHL ] = "ishl",
- [VKD3DSIH_ISHR ] = "ishr",
- [VKD3DSIH_ISINF ] = "isinf",
- [VKD3DSIH_ISNAN ] = "isnan",
- [VKD3DSIH_ITOD ] = "itod",
- [VKD3DSIH_ITOF ] = "itof",
- [VKD3DSIH_ITOI ] = "itoi",
- [VKD3DSIH_LABEL ] = "label",
- [VKD3DSIH_LD ] = "ld",
- [VKD3DSIH_LD2DMS ] = "ld2dms",
- [VKD3DSIH_LD2DMS_S ] = "ld2dms_s",
- [VKD3DSIH_LD_RAW ] = "ld_raw",
- [VKD3DSIH_LD_RAW_S ] = "ld_raw_s",
- [VKD3DSIH_LD_S ] = "ld_s",
- [VKD3DSIH_LD_STRUCTURED ] = "ld_structured",
- [VKD3DSIH_LD_STRUCTURED_S ] = "ld_structured_s",
- [VKD3DSIH_LD_UAV_TYPED ] = "ld_uav_typed",
- [VKD3DSIH_LD_UAV_TYPED_S ] = "ld_uav_typed_s",
- [VKD3DSIH_LIT ] = "lit",
- [VKD3DSIH_LOD ] = "lod",
- [VKD3DSIH_LOG ] = "log",
- [VKD3DSIH_LOGP ] = "logp",
- [VKD3DSIH_LOOP ] = "loop",
- [VKD3DSIH_LRP ] = "lrp",
- [VKD3DSIH_LTO ] = "lt",
- [VKD3DSIH_LTU ] = "lt_unord",
- [VKD3DSIH_M3x2 ] = "m3x2",
- [VKD3DSIH_M3x3 ] = "m3x3",
- [VKD3DSIH_M3x4 ] = "m3x4",
- [VKD3DSIH_M4x3 ] = "m4x3",
- [VKD3DSIH_M4x4 ] = "m4x4",
- [VKD3DSIH_MAD ] = "mad",
- [VKD3DSIH_MAX ] = "max",
- [VKD3DSIH_MIN ] = "min",
- [VKD3DSIH_MOV ] = "mov",
- [VKD3DSIH_MOVA ] = "mova",
- [VKD3DSIH_MOVC ] = "movc",
- [VKD3DSIH_MSAD ] = "msad",
- [VKD3DSIH_MUL ] = "mul",
- [VKD3DSIH_NEO ] = "ne_ord",
- [VKD3DSIH_NEU ] = "ne",
- [VKD3DSIH_NOP ] = "nop",
- [VKD3DSIH_NOT ] = "not",
- [VKD3DSIH_NRM ] = "nrm",
- [VKD3DSIH_OR ] = "or",
- [VKD3DSIH_ORD ] = "ord",
- [VKD3DSIH_PHASE ] = "phase",
- [VKD3DSIH_PHI ] = "phi",
- [VKD3DSIH_POW ] = "pow",
- [VKD3DSIH_QUAD_READ_ACROSS_D ] = "quad_read_across_d",
- [VKD3DSIH_QUAD_READ_ACROSS_X ] = "quad_read_across_x",
- [VKD3DSIH_QUAD_READ_ACROSS_Y ] = "quad_read_across_y",
- [VKD3DSIH_QUAD_READ_LANE_AT ] = "quad_read_lane_at",
- [VKD3DSIH_RCP ] = "rcp",
- [VKD3DSIH_REP ] = "rep",
- [VKD3DSIH_RESINFO ] = "resinfo",
- [VKD3DSIH_RET ] = "ret",
- [VKD3DSIH_RETP ] = "retp",
- [VKD3DSIH_ROUND_NE ] = "round_ne",
- [VKD3DSIH_ROUND_NI ] = "round_ni",
- [VKD3DSIH_ROUND_PI ] = "round_pi",
- [VKD3DSIH_ROUND_Z ] = "round_z",
- [VKD3DSIH_RSQ ] = "rsq",
- [VKD3DSIH_SAMPLE ] = "sample",
- [VKD3DSIH_SAMPLE_B ] = "sample_b",
- [VKD3DSIH_SAMPLE_B_CL_S ] = "sample_b_cl_s",
- [VKD3DSIH_SAMPLE_C ] = "sample_c",
- [VKD3DSIH_SAMPLE_C_CL_S ] = "sample_c_cl_s",
- [VKD3DSIH_SAMPLE_C_LZ ] = "sample_c_lz",
- [VKD3DSIH_SAMPLE_C_LZ_S ] = "sample_c_lz_s",
- [VKD3DSIH_SAMPLE_CL_S ] = "sample_cl_s",
- [VKD3DSIH_SAMPLE_GRAD ] = "sample_d",
- [VKD3DSIH_SAMPLE_GRAD_CL_S ] = "sample_d_cl_s",
- [VKD3DSIH_SAMPLE_INFO ] = "sample_info",
- [VKD3DSIH_SAMPLE_LOD ] = "sample_l",
- [VKD3DSIH_SAMPLE_LOD_S ] = "sample_l_s",
- [VKD3DSIH_SAMPLE_POS ] = "sample_pos",
- [VKD3DSIH_SETP ] = "setp",
- [VKD3DSIH_SGE ] = "sge",
- [VKD3DSIH_SGN ] = "sgn",
- [VKD3DSIH_SINCOS ] = "sincos",
- [VKD3DSIH_SLT ] = "slt",
- [VKD3DSIH_SQRT ] = "sqrt",
- [VKD3DSIH_STORE_RAW ] = "store_raw",
- [VKD3DSIH_STORE_STRUCTURED ] = "store_structured",
- [VKD3DSIH_STORE_UAV_TYPED ] = "store_uav_typed",
- [VKD3DSIH_SUB ] = "sub",
- [VKD3DSIH_SWAPC ] = "swapc",
- [VKD3DSIH_SWITCH ] = "switch",
- [VKD3DSIH_SWITCH_MONOLITHIC ] = "switch",
- [VKD3DSIH_SYNC ] = "sync",
- [VKD3DSIH_TAN ] = "tan",
- [VKD3DSIH_TEX ] = "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_UNO ] = "uno",
- [VKD3DSIH_USHR ] = "ushr",
- [VKD3DSIH_UTOD ] = "utod",
- [VKD3DSIH_UTOF ] = "utof",
- [VKD3DSIH_UTOU ] = "utou",
- [VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL ] = "wave_active_all_equal",
- [VKD3DSIH_WAVE_ACTIVE_BALLOT ] = "wave_active_ballot",
- [VKD3DSIH_WAVE_ACTIVE_BIT_AND ] = "wave_active_bit_and",
- [VKD3DSIH_WAVE_ACTIVE_BIT_OR ] = "wave_active_bit_or",
- [VKD3DSIH_WAVE_ACTIVE_BIT_XOR ] = "wave_active_bit_xor",
- [VKD3DSIH_WAVE_ALL_BIT_COUNT ] = "wave_all_bit_count",
- [VKD3DSIH_WAVE_ALL_TRUE ] = "wave_all_true",
- [VKD3DSIH_WAVE_ANY_TRUE ] = "wave_any_true",
- [VKD3DSIH_WAVE_IS_FIRST_LANE ] = "wave_is_first_lane",
- [VKD3DSIH_WAVE_OP_ADD ] = "wave_op_add",
- [VKD3DSIH_WAVE_OP_IMAX ] = "wave_op_imax",
- [VKD3DSIH_WAVE_OP_IMIN ] = "wave_op_imin",
- [VKD3DSIH_WAVE_OP_MAX ] = "wave_op_max",
- [VKD3DSIH_WAVE_OP_MIN ] = "wave_op_min",
- [VKD3DSIH_WAVE_OP_MUL ] = "wave_op_mul",
- [VKD3DSIH_WAVE_OP_UMAX ] = "wave_op_umax",
- [VKD3DSIH_WAVE_OP_UMIN ] = "wave_op_umin",
- [VKD3DSIH_WAVE_PREFIX_BIT_COUNT ] = "wave_prefix_bit_count",
- [VKD3DSIH_WAVE_READ_LANE_AT ] = "wave_read_lane_at",
- [VKD3DSIH_WAVE_READ_LANE_FIRST ] = "wave_read_lane_first",
- [VKD3DSIH_XOR ] = "xor",
-};
-
static const char * const shader_register_names[] =
{
[VKD3DSPR_ADDR ] = "a",
@@ -483,6 +156,8 @@ static void shader_dump_atomic_op_flags(struct vkd3d_d3d_asm_compiler *compiler,
atomic_flags &= ~VKD3DARF_VOLATILE;
}
+ atomic_flags &= ~VKD3DSI_PRECISE_XYZW;
+
if (atomic_flags)
vkd3d_string_buffer_printf(&compiler->buffer, "_unknown_flags(%#x)", atomic_flags);
}
@@ -510,6 +185,8 @@ static void shader_dump_sync_flags(struct vkd3d_d3d_asm_compiler *compiler, uint
sync_flags &= ~VKD3DSSF_THREAD_GROUP;
}
+ sync_flags &= ~VKD3DSI_PRECISE_XYZW;
+
if (sync_flags)
vkd3d_string_buffer_printf(&compiler->buffer, "_unknown_flags(%#x)", sync_flags);
}
@@ -711,25 +388,25 @@ static void shader_print_resource_type(struct vkd3d_d3d_asm_compiler *compiler,
compiler->colours.error, type, compiler->colours.reset);
}
-static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_data_type type)
+static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vsir_data_type type)
{
static const char *const data_type_names[] =
{
- [VKD3D_DATA_FLOAT ] = "float",
- [VKD3D_DATA_INT ] = "int",
- [VKD3D_DATA_UINT ] = "uint",
- [VKD3D_DATA_UNORM ] = "unorm",
- [VKD3D_DATA_SNORM ] = "snorm",
- [VKD3D_DATA_OPAQUE ] = "opaque",
- [VKD3D_DATA_MIXED ] = "mixed",
- [VKD3D_DATA_DOUBLE ] = "double",
- [VKD3D_DATA_CONTINUED] = "<continued>",
- [VKD3D_DATA_UNUSED ] = "<unused>",
- [VKD3D_DATA_UINT8 ] = "uint8",
- [VKD3D_DATA_UINT64 ] = "uint64",
- [VKD3D_DATA_BOOL ] = "bool",
- [VKD3D_DATA_UINT16 ] = "uint16",
- [VKD3D_DATA_HALF ] = "half",
+ [VSIR_DATA_BOOL ] = "bool",
+ [VSIR_DATA_F16 ] = "half",
+ [VSIR_DATA_F32 ] = "float",
+ [VSIR_DATA_F64 ] = "double",
+ [VSIR_DATA_I32 ] = "int",
+ [VSIR_DATA_U8 ] = "uint8",
+ [VSIR_DATA_U16 ] = "uint16",
+ [VSIR_DATA_U32 ] = "uint",
+ [VSIR_DATA_U64 ] = "uint64",
+ [VSIR_DATA_SNORM ] = "snorm",
+ [VSIR_DATA_UNORM ] = "unorm",
+ [VSIR_DATA_OPAQUE ] = "opaque",
+ [VSIR_DATA_MIXED ] = "mixed",
+ [VSIR_DATA_CONTINUED] = "<continued>",
+ [VSIR_DATA_UNUSED ] = "<unused>",
};
if (type < ARRAY_SIZE(data_type_names))
@@ -739,7 +416,7 @@ static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum
compiler->colours.error, type, compiler->colours.reset);
}
-static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vkd3d_data_type *type)
+static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vsir_data_type *type)
{
int i;
@@ -917,9 +594,10 @@ static void shader_print_double_literal(struct vkd3d_d3d_asm_compiler *compiler,
static void shader_print_int_literal(struct vkd3d_d3d_asm_compiler *compiler,
const char *prefix, int i, const char *suffix)
{
+ /* Note that we need to handle INT_MIN here as well. */
if (i < 0)
- vkd3d_string_buffer_printf(&compiler->buffer, "%s-%s%d%s%s",
- prefix, compiler->colours.literal, -i, compiler->colours.reset, suffix);
+ vkd3d_string_buffer_printf(&compiler->buffer, "%s-%s%u%s%s",
+ prefix, compiler->colours.literal, -(unsigned int)i, compiler->colours.reset, suffix);
else
vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%d%s%s",
prefix, compiler->colours.literal, i, compiler->colours.reset, suffix);
@@ -1041,8 +719,8 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const
switch (compiler->current->opcode)
{
- case VKD3DSIH_MOV:
- case VKD3DSIH_MOVC:
+ case VSIR_OP_MOV:
+ case VSIR_OP_MOVC:
untyped = true;
break;
@@ -1056,16 +734,16 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const
case VSIR_DIMENSION_SCALAR:
switch (reg->data_type)
{
- case VKD3D_DATA_FLOAT:
+ case VSIR_DATA_F32:
if (untyped)
shader_print_untyped_literal(compiler, "", reg->u.immconst_u32[0], "");
else
shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], "");
break;
- case VKD3D_DATA_INT:
+ case VSIR_DATA_I32:
shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], "");
break;
- case VKD3D_DATA_UINT:
+ case VSIR_DATA_U32:
shader_print_uint_literal(compiler, "", reg->u.immconst_u32[0], "");
break;
default:
@@ -1078,7 +756,7 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const
case VSIR_DIMENSION_VEC4:
switch (reg->data_type)
{
- case VKD3D_DATA_FLOAT:
+ case VSIR_DATA_F32:
if (untyped)
{
shader_print_untyped_literal(compiler, "", reg->u.immconst_u32[0], "");
@@ -1094,13 +772,13 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const
shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[3], "");
}
break;
- case VKD3D_DATA_INT:
+ case VSIR_DATA_I32:
shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], "");
shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[1], "");
shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[2], "");
shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[3], "");
break;
- case VKD3D_DATA_UINT:
+ case VSIR_DATA_U32:
shader_print_uint_literal(compiler, "", reg->u.immconst_u32[0], "");
shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[1], "");
shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[2], "");
@@ -1126,13 +804,13 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const
/* A double2 vector is treated as a float4 vector in enum vsir_dimension. */
if (reg->dimension == VSIR_DIMENSION_SCALAR || reg->dimension == VSIR_DIMENSION_VEC4)
{
- if (reg->data_type == VKD3D_DATA_DOUBLE)
+ if (reg->data_type == VSIR_DATA_F64)
{
shader_print_double_literal(compiler, "", reg->u.immconst_f64[0], "");
if (reg->dimension == VSIR_DIMENSION_VEC4)
shader_print_double_literal(compiler, ", ", reg->u.immconst_f64[1], "");
}
- else if (reg->data_type == VKD3D_DATA_UINT64)
+ else if (reg->data_type == VSIR_DATA_U64)
{
shader_print_uint64_literal(compiler, "", reg->u.immconst_u64[0], "");
if (reg->dimension == VSIR_DIMENSION_VEC4)
@@ -1283,7 +961,7 @@ static void shader_print_reg_type(struct vkd3d_d3d_asm_compiler *compiler,
return;
}
- if (reg->data_type == VKD3D_DATA_UNUSED)
+ if (reg->data_type == VSIR_DATA_UNUSED)
return;
if (reg->dimension < ARRAY_SIZE(dimensions))
@@ -1610,11 +1288,11 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile
switch (ins->opcode)
{
- case VKD3DSIH_BREAKP:
- case VKD3DSIH_CONTINUEP:
- case VKD3DSIH_DISCARD:
- case VKD3DSIH_IF:
- case VKD3DSIH_RETP:
+ case VSIR_OP_BREAKP:
+ case VSIR_OP_CONTINUEP:
+ case VSIR_OP_DISCARD:
+ case VSIR_OP_IF:
+ case VSIR_OP_RETP:
switch (ins->flags)
{
case VKD3D_SHADER_CONDITIONAL_OP_NZ:
@@ -1629,8 +1307,8 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile
}
break;
- case VKD3DSIH_IFC:
- case VKD3DSIH_BREAKC:
+ case VSIR_OP_IFC:
+ case VSIR_OP_BREAKC:
switch (ins->flags)
{
case VKD3D_SHADER_REL_OP_GT:
@@ -1657,8 +1335,8 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile
}
break;
- case VKD3DSIH_RESINFO:
- switch (ins->flags)
+ case VSIR_OP_RESINFO:
+ switch (ins->flags & ~VKD3DSI_PRECISE_XYZW)
{
case VKD3DSI_NONE:
break;
@@ -1674,8 +1352,8 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile
}
break;
- case VKD3DSIH_SAMPLE_INFO:
- switch (ins->flags)
+ case VSIR_OP_SAMPLE_INFO:
+ switch (ins->flags & ~VKD3DSI_PRECISE_XYZW)
{
case VKD3DSI_NONE:
break;
@@ -1688,24 +1366,24 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile
}
break;
- case VKD3DSIH_IMM_ATOMIC_CMP_EXCH:
- case VKD3DSIH_IMM_ATOMIC_IADD:
- case VKD3DSIH_IMM_ATOMIC_AND:
- case VKD3DSIH_IMM_ATOMIC_IMAX:
- case VKD3DSIH_IMM_ATOMIC_IMIN:
- case VKD3DSIH_IMM_ATOMIC_OR:
- case VKD3DSIH_IMM_ATOMIC_UMAX:
- case VKD3DSIH_IMM_ATOMIC_UMIN:
- case VKD3DSIH_IMM_ATOMIC_EXCH:
- case VKD3DSIH_IMM_ATOMIC_XOR:
+ case VSIR_OP_IMM_ATOMIC_CMP_EXCH:
+ case VSIR_OP_IMM_ATOMIC_IADD:
+ case VSIR_OP_IMM_ATOMIC_AND:
+ case VSIR_OP_IMM_ATOMIC_IMAX:
+ case VSIR_OP_IMM_ATOMIC_IMIN:
+ case VSIR_OP_IMM_ATOMIC_OR:
+ case VSIR_OP_IMM_ATOMIC_UMAX:
+ case VSIR_OP_IMM_ATOMIC_UMIN:
+ case VSIR_OP_IMM_ATOMIC_EXCH:
+ case VSIR_OP_IMM_ATOMIC_XOR:
shader_dump_atomic_op_flags(compiler, ins->flags);
break;
- case VKD3DSIH_SYNC:
+ case VSIR_OP_SYNC:
shader_dump_sync_flags(compiler, ins->flags);
break;
- case VKD3DSIH_TEX:
+ case VSIR_OP_TEXLD:
if (vkd3d_shader_ver_ge(&compiler->shader_version, 2, 0))
{
if (ins->flags & VKD3DSI_TEXLD_PROJECT)
@@ -1715,25 +1393,25 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile
}
break;
- case VKD3DSIH_WAVE_OP_ADD:
- case VKD3DSIH_WAVE_OP_IMAX:
- case VKD3DSIH_WAVE_OP_IMIN:
- case VKD3DSIH_WAVE_OP_MAX:
- case VKD3DSIH_WAVE_OP_MIN:
- case VKD3DSIH_WAVE_OP_MUL:
- case VKD3DSIH_WAVE_OP_UMAX:
- case VKD3DSIH_WAVE_OP_UMIN:
+ case VSIR_OP_WAVE_OP_ADD:
+ case VSIR_OP_WAVE_OP_IMAX:
+ case VSIR_OP_WAVE_OP_IMIN:
+ case VSIR_OP_WAVE_OP_MAX:
+ case VSIR_OP_WAVE_OP_MIN:
+ case VSIR_OP_WAVE_OP_MUL:
+ case VSIR_OP_WAVE_OP_UMAX:
+ case VSIR_OP_WAVE_OP_UMIN:
vkd3d_string_buffer_printf(&compiler->buffer, (ins->flags & VKD3DSI_WAVE_PREFIX) ? "_prefix" : "_active");
break;
- case VKD3DSIH_ISHL:
- case VKD3DSIH_ISHR:
- case VKD3DSIH_USHR:
+ case VSIR_OP_ISHL:
+ case VSIR_OP_ISHR:
+ case VSIR_OP_USHR:
if (ins->flags & VKD3DSI_SHIFT_UNMASKED)
vkd3d_string_buffer_printf(buffer, "_unmasked");
- /* fall through */
+ break;
+
default:
- shader_dump_precise_flags(compiler, ins->flags);
break;
}
}
@@ -1747,7 +1425,7 @@ static void shader_dump_register_space(struct vkd3d_d3d_asm_compiler *compiler,
static void shader_print_opcode(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_shader_opcode opcode)
{
vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%s", compiler->colours.opcode,
- shader_opcode_names[opcode], compiler->colours.reset);
+ vsir_opcode_get_name(opcode, "<unknown>"), compiler->colours.reset);
}
static void shader_dump_icb(struct vkd3d_d3d_asm_compiler *compiler,
@@ -1799,8 +1477,8 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
switch (ins->opcode)
{
- case VKD3DSIH_DCL:
- case VKD3DSIH_DCL_UAV_TYPED:
+ case VSIR_OP_DCL:
+ case VSIR_OP_DCL_UAV_TYPED:
vkd3d_string_buffer_printf(buffer, "%s", compiler->colours.opcode);
shader_print_dcl_usage(compiler, "_", &ins->declaration.semantic, ins->flags, "");
shader_dump_ins_modifiers(compiler, &ins->declaration.semantic.resource.reg);
@@ -1809,7 +1487,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
shader_dump_register_space(compiler, ins->declaration.semantic.resource.range.space);
break;
- case VKD3DSIH_DCL_CONSTANT_BUFFER:
+ case VSIR_OP_DCL_CONSTANT_BUFFER:
shader_print_register(compiler, " ", &ins->declaration.cb.src.reg, true, "");
if (vkd3d_shader_ver_ge(&compiler->shader_version, 6, 0))
shader_print_subscript(compiler, ins->declaration.cb.size, NULL);
@@ -1820,33 +1498,33 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
shader_dump_register_space(compiler, ins->declaration.cb.range.space);
break;
- case VKD3DSIH_DCL_FUNCTION_BODY:
+ case VSIR_OP_DCL_FUNCTION_BODY:
vkd3d_string_buffer_printf(buffer, " fb%u", ins->declaration.index);
break;
- case VKD3DSIH_DCL_FUNCTION_TABLE:
+ case VSIR_OP_DCL_FUNCTION_TABLE:
vkd3d_string_buffer_printf(buffer, " ft%u = {...}", ins->declaration.index);
break;
- case VKD3DSIH_DCL_GLOBAL_FLAGS:
+ case VSIR_OP_DCL_GLOBAL_FLAGS:
vkd3d_string_buffer_printf(buffer, " ");
shader_dump_global_flags(compiler, ins->declaration.global_flags);
break;
- case VKD3DSIH_DCL_HS_MAX_TESSFACTOR:
+ case VSIR_OP_DCL_HS_MAX_TESSFACTOR:
shader_print_float_literal(compiler, " ", ins->declaration.max_tessellation_factor, "");
break;
- case VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER:
+ case VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER:
shader_dump_icb(compiler, ins->declaration.icb);
break;
- case VKD3DSIH_DCL_INDEX_RANGE:
+ case VSIR_OP_DCL_INDEX_RANGE:
shader_print_dst_param(compiler, " ", &ins->declaration.index_range.dst, true, "");
shader_print_uint_literal(compiler, " ", ins->declaration.index_range.register_count, "");
break;
- case VKD3DSIH_DCL_INDEXABLE_TEMP:
+ case VSIR_OP_DCL_INDEXABLE_TEMP:
vkd3d_string_buffer_printf(buffer, " %sx%u%s", compiler->colours.reg,
ins->declaration.indexable_temp.register_idx, compiler->colours.reset);
shader_print_subscript(compiler, ins->declaration.indexable_temp.register_size, NULL);
@@ -1857,112 +1535,113 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
shader_dump_icb(compiler, ins->declaration.indexable_temp.initialiser);
break;
- case VKD3DSIH_DCL_INPUT_PS:
+ case VSIR_OP_DCL_INPUT_PS:
shader_print_interpolation_mode(compiler, " ", ins->flags, "");
shader_print_dst_param(compiler, " ", &ins->declaration.dst, true, "");
break;
- case VKD3DSIH_DCL_INPUT_PS_SGV:
- case VKD3DSIH_DCL_INPUT_SGV:
- case VKD3DSIH_DCL_INPUT_SIV:
- case VKD3DSIH_DCL_OUTPUT_SIV:
+ case VSIR_OP_DCL_INPUT_PS_SGV:
+ case VSIR_OP_DCL_INPUT_SGV:
+ case VSIR_OP_DCL_INPUT_SIV:
+ case VSIR_OP_DCL_OUTPUT_SGV:
+ case VSIR_OP_DCL_OUTPUT_SIV:
shader_print_dst_param(compiler, " ", &ins->declaration.register_semantic.reg, true, "");
shader_print_input_sysval_semantic(compiler, ", ", ins->declaration.register_semantic.sysval_semantic, "");
break;
- case VKD3DSIH_DCL_INPUT_PS_SIV:
+ case VSIR_OP_DCL_INPUT_PS_SIV:
shader_print_interpolation_mode(compiler, " ", ins->flags, "");
shader_print_dst_param(compiler, " ", &ins->declaration.register_semantic.reg, true, "");
shader_print_input_sysval_semantic(compiler, ", ", ins->declaration.register_semantic.sysval_semantic, "");
break;
- case VKD3DSIH_DCL_INPUT:
- case VKD3DSIH_DCL_OUTPUT:
+ case VSIR_OP_DCL_INPUT:
+ case VSIR_OP_DCL_OUTPUT:
shader_print_dst_param(compiler, " ", &ins->declaration.dst, true, "");
break;
- case VKD3DSIH_DCL_INPUT_PRIMITIVE:
- case VKD3DSIH_DCL_OUTPUT_TOPOLOGY:
+ case VSIR_OP_DCL_INPUT_PRIMITIVE:
+ case VSIR_OP_DCL_OUTPUT_TOPOLOGY:
shader_print_primitive_type(compiler, " ", &ins->declaration.primitive_type, "");
break;
- case VKD3DSIH_DCL_INTERFACE:
+ case VSIR_OP_DCL_INTERFACE:
vkd3d_string_buffer_printf(buffer, " fp%u", ins->declaration.fp.index);
shader_print_subscript(compiler, ins->declaration.fp.array_size, NULL);
shader_print_subscript(compiler, ins->declaration.fp.body_count, NULL);
vkd3d_string_buffer_printf(buffer, " = {...}");
break;
- case VKD3DSIH_DCL_RESOURCE_RAW:
+ case VSIR_OP_DCL_RESOURCE_RAW:
shader_print_dst_param(compiler, " ", &ins->declaration.raw_resource.resource.reg, true, "");
shader_dump_register_space(compiler, ins->declaration.raw_resource.resource.range.space);
break;
- case VKD3DSIH_DCL_RESOURCE_STRUCTURED:
+ case VSIR_OP_DCL_RESOURCE_STRUCTURED:
shader_print_dst_param(compiler, " ", &ins->declaration.structured_resource.resource.reg, true, "");
shader_print_uint_literal(compiler, ", ", ins->declaration.structured_resource.byte_stride, "");
shader_dump_register_space(compiler, ins->declaration.structured_resource.resource.range.space);
break;
- case VKD3DSIH_DCL_SAMPLER:
+ case VSIR_OP_DCL_SAMPLER:
shader_print_register(compiler, " ", &ins->declaration.sampler.src.reg, true,
ins->flags == VKD3DSI_SAMPLER_COMPARISON_MODE ? ", comparisonMode" : "");
shader_dump_register_space(compiler, ins->declaration.sampler.range.space);
break;
- case VKD3DSIH_DCL_TEMPS:
- case VKD3DSIH_DCL_GS_INSTANCES:
- case VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT:
- case VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT:
- case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT:
- case VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT:
- case VKD3DSIH_DCL_VERTICES_OUT:
+ case VSIR_OP_DCL_TEMPS:
+ case VSIR_OP_DCL_GS_INSTANCES:
+ case VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT:
+ case VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT:
+ case VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT:
+ case VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT:
+ case VSIR_OP_DCL_VERTICES_OUT:
shader_print_uint_literal(compiler, " ", ins->declaration.count, "");
break;
- case VKD3DSIH_DCL_TESSELLATOR_DOMAIN:
+ case VSIR_OP_DCL_TESSELLATOR_DOMAIN:
shader_print_tessellator_domain(compiler, " ", ins->declaration.tessellator_domain, "");
break;
- case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE:
+ case VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE:
shader_print_tessellator_output_primitive(compiler, " ", ins->declaration.tessellator_output_primitive, "");
break;
- case VKD3DSIH_DCL_TESSELLATOR_PARTITIONING:
+ case VSIR_OP_DCL_TESSELLATOR_PARTITIONING:
shader_print_tessellator_partitioning(compiler, " ", ins->declaration.tessellator_partitioning, "");
break;
- case VKD3DSIH_DCL_TGSM_RAW:
+ case VSIR_OP_DCL_TGSM_RAW:
shader_print_dst_param(compiler, " ", &ins->declaration.tgsm_raw.reg, true, "");
shader_print_uint_literal(compiler, ", ", ins->declaration.tgsm_raw.byte_count, "");
break;
- case VKD3DSIH_DCL_TGSM_STRUCTURED:
+ case VSIR_OP_DCL_TGSM_STRUCTURED:
shader_print_dst_param(compiler, " ", &ins->declaration.tgsm_structured.reg, true, "");
shader_print_uint_literal(compiler, ", ", ins->declaration.tgsm_structured.byte_stride, "");
shader_print_uint_literal(compiler, ", ", ins->declaration.tgsm_structured.structure_count, "");
break;
- case VKD3DSIH_DCL_THREAD_GROUP:
+ case VSIR_OP_DCL_THREAD_GROUP:
shader_print_uint_literal(compiler, " ", ins->declaration.thread_group_size.x, "");
shader_print_uint_literal(compiler, ", ", ins->declaration.thread_group_size.y, "");
shader_print_uint_literal(compiler, ", ", ins->declaration.thread_group_size.z, "");
break;
- case VKD3DSIH_DCL_UAV_RAW:
+ case VSIR_OP_DCL_UAV_RAW:
shader_dump_uav_flags(compiler, ins->flags);
shader_print_dst_param(compiler, " ", &ins->declaration.raw_resource.resource.reg, true, "");
shader_dump_register_space(compiler, ins->declaration.raw_resource.resource.range.space);
break;
- case VKD3DSIH_DCL_UAV_STRUCTURED:
+ case VSIR_OP_DCL_UAV_STRUCTURED:
shader_dump_uav_flags(compiler, ins->flags);
shader_print_dst_param(compiler, " ", &ins->declaration.structured_resource.resource.reg, true, "");
shader_print_uint_literal(compiler, ", ", ins->declaration.structured_resource.byte_stride, "");
shader_dump_register_space(compiler, ins->declaration.structured_resource.resource.range.space);
break;
- case VKD3DSIH_DEF:
+ case VSIR_OP_DEF:
vkd3d_string_buffer_printf(buffer, " %sc%u%s", compiler->colours.reg,
ins->dst[0].reg.idx[0].offset, compiler->colours.reset);
shader_print_float_literal(compiler, " = ", ins->src[0].reg.u.immconst_f32[0], "");
@@ -1971,7 +1650,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_f32[3], "");
break;
- case VKD3DSIH_DEFI:
+ case VSIR_OP_DEFI:
vkd3d_string_buffer_printf(buffer, " %si%u%s", compiler->colours.reg,
ins->dst[0].reg.idx[0].offset, compiler->colours.reset);
shader_print_int_literal(compiler, " = ", ins->src[0].reg.u.immconst_u32[0], "");
@@ -1980,7 +1659,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_u32[3], "");
break;
- case VKD3DSIH_DEFB:
+ case VSIR_OP_DEFB:
vkd3d_string_buffer_printf(buffer, " %sb%u%s", compiler->colours.reg,
ins->dst[0].reg.idx[0].offset, compiler->colours.reset);
shader_print_bool_literal(compiler, " = ", ins->src[0].reg.u.immconst_u32[0], "");
@@ -1989,9 +1668,14 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
default:
shader_dump_instruction_flags(compiler, ins);
+ if (ins->resource_type != VKD3D_SHADER_RESOURCE_NONE)
+ vkd3d_string_buffer_printf(buffer, "_indexable");
+
+ shader_dump_precise_flags(compiler, ins->flags);
+
if (ins->resource_type != VKD3D_SHADER_RESOURCE_NONE)
{
- vkd3d_string_buffer_printf(buffer, "_indexable(");
+ vkd3d_string_buffer_printf(buffer, "(");
if (ins->raw)
vkd3d_string_buffer_printf(buffer, "raw_");
if (ins->structured)
@@ -2009,10 +1693,10 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
shader_print_int_literal(compiler, ",", ins->texel_offset.w, ")");
}
- if (ins->resource_data_type[0] != VKD3D_DATA_FLOAT
- || ins->resource_data_type[1] != VKD3D_DATA_FLOAT
- || ins->resource_data_type[2] != VKD3D_DATA_FLOAT
- || ins->resource_data_type[3] != VKD3D_DATA_FLOAT)
+ if (ins->resource_data_type[0] != VSIR_DATA_F32
+ || ins->resource_data_type[1] != VSIR_DATA_F32
+ || ins->resource_data_type[2] != VSIR_DATA_F32
+ || ins->resource_data_type[3] != VSIR_DATA_F32)
shader_dump_resource_data_type(compiler, ins->resource_data_type);
for (i = 0; i < ins->dst_count; ++i)
@@ -2276,9 +1960,8 @@ static void shader_print_descriptors(struct vkd3d_d3d_asm_compiler *compiler,
}
}
-enum vkd3d_result d3d_asm_compile(const struct vsir_program *program,
- const struct vkd3d_shader_compile_info *compile_info,
- struct vkd3d_shader_code *out, enum vsir_asm_flags flags)
+enum vkd3d_result d3d_asm_compile(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_code *out, enum vsir_asm_flags flags, struct vkd3d_shader_message_context *message_context)
{
const struct vkd3d_shader_version *shader_version = &program->shader_version;
enum vkd3d_shader_compile_option_formatting_flags formatting;
@@ -2286,8 +1969,10 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program,
{
.flags = flags,
};
+ struct vkd3d_shader_instruction *ins;
enum vkd3d_result result = VKD3D_OK;
struct vkd3d_string_buffer *buffer;
+ struct vsir_program_iterator it;
unsigned int indent, i, j;
const char *indent_str;
@@ -2344,6 +2029,14 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program,
if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_IO_SIGNATURES && shader_version->major >= 4)
compiler.flags |= VSIR_ASM_FLAG_DUMP_SIGNATURES;
+ if (compiler.flags & VSIR_ASM_FLAG_ALLOCATE_TEMPS)
+ {
+ if ((result = vsir_allocate_temp_registers(program, message_context)) < 0)
+ return result;
+ if ((result = vsir_update_dcl_temps(program, message_context)))
+ return result;
+ }
+
buffer = &compiler.buffer;
vkd3d_string_buffer_init(buffer);
@@ -2367,25 +2060,25 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program,
vkd3d_string_buffer_printf(buffer, "%s.text%s\n", compiler.colours.opcode, compiler.colours.reset);
indent = 0;
- for (i = 0; i < program->instructions.count; ++i)
- {
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
+ it = vsir_program_iterator(&program->instructions);
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
+ {
switch (ins->opcode)
{
- case VKD3DSIH_ELSE:
- case VKD3DSIH_ENDIF:
- case VKD3DSIH_ENDLOOP:
- case VKD3DSIH_ENDSWITCH:
+ case VSIR_OP_ELSE:
+ case VSIR_OP_ENDIF:
+ case VSIR_OP_ENDLOOP:
+ case VSIR_OP_ENDSWITCH:
if (indent)
--indent;
break;
- case VKD3DSIH_LABEL:
- case VKD3DSIH_HS_DECLS:
- case VKD3DSIH_HS_CONTROL_POINT_PHASE:
- case VKD3DSIH_HS_FORK_PHASE:
- case VKD3DSIH_HS_JOIN_PHASE:
+ case VSIR_OP_LABEL:
+ case VSIR_OP_HS_DECLS:
+ case VSIR_OP_HS_CONTROL_POINT_PHASE:
+ case VSIR_OP_HS_FORK_PHASE:
+ case VSIR_OP_HS_JOIN_PHASE:
indent = 0;
break;
@@ -2402,12 +2095,12 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program,
switch (ins->opcode)
{
- case VKD3DSIH_ELSE:
- case VKD3DSIH_IF:
- case VKD3DSIH_IFC:
- case VKD3DSIH_LOOP:
- case VKD3DSIH_SWITCH:
- case VKD3DSIH_LABEL:
+ case VSIR_OP_ELSE:
+ case VSIR_OP_IF:
+ case VSIR_OP_IFC:
+ case VSIR_OP_LOOP:
+ case VSIR_OP_SWITCH:
+ case VSIR_OP_LABEL:
++indent;
break;
@@ -2561,21 +2254,26 @@ static void trace_io_declarations(const struct vsir_program *program)
vkd3d_string_buffer_cleanup(&buffer);
}
-void vsir_program_trace(const struct vsir_program *program)
+void vsir_program_trace(struct vsir_program *program)
{
const unsigned int flags = VSIR_ASM_FLAG_DUMP_TYPES | VSIR_ASM_FLAG_DUMP_ALL_INDICES
| VSIR_ASM_FLAG_DUMP_SIGNATURES | VSIR_ASM_FLAG_DUMP_DESCRIPTORS;
+ struct vkd3d_shader_message_context message_context;
struct vkd3d_shader_code code;
const char *p, *q, *end;
+ vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_NONE);
+
trace_signature(&program->input_signature, "Input");
trace_signature(&program->output_signature, "Output");
trace_signature(&program->patch_constant_signature, "Patch-constant");
trace_io_declarations(program);
- if (d3d_asm_compile(program, NULL, &code, flags) != VKD3D_OK)
+ if (d3d_asm_compile(program, NULL, &code, flags, &message_context) != VKD3D_OK)
return;
+ vkd3d_shader_message_context_cleanup(&message_context);
+
end = (const char *)code.code + code.size;
for (p = code.code; p < end; p = q)
{
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index 57d874efe37..751e5578276 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -259,159 +259,159 @@ struct vkd3d_shader_sm1_parser
static const struct vkd3d_sm1_opcode_info vs_opcode_table[] =
{
/* Arithmetic */
- {VKD3D_SM1_OP_NOP, 0, 0, VKD3DSIH_NOP},
- {VKD3D_SM1_OP_MOV, 1, 1, VKD3DSIH_MOV},
- {VKD3D_SM1_OP_MOVA, 1, 1, VKD3DSIH_MOVA, {2, 0}},
- {VKD3D_SM1_OP_ADD, 1, 2, VKD3DSIH_ADD},
- {VKD3D_SM1_OP_SUB, 1, 2, VKD3DSIH_SUB},
- {VKD3D_SM1_OP_MAD, 1, 3, VKD3DSIH_MAD},
- {VKD3D_SM1_OP_MUL, 1, 2, VKD3DSIH_MUL},
- {VKD3D_SM1_OP_RCP, 1, 1, VKD3DSIH_RCP},
- {VKD3D_SM1_OP_RSQ, 1, 1, VKD3DSIH_RSQ},
- {VKD3D_SM1_OP_DP3, 1, 2, VKD3DSIH_DP3},
- {VKD3D_SM1_OP_DP4, 1, 2, VKD3DSIH_DP4},
- {VKD3D_SM1_OP_MIN, 1, 2, VKD3DSIH_MIN},
- {VKD3D_SM1_OP_MAX, 1, 2, VKD3DSIH_MAX},
- {VKD3D_SM1_OP_SLT, 1, 2, VKD3DSIH_SLT},
- {VKD3D_SM1_OP_SGE, 1, 2, VKD3DSIH_SGE},
- {VKD3D_SM1_OP_ABS, 1, 1, VKD3DSIH_ABS, {2, 0}},
- {VKD3D_SM1_OP_EXP, 1, 1, VKD3DSIH_EXP},
- {VKD3D_SM1_OP_LOG, 1, 1, VKD3DSIH_LOG},
- {VKD3D_SM1_OP_EXPP, 1, 1, VKD3DSIH_EXPP},
- {VKD3D_SM1_OP_LOGP, 1, 1, VKD3DSIH_LOGP},
- {VKD3D_SM1_OP_LIT, 1, 1, VKD3DSIH_LIT},
- {VKD3D_SM1_OP_DST, 1, 2, VKD3DSIH_DST},
- {VKD3D_SM1_OP_LRP, 1, 3, VKD3DSIH_LRP, {2, 0}},
- {VKD3D_SM1_OP_FRC, 1, 1, VKD3DSIH_FRC},
- {VKD3D_SM1_OP_POW, 1, 2, VKD3DSIH_POW, {2, 0}},
- {VKD3D_SM1_OP_CRS, 1, 2, VKD3DSIH_CRS, {2, 0}},
- {VKD3D_SM1_OP_SGN, 1, 3, VKD3DSIH_SGN, {2, 0}, {2, 1}},
- {VKD3D_SM1_OP_SGN, 1, 1, VKD3DSIH_SGN, {3, 0}},
- {VKD3D_SM1_OP_NRM, 1, 1, VKD3DSIH_NRM, {2, 0}},
- {VKD3D_SM1_OP_SINCOS, 1, 3, VKD3DSIH_SINCOS, {2, 0}, {2, 1}},
- {VKD3D_SM1_OP_SINCOS, 1, 1, VKD3DSIH_SINCOS, {3, 0}},
+ {VKD3D_SM1_OP_NOP, 0, 0, VSIR_OP_NOP},
+ {VKD3D_SM1_OP_MOV, 1, 1, VSIR_OP_MOV},
+ {VKD3D_SM1_OP_MOVA, 1, 1, VSIR_OP_MOVA, {2, 0}},
+ {VKD3D_SM1_OP_ADD, 1, 2, VSIR_OP_ADD},
+ {VKD3D_SM1_OP_SUB, 1, 2, VSIR_OP_SUB},
+ {VKD3D_SM1_OP_MAD, 1, 3, VSIR_OP_MAD},
+ {VKD3D_SM1_OP_MUL, 1, 2, VSIR_OP_MUL},
+ {VKD3D_SM1_OP_RCP, 1, 1, VSIR_OP_RCP},
+ {VKD3D_SM1_OP_RSQ, 1, 1, VSIR_OP_RSQ},
+ {VKD3D_SM1_OP_DP3, 1, 2, VSIR_OP_DP3},
+ {VKD3D_SM1_OP_DP4, 1, 2, VSIR_OP_DP4},
+ {VKD3D_SM1_OP_MIN, 1, 2, VSIR_OP_MIN},
+ {VKD3D_SM1_OP_MAX, 1, 2, VSIR_OP_MAX},
+ {VKD3D_SM1_OP_SLT, 1, 2, VSIR_OP_SLT},
+ {VKD3D_SM1_OP_SGE, 1, 2, VSIR_OP_SGE},
+ {VKD3D_SM1_OP_ABS, 1, 1, VSIR_OP_ABS, {2, 0}},
+ {VKD3D_SM1_OP_EXP, 1, 1, VSIR_OP_EXP},
+ {VKD3D_SM1_OP_LOG, 1, 1, VSIR_OP_LOG},
+ {VKD3D_SM1_OP_EXPP, 1, 1, VSIR_OP_EXPP},
+ {VKD3D_SM1_OP_LOGP, 1, 1, VSIR_OP_LOGP},
+ {VKD3D_SM1_OP_LIT, 1, 1, VSIR_OP_LIT},
+ {VKD3D_SM1_OP_DST, 1, 2, VSIR_OP_DST},
+ {VKD3D_SM1_OP_LRP, 1, 3, VSIR_OP_LRP, {2, 0}},
+ {VKD3D_SM1_OP_FRC, 1, 1, VSIR_OP_FRC},
+ {VKD3D_SM1_OP_POW, 1, 2, VSIR_OP_POW, {2, 0}},
+ {VKD3D_SM1_OP_CRS, 1, 2, VSIR_OP_CRS, {2, 0}},
+ {VKD3D_SM1_OP_SGN, 1, 3, VSIR_OP_SGN, {2, 0}, {2, 1}},
+ {VKD3D_SM1_OP_SGN, 1, 1, VSIR_OP_SGN, {3, 0}},
+ {VKD3D_SM1_OP_NRM, 1, 1, VSIR_OP_NRM, {2, 0}},
+ {VKD3D_SM1_OP_SINCOS, 1, 3, VSIR_OP_SINCOS, {2, 0}, {2, 1}},
+ {VKD3D_SM1_OP_SINCOS, 1, 1, VSIR_OP_SINCOS, {3, 0}},
/* Matrix */
- {VKD3D_SM1_OP_M4x4, 1, 2, VKD3DSIH_M4x4},
- {VKD3D_SM1_OP_M4x3, 1, 2, VKD3DSIH_M4x3},
- {VKD3D_SM1_OP_M3x4, 1, 2, VKD3DSIH_M3x4},
- {VKD3D_SM1_OP_M3x3, 1, 2, VKD3DSIH_M3x3},
- {VKD3D_SM1_OP_M3x2, 1, 2, VKD3DSIH_M3x2},
+ {VKD3D_SM1_OP_M4x4, 1, 2, VSIR_OP_M4x4},
+ {VKD3D_SM1_OP_M4x3, 1, 2, VSIR_OP_M4x3},
+ {VKD3D_SM1_OP_M3x4, 1, 2, VSIR_OP_M3x4},
+ {VKD3D_SM1_OP_M3x3, 1, 2, VSIR_OP_M3x3},
+ {VKD3D_SM1_OP_M3x2, 1, 2, VSIR_OP_M3x2},
/* Declarations */
- {VKD3D_SM1_OP_DCL, 0, 0, VKD3DSIH_DCL},
+ {VKD3D_SM1_OP_DCL, 0, 0, VSIR_OP_DCL},
/* Constant definitions */
- {VKD3D_SM1_OP_DEF, 1, 1, VKD3DSIH_DEF},
- {VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB, {2, 0}},
- {VKD3D_SM1_OP_DEFI, 1, 1, VKD3DSIH_DEFI, {2, 0}},
+ {VKD3D_SM1_OP_DEF, 1, 1, VSIR_OP_DEF},
+ {VKD3D_SM1_OP_DEFB, 1, 1, VSIR_OP_DEFB, {2, 0}},
+ {VKD3D_SM1_OP_DEFI, 1, 1, VSIR_OP_DEFI, {2, 0}},
/* Control flow */
- {VKD3D_SM1_OP_REP, 0, 1, VKD3DSIH_REP, {2, 0}},
- {VKD3D_SM1_OP_ENDREP, 0, 0, VKD3DSIH_ENDREP, {2, 0}},
- {VKD3D_SM1_OP_IF, 0, 1, VKD3DSIH_IF, {2, 0}},
- {VKD3D_SM1_OP_IFC, 0, 2, VKD3DSIH_IFC, {2, 1}},
- {VKD3D_SM1_OP_ELSE, 0, 0, VKD3DSIH_ELSE, {2, 0}},
- {VKD3D_SM1_OP_ENDIF, 0, 0, VKD3DSIH_ENDIF, {2, 0}},
- {VKD3D_SM1_OP_BREAK, 0, 0, VKD3DSIH_BREAK, {2, 1}},
- {VKD3D_SM1_OP_BREAKC, 0, 2, VKD3DSIH_BREAKC, {2, 1}},
- {VKD3D_SM1_OP_BREAKP, 0, 1, VKD3DSIH_BREAKP, {2, 1}},
- {VKD3D_SM1_OP_CALL, 0, 1, VKD3DSIH_CALL, {2, 0}},
- {VKD3D_SM1_OP_CALLNZ, 0, 2, VKD3DSIH_CALLNZ, {2, 0}},
- {VKD3D_SM1_OP_LOOP, 0, 2, VKD3DSIH_LOOP, {2, 0}},
- {VKD3D_SM1_OP_RET, 0, 0, VKD3DSIH_RET, {2, 0}},
- {VKD3D_SM1_OP_ENDLOOP, 0, 0, VKD3DSIH_ENDLOOP, {2, 0}},
- {VKD3D_SM1_OP_LABEL, 0, 1, VKD3DSIH_LABEL, {2, 0}},
-
- {VKD3D_SM1_OP_SETP, 1, 2, VKD3DSIH_SETP, {2, 1}},
- {VKD3D_SM1_OP_TEXLDL, 1, 2, VKD3DSIH_TEXLDL, {3, 0}},
- {0, 0, 0, VKD3DSIH_INVALID},
+ {VKD3D_SM1_OP_REP, 0, 1, VSIR_OP_REP, {2, 0}},
+ {VKD3D_SM1_OP_ENDREP, 0, 0, VSIR_OP_ENDREP, {2, 0}},
+ {VKD3D_SM1_OP_IF, 0, 1, VSIR_OP_IF, {2, 0}},
+ {VKD3D_SM1_OP_IFC, 0, 2, VSIR_OP_IFC, {2, 1}},
+ {VKD3D_SM1_OP_ELSE, 0, 0, VSIR_OP_ELSE, {2, 0}},
+ {VKD3D_SM1_OP_ENDIF, 0, 0, VSIR_OP_ENDIF, {2, 0}},
+ {VKD3D_SM1_OP_BREAK, 0, 0, VSIR_OP_BREAK, {2, 1}},
+ {VKD3D_SM1_OP_BREAKC, 0, 2, VSIR_OP_BREAKC, {2, 1}},
+ {VKD3D_SM1_OP_BREAKP, 0, 1, VSIR_OP_BREAKP, {2, 1}},
+ {VKD3D_SM1_OP_CALL, 0, 1, VSIR_OP_CALL, {2, 0}},
+ {VKD3D_SM1_OP_CALLNZ, 0, 2, VSIR_OP_CALLNZ, {2, 0}},
+ {VKD3D_SM1_OP_LOOP, 0, 2, VSIR_OP_LOOP, {2, 0}},
+ {VKD3D_SM1_OP_RET, 0, 0, VSIR_OP_RET, {2, 0}},
+ {VKD3D_SM1_OP_ENDLOOP, 0, 0, VSIR_OP_ENDLOOP, {2, 0}},
+ {VKD3D_SM1_OP_LABEL, 0, 1, VSIR_OP_LABEL, {2, 0}},
+
+ {VKD3D_SM1_OP_SETP, 1, 2, VSIR_OP_SETP, {2, 1}},
+ {VKD3D_SM1_OP_TEXLDL, 1, 2, VSIR_OP_TEXLDL, {3, 0}},
+ {0, 0, 0, VSIR_OP_INVALID},
};
static const struct vkd3d_sm1_opcode_info ps_opcode_table[] =
{
/* Arithmetic */
- {VKD3D_SM1_OP_NOP, 0, 0, VKD3DSIH_NOP},
- {VKD3D_SM1_OP_MOV, 1, 1, VKD3DSIH_MOV},
- {VKD3D_SM1_OP_ADD, 1, 2, VKD3DSIH_ADD},
- {VKD3D_SM1_OP_SUB, 1, 2, VKD3DSIH_SUB},
- {VKD3D_SM1_OP_MAD, 1, 3, VKD3DSIH_MAD},
- {VKD3D_SM1_OP_MUL, 1, 2, VKD3DSIH_MUL},
- {VKD3D_SM1_OP_RCP, 1, 1, VKD3DSIH_RCP, {2, 0}},
- {VKD3D_SM1_OP_RSQ, 1, 1, VKD3DSIH_RSQ, {2, 0}},
- {VKD3D_SM1_OP_DP3, 1, 2, VKD3DSIH_DP3},
- {VKD3D_SM1_OP_DP4, 1, 2, VKD3DSIH_DP4, {1, 2}},
- {VKD3D_SM1_OP_MIN, 1, 2, VKD3DSIH_MIN, {2, 0}},
- {VKD3D_SM1_OP_MAX, 1, 2, VKD3DSIH_MAX, {2, 0}},
- {VKD3D_SM1_OP_ABS, 1, 1, VKD3DSIH_ABS, {2, 0}},
- {VKD3D_SM1_OP_EXP, 1, 1, VKD3DSIH_EXP, {2, 0}},
- {VKD3D_SM1_OP_LOG, 1, 1, VKD3DSIH_LOG, {2, 0}},
- {VKD3D_SM1_OP_LRP, 1, 3, VKD3DSIH_LRP},
- {VKD3D_SM1_OP_FRC, 1, 1, VKD3DSIH_FRC, {2, 0}},
- {VKD3D_SM1_OP_CND, 1, 3, VKD3DSIH_CND, {1, 0}, {1, 4}},
- {VKD3D_SM1_OP_CMP, 1, 3, VKD3DSIH_CMP, {1, 2}},
- {VKD3D_SM1_OP_POW, 1, 2, VKD3DSIH_POW, {2, 0}},
- {VKD3D_SM1_OP_CRS, 1, 2, VKD3DSIH_CRS, {2, 0}},
- {VKD3D_SM1_OP_NRM, 1, 1, VKD3DSIH_NRM, {2, 0}},
- {VKD3D_SM1_OP_SINCOS, 1, 3, VKD3DSIH_SINCOS, {2, 0}, {2, 1}},
- {VKD3D_SM1_OP_SINCOS, 1, 1, VKD3DSIH_SINCOS, {3, 0}},
- {VKD3D_SM1_OP_DP2ADD, 1, 3, VKD3DSIH_DP2ADD, {2, 0}},
+ {VKD3D_SM1_OP_NOP, 0, 0, VSIR_OP_NOP},
+ {VKD3D_SM1_OP_MOV, 1, 1, VSIR_OP_MOV},
+ {VKD3D_SM1_OP_ADD, 1, 2, VSIR_OP_ADD},
+ {VKD3D_SM1_OP_SUB, 1, 2, VSIR_OP_SUB},
+ {VKD3D_SM1_OP_MAD, 1, 3, VSIR_OP_MAD},
+ {VKD3D_SM1_OP_MUL, 1, 2, VSIR_OP_MUL},
+ {VKD3D_SM1_OP_RCP, 1, 1, VSIR_OP_RCP, {2, 0}},
+ {VKD3D_SM1_OP_RSQ, 1, 1, VSIR_OP_RSQ, {2, 0}},
+ {VKD3D_SM1_OP_DP3, 1, 2, VSIR_OP_DP3},
+ {VKD3D_SM1_OP_DP4, 1, 2, VSIR_OP_DP4, {1, 2}},
+ {VKD3D_SM1_OP_MIN, 1, 2, VSIR_OP_MIN, {2, 0}},
+ {VKD3D_SM1_OP_MAX, 1, 2, VSIR_OP_MAX, {2, 0}},
+ {VKD3D_SM1_OP_ABS, 1, 1, VSIR_OP_ABS, {2, 0}},
+ {VKD3D_SM1_OP_EXP, 1, 1, VSIR_OP_EXP, {2, 0}},
+ {VKD3D_SM1_OP_LOG, 1, 1, VSIR_OP_LOG, {2, 0}},
+ {VKD3D_SM1_OP_LRP, 1, 3, VSIR_OP_LRP},
+ {VKD3D_SM1_OP_FRC, 1, 1, VSIR_OP_FRC, {2, 0}},
+ {VKD3D_SM1_OP_CND, 1, 3, VSIR_OP_CND, {1, 0}, {1, 4}},
+ {VKD3D_SM1_OP_CMP, 1, 3, VSIR_OP_CMP, {1, 2}},
+ {VKD3D_SM1_OP_POW, 1, 2, VSIR_OP_POW, {2, 0}},
+ {VKD3D_SM1_OP_CRS, 1, 2, VSIR_OP_CRS, {2, 0}},
+ {VKD3D_SM1_OP_NRM, 1, 1, VSIR_OP_NRM, {2, 0}},
+ {VKD3D_SM1_OP_SINCOS, 1, 3, VSIR_OP_SINCOS, {2, 0}, {2, 1}},
+ {VKD3D_SM1_OP_SINCOS, 1, 1, VSIR_OP_SINCOS, {3, 0}},
+ {VKD3D_SM1_OP_DP2ADD, 1, 3, VSIR_OP_DP2ADD, {2, 0}},
/* Matrix */
- {VKD3D_SM1_OP_M4x4, 1, 2, VKD3DSIH_M4x4, {2, 0}},
- {VKD3D_SM1_OP_M4x3, 1, 2, VKD3DSIH_M4x3, {2, 0}},
- {VKD3D_SM1_OP_M3x4, 1, 2, VKD3DSIH_M3x4, {2, 0}},
- {VKD3D_SM1_OP_M3x3, 1, 2, VKD3DSIH_M3x3, {2, 0}},
- {VKD3D_SM1_OP_M3x2, 1, 2, VKD3DSIH_M3x2, {2, 0}},
+ {VKD3D_SM1_OP_M4x4, 1, 2, VSIR_OP_M4x4, {2, 0}},
+ {VKD3D_SM1_OP_M4x3, 1, 2, VSIR_OP_M4x3, {2, 0}},
+ {VKD3D_SM1_OP_M3x4, 1, 2, VSIR_OP_M3x4, {2, 0}},
+ {VKD3D_SM1_OP_M3x3, 1, 2, VSIR_OP_M3x3, {2, 0}},
+ {VKD3D_SM1_OP_M3x2, 1, 2, VSIR_OP_M3x2, {2, 0}},
/* Declarations */
- {VKD3D_SM1_OP_DCL, 0, 0, VKD3DSIH_DCL, {2, 0}},
+ {VKD3D_SM1_OP_DCL, 0, 0, VSIR_OP_DCL, {2, 0}},
/* Constant definitions */
- {VKD3D_SM1_OP_DEF, 1, 1, VKD3DSIH_DEF},
- {VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB, {2, 0}},
- {VKD3D_SM1_OP_DEFI, 1, 1, VKD3DSIH_DEFI, {2, 1}},
+ {VKD3D_SM1_OP_DEF, 1, 1, VSIR_OP_DEF},
+ {VKD3D_SM1_OP_DEFB, 1, 1, VSIR_OP_DEFB, {2, 0}},
+ {VKD3D_SM1_OP_DEFI, 1, 1, VSIR_OP_DEFI, {2, 1}},
/* Control flow */
- {VKD3D_SM1_OP_REP, 0, 1, VKD3DSIH_REP, {2, 1}},
- {VKD3D_SM1_OP_ENDREP, 0, 0, VKD3DSIH_ENDREP, {2, 1}},
- {VKD3D_SM1_OP_IF, 0, 1, VKD3DSIH_IF, {2, 1}},
- {VKD3D_SM1_OP_IFC, 0, 2, VKD3DSIH_IFC, {2, 1}},
- {VKD3D_SM1_OP_ELSE, 0, 0, VKD3DSIH_ELSE, {2, 1}},
- {VKD3D_SM1_OP_ENDIF, 0, 0, VKD3DSIH_ENDIF, {2, 1}},
- {VKD3D_SM1_OP_BREAK, 0, 0, VKD3DSIH_BREAK, {2, 1}},
- {VKD3D_SM1_OP_BREAKC, 0, 2, VKD3DSIH_BREAKC, {2, 1}},
- {VKD3D_SM1_OP_BREAKP, 0, 1, VKD3DSIH_BREAKP, {2, 1}},
- {VKD3D_SM1_OP_CALL, 0, 1, VKD3DSIH_CALL, {2, 1}},
- {VKD3D_SM1_OP_CALLNZ, 0, 2, VKD3DSIH_CALLNZ, {2, 1}},
- {VKD3D_SM1_OP_LOOP, 0, 2, VKD3DSIH_LOOP, {3, 0}},
- {VKD3D_SM1_OP_RET, 0, 0, VKD3DSIH_RET, {2, 1}},
- {VKD3D_SM1_OP_ENDLOOP, 0, 0, VKD3DSIH_ENDLOOP, {3, 0}},
- {VKD3D_SM1_OP_LABEL, 0, 1, VKD3DSIH_LABEL, {2, 1}},
+ {VKD3D_SM1_OP_REP, 0, 1, VSIR_OP_REP, {2, 1}},
+ {VKD3D_SM1_OP_ENDREP, 0, 0, VSIR_OP_ENDREP, {2, 1}},
+ {VKD3D_SM1_OP_IF, 0, 1, VSIR_OP_IF, {2, 1}},
+ {VKD3D_SM1_OP_IFC, 0, 2, VSIR_OP_IFC, {2, 1}},
+ {VKD3D_SM1_OP_ELSE, 0, 0, VSIR_OP_ELSE, {2, 1}},
+ {VKD3D_SM1_OP_ENDIF, 0, 0, VSIR_OP_ENDIF, {2, 1}},
+ {VKD3D_SM1_OP_BREAK, 0, 0, VSIR_OP_BREAK, {2, 1}},
+ {VKD3D_SM1_OP_BREAKC, 0, 2, VSIR_OP_BREAKC, {2, 1}},
+ {VKD3D_SM1_OP_BREAKP, 0, 1, VSIR_OP_BREAKP, {2, 1}},
+ {VKD3D_SM1_OP_CALL, 0, 1, VSIR_OP_CALL, {2, 1}},
+ {VKD3D_SM1_OP_CALLNZ, 0, 2, VSIR_OP_CALLNZ, {2, 1}},
+ {VKD3D_SM1_OP_LOOP, 0, 2, VSIR_OP_LOOP, {3, 0}},
+ {VKD3D_SM1_OP_RET, 0, 0, VSIR_OP_RET, {2, 1}},
+ {VKD3D_SM1_OP_ENDLOOP, 0, 0, VSIR_OP_ENDLOOP, {3, 0}},
+ {VKD3D_SM1_OP_LABEL, 0, 1, VSIR_OP_LABEL, {2, 1}},
/* Texture */
- {VKD3D_SM1_OP_TEXCOORD, 1, 0, VKD3DSIH_TEXCOORD, {0, 0}, {1, 3}},
- {VKD3D_SM1_OP_TEXCOORD, 1, 1, VKD3DSIH_TEXCOORD, {1, 4}, {1, 4}},
- {VKD3D_SM1_OP_TEXKILL, 1, 0, VKD3DSIH_TEXKILL, {1, 0}},
- {VKD3D_SM1_OP_TEX, 1, 0, VKD3DSIH_TEX, {0, 0}, {1, 3}},
- {VKD3D_SM1_OP_TEX, 1, 1, VKD3DSIH_TEX, {1, 4}, {1, 4}},
- {VKD3D_SM1_OP_TEX, 1, 2, VKD3DSIH_TEX, {2, 0}},
- {VKD3D_SM1_OP_TEXBEM, 1, 1, VKD3DSIH_TEXBEM, {0, 0}, {1, 3}},
- {VKD3D_SM1_OP_TEXBEML, 1, 1, VKD3DSIH_TEXBEML, {1, 0}, {1, 3}},
- {VKD3D_SM1_OP_TEXREG2AR, 1, 1, VKD3DSIH_TEXREG2AR, {1, 0}, {1, 3}},
- {VKD3D_SM1_OP_TEXREG2GB, 1, 1, VKD3DSIH_TEXREG2GB, {1, 0}, {1, 3}},
- {VKD3D_SM1_OP_TEXREG2RGB, 1, 1, VKD3DSIH_TEXREG2RGB, {1, 2}, {1, 3}},
- {VKD3D_SM1_OP_TEXM3x2PAD, 1, 1, VKD3DSIH_TEXM3x2PAD, {1, 0}, {1, 3}},
- {VKD3D_SM1_OP_TEXM3x2TEX, 1, 1, VKD3DSIH_TEXM3x2TEX, {1, 0}, {1, 3}},
- {VKD3D_SM1_OP_TEXM3x3PAD, 1, 1, VKD3DSIH_TEXM3x3PAD, {1, 0}, {1, 3}},
- {VKD3D_SM1_OP_TEXM3x3DIFF, 1, 1, VKD3DSIH_TEXM3x3DIFF, {0, 0}, {0, 0}},
- {VKD3D_SM1_OP_TEXM3x3SPEC, 1, 2, VKD3DSIH_TEXM3x3SPEC, {1, 0}, {1, 3}},
- {VKD3D_SM1_OP_TEXM3x3VSPEC, 1, 1, VKD3DSIH_TEXM3x3VSPEC, {1, 0}, {1, 3}},
- {VKD3D_SM1_OP_TEXM3x3TEX, 1, 1, VKD3DSIH_TEXM3x3TEX, {1, 0}, {1, 3}},
- {VKD3D_SM1_OP_TEXDP3TEX, 1, 1, VKD3DSIH_TEXDP3TEX, {1, 2}, {1, 3}},
- {VKD3D_SM1_OP_TEXM3x2DEPTH, 1, 1, VKD3DSIH_TEXM3x2DEPTH, {1, 3}, {1, 3}},
- {VKD3D_SM1_OP_TEXDP3, 1, 1, VKD3DSIH_TEXDP3, {1, 2}, {1, 3}},
- {VKD3D_SM1_OP_TEXM3x3, 1, 1, VKD3DSIH_TEXM3x3, {1, 2}, {1, 3}},
- {VKD3D_SM1_OP_TEXDEPTH, 1, 0, VKD3DSIH_TEXDEPTH, {1, 4}, {1, 4}},
- {VKD3D_SM1_OP_BEM, 1, 2, VKD3DSIH_BEM, {1, 4}, {1, 4}},
- {VKD3D_SM1_OP_DSX, 1, 1, VKD3DSIH_DSX, {2, 1}},
- {VKD3D_SM1_OP_DSY, 1, 1, VKD3DSIH_DSY, {2, 1}},
- {VKD3D_SM1_OP_TEXLDD, 1, 4, VKD3DSIH_TEXLDD, {2, 1}},
- {VKD3D_SM1_OP_SETP, 1, 2, VKD3DSIH_SETP, {2, 1}},
- {VKD3D_SM1_OP_TEXLDL, 1, 2, VKD3DSIH_TEXLDL, {3, 0}},
- {VKD3D_SM1_OP_PHASE, 0, 0, VKD3DSIH_PHASE, {1, 4}, {1, 4}},
- {0, 0, 0, VKD3DSIH_INVALID},
+ {VKD3D_SM1_OP_TEXCOORD, 1, 0, VSIR_OP_TEXCOORD, {0, 0}, {1, 3}},
+ {VKD3D_SM1_OP_TEXCOORD, 1, 1, VSIR_OP_TEXCRD, {1, 4}, {1, 4}},
+ {VKD3D_SM1_OP_TEXKILL, 1, 0, VSIR_OP_TEXKILL, {1, 0}},
+ {VKD3D_SM1_OP_TEX, 1, 0, VSIR_OP_TEX, {0, 0}, {1, 3}},
+ {VKD3D_SM1_OP_TEX, 1, 1, VSIR_OP_TEXLD, {1, 4}, {1, 4}},
+ {VKD3D_SM1_OP_TEX, 1, 2, VSIR_OP_TEXLD, {2, 0}},
+ {VKD3D_SM1_OP_TEXBEM, 1, 1, VSIR_OP_TEXBEM, {0, 0}, {1, 3}},
+ {VKD3D_SM1_OP_TEXBEML, 1, 1, VSIR_OP_TEXBEML, {1, 0}, {1, 3}},
+ {VKD3D_SM1_OP_TEXREG2AR, 1, 1, VSIR_OP_TEXREG2AR, {1, 0}, {1, 3}},
+ {VKD3D_SM1_OP_TEXREG2GB, 1, 1, VSIR_OP_TEXREG2GB, {1, 0}, {1, 3}},
+ {VKD3D_SM1_OP_TEXREG2RGB, 1, 1, VSIR_OP_TEXREG2RGB, {1, 2}, {1, 3}},
+ {VKD3D_SM1_OP_TEXM3x2PAD, 1, 1, VSIR_OP_TEXM3x2PAD, {1, 0}, {1, 3}},
+ {VKD3D_SM1_OP_TEXM3x2TEX, 1, 1, VSIR_OP_TEXM3x2TEX, {1, 0}, {1, 3}},
+ {VKD3D_SM1_OP_TEXM3x3PAD, 1, 1, VSIR_OP_TEXM3x3PAD, {1, 0}, {1, 3}},
+ {VKD3D_SM1_OP_TEXM3x3DIFF, 1, 1, VSIR_OP_TEXM3x3DIFF, {0, 0}, {0, 0}},
+ {VKD3D_SM1_OP_TEXM3x3SPEC, 1, 2, VSIR_OP_TEXM3x3SPEC, {1, 0}, {1, 3}},
+ {VKD3D_SM1_OP_TEXM3x3VSPEC, 1, 1, VSIR_OP_TEXM3x3VSPEC, {1, 0}, {1, 3}},
+ {VKD3D_SM1_OP_TEXM3x3TEX, 1, 1, VSIR_OP_TEXM3x3TEX, {1, 0}, {1, 3}},
+ {VKD3D_SM1_OP_TEXDP3TEX, 1, 1, VSIR_OP_TEXDP3TEX, {1, 2}, {1, 3}},
+ {VKD3D_SM1_OP_TEXM3x2DEPTH, 1, 1, VSIR_OP_TEXM3x2DEPTH, {1, 3}, {1, 3}},
+ {VKD3D_SM1_OP_TEXDP3, 1, 1, VSIR_OP_TEXDP3, {1, 2}, {1, 3}},
+ {VKD3D_SM1_OP_TEXM3x3, 1, 1, VSIR_OP_TEXM3x3, {1, 2}, {1, 3}},
+ {VKD3D_SM1_OP_TEXDEPTH, 1, 0, VSIR_OP_TEXDEPTH, {1, 4}, {1, 4}},
+ {VKD3D_SM1_OP_BEM, 1, 2, VSIR_OP_BEM, {1, 4}, {1, 4}},
+ {VKD3D_SM1_OP_DSX, 1, 1, VSIR_OP_DSX, {2, 1}},
+ {VKD3D_SM1_OP_DSY, 1, 1, VSIR_OP_DSY, {2, 1}},
+ {VKD3D_SM1_OP_TEXLDD, 1, 4, VSIR_OP_TEXLDD, {2, 1}},
+ {VKD3D_SM1_OP_SETP, 1, 2, VSIR_OP_SETP, {2, 1}},
+ {VKD3D_SM1_OP_TEXLDL, 1, 2, VSIR_OP_TEXLDL, {3, 0}},
+ {VKD3D_SM1_OP_PHASE, 0, 0, VSIR_OP_PHASE, {1, 4}, {1, 4}},
+ {0, 0, 0, VSIR_OP_INVALID},
};
static const struct
@@ -475,7 +475,7 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info(
for (;;)
{
info = &sm1->opcode_table[i++];
- if (info->vkd3d_opcode == VKD3DSIH_INVALID)
+ if (info->vkd3d_opcode == VSIR_OP_INVALID)
return NULL;
if (opcode == info->sm1_opcode
@@ -563,7 +563,7 @@ static void d3dbc_parse_register(struct vkd3d_shader_sm1_parser *d3dbc,
reg_type = parse_register_type(d3dbc, param, &index_offset);
idx_count = idx_count_from_reg_type(reg_type);
- vsir_register_init(reg, reg_type, VKD3D_DATA_FLOAT, idx_count);
+ vsir_register_init(reg, reg_type, VSIR_DATA_F32, idx_count);
reg->precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT;
reg->non_uniform = false;
if (idx_count == 1)
@@ -994,7 +994,7 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co
/* DCL instructions do not have sources or destinations, but they
* read two tokens to a semantic. See
* shader_sm1_read_semantic(). */
- if (opcode_info->vkd3d_opcode == VKD3DSIH_DCL)
+ if (opcode_info->vkd3d_opcode == VSIR_OP_DCL)
{
*ptr += 2;
}
@@ -1002,7 +1002,7 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co
* four tokens for that source. See shader_sm1_read_immconst().
* Technically shader model 1 doesn't have integer registers or DEFI; we
* handle it here anyway because it's easy. */
- else if (opcode_info->vkd3d_opcode == VKD3DSIH_DEF || opcode_info->vkd3d_opcode == VKD3DSIH_DEFI)
+ else if (opcode_info->vkd3d_opcode == VSIR_OP_DEF || opcode_info->vkd3d_opcode == VSIR_OP_DEFI)
{
*ptr += 3;
}
@@ -1088,10 +1088,10 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1,
{
semantic->resource_type = resource_type_table[resource_type];
}
- semantic->resource_data_type[0] = VKD3D_DATA_FLOAT;
- semantic->resource_data_type[1] = VKD3D_DATA_FLOAT;
- semantic->resource_data_type[2] = VKD3D_DATA_FLOAT;
- semantic->resource_data_type[3] = VKD3D_DATA_FLOAT;
+ semantic->resource_data_type[0] = VSIR_DATA_F32;
+ semantic->resource_data_type[1] = VSIR_DATA_F32;
+ semantic->resource_data_type[2] = VSIR_DATA_F32;
+ semantic->resource_data_type[3] = VSIR_DATA_F32;
shader_sm1_parse_dst_param(sm1, dst_token, NULL, &semantic->resource.reg);
range = &semantic->resource.range;
range->space = 0;
@@ -1101,7 +1101,7 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1,
}
static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr,
- struct vkd3d_shader_src_param *src_param, enum vsir_dimension dimension, enum vkd3d_data_type data_type)
+ struct vkd3d_shader_src_param *src_param, enum vsir_dimension dimension, enum vsir_data_type data_type)
{
unsigned int count = dimension == VSIR_DIMENSION_VEC4 ? 4 : 1;
@@ -1194,7 +1194,7 @@ static void shader_sm1_read_comment(struct vkd3d_shader_sm1_parser *sm1)
static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1, struct vkd3d_shader_instruction *ins)
{
- if ((ins->opcode == VKD3DSIH_BREAKP || ins->opcode == VKD3DSIH_IF) && ins->flags)
+ if ((ins->opcode == VSIR_OP_BREAKP || ins->opcode == VSIR_OP_IF) && ins->flags)
{
vkd3d_shader_parser_warning(&sm1->p, VKD3D_SHADER_WARNING_D3DBC_IGNORED_INSTRUCTION_FLAGS,
"Ignoring unexpected instruction flags %#x.", ins->flags);
@@ -1242,7 +1242,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
goto fail;
}
- if (opcode_info->vkd3d_opcode == VKD3DSIH_TEXKILL)
+ if (opcode_info->vkd3d_opcode == VSIR_OP_TEXKILL)
{
vsir_src_count = 1;
vsir_dst_count = 0;
@@ -1272,10 +1272,10 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
ins->resource_type = VKD3D_SHADER_RESOURCE_NONE;
ins->resource_stride = 0;
- ins->resource_data_type[0] = VKD3D_DATA_FLOAT;
- ins->resource_data_type[1] = VKD3D_DATA_FLOAT;
- ins->resource_data_type[2] = VKD3D_DATA_FLOAT;
- ins->resource_data_type[3] = VKD3D_DATA_FLOAT;
+ ins->resource_data_type[0] = VSIR_DATA_F32;
+ ins->resource_data_type[1] = VSIR_DATA_F32;
+ ins->resource_data_type[2] = VSIR_DATA_F32;
+ ins->resource_data_type[3] = VSIR_DATA_F32;
memset(&ins->texel_offset, 0, sizeof(ins->texel_offset));
p = *ptr;
@@ -1288,29 +1288,29 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
goto fail;
}
- if (ins->opcode == VKD3DSIH_DCL)
+ if (ins->opcode == VSIR_OP_DCL)
{
shader_sm1_read_semantic(sm1, &p, &ins->declaration.semantic);
}
- else if (ins->opcode == VKD3DSIH_DEF)
+ else if (ins->opcode == VSIR_OP_DEF)
{
shader_sm1_read_dst_param(sm1, &p, dst_param);
- shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_FLOAT);
+ shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VSIR_DATA_F32);
shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true);
}
- else if (ins->opcode == VKD3DSIH_DEFB)
+ else if (ins->opcode == VSIR_OP_DEFB)
{
shader_sm1_read_dst_param(sm1, &p, dst_param);
- shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_SCALAR, VKD3D_DATA_UINT);
+ shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_SCALAR, VSIR_DATA_U32);
shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true);
}
- else if (ins->opcode == VKD3DSIH_DEFI)
+ else if (ins->opcode == VSIR_OP_DEFI)
{
shader_sm1_read_dst_param(sm1, &p, dst_param);
- shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_INT);
+ shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VSIR_DATA_I32);
shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true);
}
- else if (ins->opcode == VKD3DSIH_TEXKILL)
+ else if (ins->opcode == VSIR_OP_TEXKILL)
{
/* TEXKILL, uniquely, encodes its argument as a destination, when it is
* semantically a source. Since we have multiple passes which operate
@@ -1360,7 +1360,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
return;
fail:
- ins->opcode = VKD3DSIH_INVALID;
+ ins->opcode = VSIR_OP_INVALID;
*ptr = sm1->end;
}
@@ -1472,7 +1472,6 @@ static uint32_t get_external_constant_count(struct vkd3d_shader_sm1_parser *sm1,
int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
struct vkd3d_shader_message_context *message_context, struct vsir_program *program)
{
- struct vkd3d_shader_instruction_array *instructions;
struct vkd3d_shader_sm1_parser sm1 = {0};
struct vkd3d_shader_instruction *ins;
unsigned int i;
@@ -1484,26 +1483,22 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c
return ret;
}
- instructions = &program->instructions;
while (!shader_sm1_is_end(&sm1))
{
- if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
+ if (!(ins = vsir_program_append(program)))
{
- ERR("Failed to allocate instructions.\n");
vkd3d_shader_parser_error(&sm1.p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory.");
vsir_program_cleanup(program);
return VKD3D_ERROR_OUT_OF_MEMORY;
}
- ins = &instructions->elements[instructions->count];
shader_sm1_read_instruction(&sm1, ins);
- if (ins->opcode == VKD3DSIH_INVALID)
+ if (ins->opcode == VSIR_OP_INVALID)
{
WARN("Encountered unrecognized or invalid instruction.\n");
vsir_program_cleanup(program);
return VKD3D_ERROR_INVALID_SHADER;
}
- ++instructions->count;
}
for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i)
@@ -1518,7 +1513,10 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c
return ret;
}
- return VKD3D_OK;
+ if (program->normalisation_level >= VSIR_NORMALISED_SM4)
+ ret = vsir_program_lower_d3dbc(program, config_flags, compile_info, message_context);
+
+ return ret;
}
bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, const char *semantic_name,
@@ -1662,7 +1660,7 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir(
for (;;)
{
info = &d3dbc->opcode_table[i++];
- if (info->vkd3d_opcode == VKD3DSIH_INVALID)
+ if (info->vkd3d_opcode == VSIR_OP_INVALID)
return NULL;
if (vkd3d_opcode == info->vkd3d_opcode
@@ -1681,7 +1679,8 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir_
if (!(info = shader_sm1_get_opcode_info_from_vsir(d3dbc, ins->opcode)))
{
vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE,
- "Opcode %#x not supported for shader profile.", ins->opcode);
+ "Instruction \"%s\" (%#x) is not supported for the current target.",
+ vsir_opcode_get_name(ins->opcode, "<unknown>"), ins->opcode);
d3dbc->failed = true;
return NULL;
}
@@ -1689,16 +1688,16 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir_
if (ins->dst_count != info->dst_count)
{
vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_COUNT,
- "Invalid destination count %u for vsir instruction %#x (expected %u).",
- ins->dst_count, ins->opcode, info->dst_count);
+ "Invalid destination parameter count %zu for instruction \"%s\" (%#x); expected %u.",
+ ins->dst_count, vsir_opcode_get_name(ins->opcode, "<unknown>"), ins->opcode, info->dst_count);
d3dbc->failed = true;
return NULL;
}
if (ins->src_count != info->src_count)
{
vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_COUNT,
- "Invalid source count %u for vsir instruction %#x (expected %u).",
- ins->src_count, ins->opcode, info->src_count);
+ "Invalid source parameter count %zu for instruction \"%s\" (%#x); expected %u.",
+ ins->src_count, vsir_opcode_get_name(ins->opcode, "<unknown>"), ins->opcode, info->src_count);
d3dbc->failed = true;
return NULL;
}
@@ -1772,7 +1771,7 @@ static bool is_inconsequential_instr(const struct vkd3d_shader_instruction *ins)
const struct vkd3d_shader_src_param *src = &ins->src[0];
unsigned int i;
- if (ins->opcode != VKD3DSIH_MOV)
+ if (ins->opcode != VSIR_OP_MOV)
return false;
if (dst->modifiers != VKD3DSPDM_NONE)
return false;
@@ -1829,6 +1828,7 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v
struct vkd3d_bytecode_buffer *buffer = &d3dbc->buffer;
const struct vkd3d_shader_src_param *src;
const struct vkd3d_sm1_opcode_info *info;
+ size_t size, token_position;
unsigned int i;
uint32_t token;
@@ -1841,9 +1841,7 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v
token = info->sm1_opcode;
token |= VKD3D_SM1_INSTRUCTION_FLAGS_MASK & (ins->flags << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT);
- if (version->major > 1)
- token |= (ins->dst_count + ins->src_count) << VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT;
- put_u32(buffer, token);
+ token_position = put_u32(buffer, 0);
for (i = 0; i < ins->dst_count; ++i)
{
@@ -1863,6 +1861,14 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v
if (src->reg.idx_count && src->reg.idx[0].rel_addr)
write_sm1_src_register(buffer, src->reg.idx[0].rel_addr);
}
+
+ if (version->major > 1)
+ {
+ size = (bytecode_get_size(buffer) - token_position) / sizeof(uint32_t);
+ token |= ((size - 1) << VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT);
+ }
+
+ set_u32(buffer, token_position, token);
};
static void d3dbc_write_texkill(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins)
@@ -1982,55 +1988,56 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str
switch (ins->opcode)
{
- case VKD3DSIH_DEF:
+ case VSIR_OP_DEF:
d3dbc_write_vsir_def(d3dbc, ins);
break;
- case VKD3DSIH_DCL:
+ case VSIR_OP_DCL:
d3dbc_write_vsir_dcl(d3dbc, ins);
break;
- case VKD3DSIH_TEXKILL:
+ case VSIR_OP_TEXKILL:
d3dbc_write_texkill(d3dbc, ins);
break;
- case VKD3DSIH_ABS:
- case VKD3DSIH_ADD:
- case VKD3DSIH_CMP:
- case VKD3DSIH_DP2ADD:
- case VKD3DSIH_DP3:
- case VKD3DSIH_DP4:
- case VKD3DSIH_DSX:
- case VKD3DSIH_DSY:
- case VKD3DSIH_ELSE:
- case VKD3DSIH_ENDIF:
- case VKD3DSIH_FRC:
- case VKD3DSIH_IFC:
- case VKD3DSIH_MAD:
- case VKD3DSIH_MAX:
- case VKD3DSIH_MIN:
- case VKD3DSIH_MOV:
- case VKD3DSIH_MOVA:
- case VKD3DSIH_MUL:
- case VKD3DSIH_SINCOS:
- case VKD3DSIH_SLT:
- case VKD3DSIH_TEX:
- case VKD3DSIH_TEXLDD:
+ case VSIR_OP_ABS:
+ case VSIR_OP_ADD:
+ case VSIR_OP_CMP:
+ case VSIR_OP_DP2ADD:
+ case VSIR_OP_DP3:
+ case VSIR_OP_DP4:
+ case VSIR_OP_DSX:
+ case VSIR_OP_DSY:
+ case VSIR_OP_ELSE:
+ case VSIR_OP_ENDIF:
+ case VSIR_OP_FRC:
+ case VSIR_OP_IFC:
+ case VSIR_OP_MAD:
+ case VSIR_OP_MAX:
+ case VSIR_OP_MIN:
+ case VSIR_OP_MOV:
+ case VSIR_OP_MOVA:
+ case VSIR_OP_MUL:
+ case VSIR_OP_SINCOS:
+ case VSIR_OP_SLT:
+ case VSIR_OP_TEXLD:
+ case VSIR_OP_TEXLDL:
+ case VSIR_OP_TEXLDD:
d3dbc_write_instruction(d3dbc, ins);
break;
- case VKD3DSIH_EXP:
- case VKD3DSIH_LOG:
- case VKD3DSIH_RCP:
- case VKD3DSIH_RSQ:
+ case VSIR_OP_EXP:
+ case VSIR_OP_LOG:
+ case VSIR_OP_RCP:
+ case VSIR_OP_RSQ:
writemask = ins->dst->write_mask;
if (writemask != VKD3DSP_WRITEMASK_0 && writemask != VKD3DSP_WRITEMASK_1
&& writemask != VKD3DSP_WRITEMASK_2 && writemask != VKD3DSP_WRITEMASK_3)
{
vkd3d_shader_error(d3dbc->message_context, &ins->location,
VKD3D_SHADER_ERROR_D3DBC_INVALID_WRITEMASK,
- "writemask %#x for vsir instruction with opcode %#x is not single component.",
- writemask, ins->opcode);
+ "Writemask %#x for instruction \"%s\" (%#x) is not single component.",
+ writemask, vsir_opcode_get_name(ins->opcode, "<unknown>"), ins->opcode);
d3dbc->failed = true;
}
d3dbc_write_instruction(d3dbc, ins);
@@ -2038,7 +2045,8 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str
default:
vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE,
- "vsir instruction with opcode %#x.", ins->opcode);
+ "Internal compiler error: Unhandled instruction \"%s\" (%#x).",
+ vsir_opcode_get_name(ins->opcode, "<unknown>"), ins->opcode);
d3dbc->failed = true;
break;
}
@@ -2067,6 +2075,13 @@ static void d3dbc_write_semantic_dcl(struct d3dbc_compiler *d3dbc,
VKD3D_ASSERT(ret);
reg.reg.type = output ? VKD3DSPR_OUTPUT : VKD3DSPR_INPUT;
reg.reg.idx[0].offset = element->register_index;
+ if (!vkd3d_shader_ver_ge(version, 3, 0))
+ {
+ if (reg.reg.idx[0].offset > SM1_RASTOUT_REGISTER_OFFSET)
+ reg.reg.idx[0].offset -= SM1_RASTOUT_REGISTER_OFFSET;
+ else if (reg.reg.idx[0].offset > SM1_COLOR_REGISTER_OFFSET)
+ reg.reg.idx[0].offset -= SM1_COLOR_REGISTER_OFFSET;
+ }
}
token = VKD3D_SM1_OP_DCL;
@@ -2112,11 +2127,13 @@ static void d3dbc_write_semantic_dcls(struct d3dbc_compiler *d3dbc)
static void d3dbc_write_program_instructions(struct d3dbc_compiler *d3dbc)
{
- struct vsir_program *program = d3dbc->program;
- unsigned int i;
+ struct vsir_program_iterator it = vsir_program_iterator(&d3dbc->program->instructions);
+ struct vkd3d_shader_instruction *ins;
- for (i = 0; i < program->instructions.count; ++i)
- d3dbc_write_vsir_instruction(d3dbc, &program->instructions.elements[i]);
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
+ {
+ d3dbc_write_vsir_instruction(d3dbc, ins);
+ }
}
int d3dbc_compile(struct vsir_program *program, uint64_t config_flags,
@@ -2128,6 +2145,12 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags,
struct vkd3d_bytecode_buffer *buffer = &d3dbc.buffer;
int result;
+ if ((result = vsir_allocate_temp_registers(program, message_context)))
+ return result;
+
+ if ((result = vsir_update_dcl_temps(program, message_context)))
+ return result;
+
d3dbc.program = program;
d3dbc.message_context = message_context;
switch (version->type)
@@ -2147,7 +2170,7 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags,
}
put_u32(buffer, sm1_version(version->type, version->major, version->minor));
- d3dbc_write_comment(&d3dbc, VKD3D_MAKE_TAG('C','T','A','B'), ctab);
+ d3dbc_write_comment(&d3dbc, TAG_CTAB, ctab);
d3dbc_write_semantic_dcls(&d3dbc);
d3dbc_write_program_instructions(&d3dbc);
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxbc.c b/libs/vkd3d/libs/vkd3d-shader/dxbc.c
index 9e3a57132a1..45a45c3ad4a 100644
--- a/libs/vkd3d/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/dxbc.c
@@ -388,7 +388,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
{
WARN("Invalid data size %#zx.\n", section->data.size);
vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE,
- "Section size %zu is smaller than the minimum signature header size.\n", section->data.size);
+ "Section size %zu is smaller than the minimum signature header size.", section->data.size);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
@@ -402,7 +402,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
{
WARN("Invalid header size %#x.\n", header_size);
vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE,
- "Signature header size %#x is invalid.\n", header_size);
+ "Signature header size %#x is invalid.", header_size);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
skip_dword_unknown(&ptr, i - 2);
@@ -438,7 +438,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
|| !(e[i].semantic_name = vkd3d_strdup(name)))
{
vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_STRING_REFERENCE,
- "Element %u has invalid semantic name reference %#zx (data size %#zx).\n",
+ "Element %u has invalid semantic name reference %#zx (data size %#zx).",
i, name_offset, section->data.size);
fail = true;
}
@@ -447,7 +447,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
if ((e[i].component_type = read_u32(&ptr)) > VKD3D_SHADER_COMPONENT_FLOAT)
{
vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_COMPONENT_TYPE,
- "Element %u has invalid component type %#x.\n", i, e[i].component_type);
+ "Element %u has invalid component type %#x.", i, e[i].component_type);
fail = true;
}
e[i].register_index = read_u32(&ptr);
@@ -531,7 +531,7 @@ static int shdr_parse_features(const struct vkd3d_shader_dxbc_section_desc *sect
{
WARN("Invalid data size %#zx.\n", section->data.size);
vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE,
- "SFI0 section size %zu is too small to contain flags.\n", section->data.size);
+ "SFI0 section size %zu is too small to contain flags.", section->data.size);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
flags = read_u64(&ptr);
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
index ca79939a39b..c448e000cf9 100644
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
@@ -643,16 +643,22 @@ struct sm6_type
enum sm6_value_type
{
+ VALUE_TYPE_INVALID,
VALUE_TYPE_FUNCTION,
- VALUE_TYPE_REG,
VALUE_TYPE_DATA,
VALUE_TYPE_HANDLE,
VALUE_TYPE_SSA,
VALUE_TYPE_ICB,
VALUE_TYPE_IDXTEMP,
VALUE_TYPE_GROUPSHAREDMEM,
+ VALUE_TYPE_CONSTANT,
VALUE_TYPE_UNDEFINED,
- VALUE_TYPE_INVALID,
+};
+
+struct sm6_index
+{
+ const struct sm6_value *index;
+ bool is_in_bounds;
};
struct sm6_function_data
@@ -678,16 +684,24 @@ struct sm6_icb_data
{
unsigned int data_id;
unsigned int id;
+ struct sm6_index index;
};
struct sm6_idxtemp_data
{
unsigned int id;
+ struct sm6_index index;
};
struct sm6_groupsharedmem_data
{
unsigned int id;
+ struct sm6_index index;
+};
+
+struct sm6_constant_data
+{
+ union vsir_immediate_constant immconst;
};
struct sm6_value
@@ -696,6 +710,7 @@ struct sm6_value
enum sm6_value_type value_type;
unsigned int structure_stride;
bool is_back_ref;
+ bool non_uniform;
union
{
struct sm6_function_data function;
@@ -705,8 +720,8 @@ struct sm6_value
struct sm6_icb_data icb;
struct sm6_idxtemp_data idxtemp;
struct sm6_groupsharedmem_data groupsharedmem;
+ struct sm6_constant_data constant;
} u;
- struct vkd3d_shader_register reg;
};
struct dxil_record
@@ -731,7 +746,7 @@ struct incoming_value
struct sm6_phi
{
- struct vkd3d_shader_register reg;
+ struct sm6_value value;
struct incoming_value *incoming;
size_t incoming_capacity;
size_t incoming_count;
@@ -867,9 +882,9 @@ struct sm6_descriptor_info
struct vkd3d_shader_register_range range;
enum vkd3d_shader_resource_type resource_type;
enum dxil_resource_kind kind;
- enum vkd3d_data_type resource_data_type;
+ enum vsir_data_type resource_data_type;
enum vkd3d_shader_register_type reg_type;
- enum vkd3d_data_type reg_data_type;
+ enum vsir_data_type reg_data_type;
};
struct sm6_parser
@@ -2010,11 +2025,6 @@ static inline bool sm6_type_is_handle(const struct sm6_type *type)
return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.Handle");
}
-static inline const struct sm6_type *sm6_type_get_element_type(const struct sm6_type *type)
-{
- return (type->class == TYPE_CLASS_ARRAY || type->class == TYPE_CLASS_VECTOR) ? type->u.array.elem_type : type;
-}
-
static const struct sm6_type *sm6_type_get_pointer_to_type(const struct sm6_type *type,
enum bitcode_address_space addr_space, struct sm6_parser *sm6)
{
@@ -2214,38 +2224,14 @@ static const char *sm6_parser_get_global_symbol_name(const struct sm6_parser *sm
return NULL;
}
-static unsigned int register_get_uint_value(const struct vkd3d_shader_register *reg)
-{
- if (!register_is_constant(reg) || (!data_type_is_integer(reg->data_type) && !data_type_is_bool(reg->data_type)))
- return UINT_MAX;
-
- if (reg->dimension == VSIR_DIMENSION_VEC4)
- WARN("Returning vec4.x.\n");
-
- if (reg->type == VKD3DSPR_IMMCONST64)
- {
- if (reg->u.immconst_u64[0] > UINT_MAX)
- FIXME("Truncating 64-bit value.\n");
- return reg->u.immconst_u64[0];
- }
-
- return reg->u.immconst_u32[0];
-}
-
-static uint64_t register_get_uint64_value(const struct vkd3d_shader_register *reg)
+static inline bool sm6_value_is_function_dcl(const struct sm6_value *value)
{
- if (!register_is_constant(reg) || !data_type_is_integer(reg->data_type))
- return UINT64_MAX;
-
- if (reg->dimension == VSIR_DIMENSION_VEC4)
- WARN("Returning vec4.x.\n");
-
- return (reg->type == VKD3DSPR_IMMCONST64) ? reg->u.immconst_u64[0] : reg->u.immconst_u32[0];
+ return value->value_type == VALUE_TYPE_FUNCTION;
}
-static inline bool sm6_value_is_function_dcl(const struct sm6_value *value)
+static bool sm6_value_is_invalid(const struct sm6_value *value)
{
- return value->value_type == VALUE_TYPE_FUNCTION;
+ return value->value_type == VALUE_TYPE_INVALID;
}
static inline bool sm6_value_is_dx_intrinsic_dcl(const struct sm6_value *fn)
@@ -2264,11 +2250,11 @@ static inline bool sm6_value_is_register(const struct sm6_value *value)
{
switch (value->value_type)
{
- case VALUE_TYPE_REG:
case VALUE_TYPE_SSA:
case VALUE_TYPE_ICB:
case VALUE_TYPE_IDXTEMP:
case VALUE_TYPE_GROUPSHAREDMEM:
+ case VALUE_TYPE_CONSTANT:
case VALUE_TYPE_UNDEFINED:
case VALUE_TYPE_INVALID:
return true;
@@ -2285,18 +2271,41 @@ static bool sm6_value_is_handle(const struct sm6_value *value)
static inline bool sm6_value_is_constant(const struct sm6_value *value)
{
- return sm6_value_is_register(value) && register_is_constant(&value->reg);
+ return value->value_type == VALUE_TYPE_CONSTANT;
}
static bool sm6_value_is_constant_zero(const struct sm6_value *value)
{
- /* Constant vectors do not occur. */
- return sm6_value_is_register(value) && register_is_scalar_constant_zero(&value->reg);
+ if (value->value_type != VALUE_TYPE_CONSTANT)
+ return false;
+
+ switch (value->type->class)
+ {
+ case TYPE_CLASS_INTEGER:
+ case TYPE_CLASS_FLOAT:
+ break;
+
+ default:
+ return false;
+ }
+
+ if (value->type->u.width == 64)
+ return value->u.constant.immconst.immconst_u64[0] == 0;
+ else
+ return value->u.constant.immconst.immconst_u32[0] == 0;
}
static inline bool sm6_value_is_undef(const struct sm6_value *value)
{
- return sm6_value_is_register(value) && value->reg.type == VKD3DSPR_UNDEF;
+ switch (value->value_type)
+ {
+ case VALUE_TYPE_UNDEFINED:
+ case VALUE_TYPE_INVALID:
+ return true;
+
+ default:
+ return false;
+ }
}
static bool sm6_value_vector_is_constant_or_undef(const struct sm6_value **values, unsigned int count)
@@ -2315,26 +2324,98 @@ static bool sm6_value_is_data(const struct sm6_value *value)
static bool sm6_value_is_ssa(const struct sm6_value *value)
{
- return sm6_value_is_register(value) && register_is_ssa(&value->reg);
+ return value->value_type == VALUE_TYPE_SSA;
}
static bool sm6_value_is_numeric_array(const struct sm6_value *value)
{
- return sm6_value_is_register(value) && register_is_numeric_array(&value->reg);
+ switch (value->value_type)
+ {
+ case VALUE_TYPE_ICB:
+ case VALUE_TYPE_IDXTEMP:
+ case VALUE_TYPE_GROUPSHAREDMEM:
+ return true;
+
+ default:
+ return false;
+ }
}
-static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *value)
+static unsigned int sm6_value_get_constant_uint(const struct sm6_value *value, struct sm6_parser *sm6)
{
if (!sm6_value_is_constant(value))
+ {
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT,
+ "Invalid non-constant value.");
return UINT_MAX;
- return register_get_uint_value(&value->reg);
+ }
+
+ if (value->type->class != TYPE_CLASS_INTEGER)
+ {
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT,
+ "Invalid non-integer constant value.");
+ return UINT_MAX;
+ }
+
+ if (value->type->u.width == 64)
+ {
+ uint64_t val = value->u.constant.immconst.immconst_u64[0];
+ if (val > UINT_MAX)
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT,
+ "Invalid 64-bit constant %"PRIu64" will be truncated do %u.", val, (unsigned int)val);
+ return val;
+ }
+
+ return value->u.constant.immconst.immconst_u32[0];
}
-static uint64_t sm6_value_get_constant_uint64(const struct sm6_value *value)
+static uint64_t sm6_value_get_constant_uint64(const struct sm6_value *value, struct sm6_parser *sm6)
{
if (!sm6_value_is_constant(value))
+ {
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT,
+ "Invalid non-constant value.");
return UINT64_MAX;
- return register_get_uint64_value(&value->reg);
+ }
+
+ if (value->type->class != TYPE_CLASS_INTEGER)
+ {
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT,
+ "Invalid non-integer constant value.");
+ return UINT64_MAX;
+ }
+
+ if (value->type->u.width == 64)
+ return value->u.constant.immconst.immconst_u64[0];
+ else
+ return value->u.constant.immconst.immconst_u32[0];
+}
+
+static float sm6_value_get_constant_float(const struct sm6_value *value, struct sm6_parser *sm6)
+{
+ if (!sm6_value_is_constant(value))
+ {
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT,
+ "Invalid non-constant value.");
+ return 0.0f;
+ }
+
+ if (value->type->class != TYPE_CLASS_FLOAT)
+ {
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT,
+ "Invalid non-floating-point constant value.");
+ return 0.0f;
+ }
+
+ if (value->type->u.width == 64)
+ {
+ double val = value->u.constant.immconst.immconst_f64[0];
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT,
+ "Invalid double constant %lf will be truncated do float %f.", val, (float)val);
+ return val;
+ }
+
+ return value->u.constant.immconst.immconst_f32[0];
}
static unsigned int sm6_parser_alloc_ssa_id(struct sm6_parser *sm6)
@@ -2386,31 +2467,31 @@ static struct vkd3d_shader_dst_param *instruction_dst_params_alloc(struct vkd3d_
}
static void register_init_with_id(struct vkd3d_shader_register *reg,
- enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int id)
+ enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type, unsigned int id)
{
vsir_register_init(reg, reg_type, data_type, 1);
reg->idx[0].offset = id;
}
-static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type *type)
+static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type)
{
if (type->class == TYPE_CLASS_INTEGER)
{
switch (type->u.width)
{
case 1:
- return VKD3D_DATA_BOOL;
+ return VSIR_DATA_BOOL;
case 8:
- return VKD3D_DATA_UINT8;
+ return VSIR_DATA_U8;
case 16:
- return VKD3D_DATA_UINT16;
+ return VSIR_DATA_U16;
case 32:
- return VKD3D_DATA_UINT;
+ return VSIR_DATA_U32;
case 64:
- return VKD3D_DATA_UINT64;
+ return VSIR_DATA_U64;
default:
FIXME("Unhandled width %u.\n", type->u.width);
- return VKD3D_DATA_UINT;
+ return VSIR_DATA_U32;
}
}
else if (type->class == TYPE_CLASS_FLOAT)
@@ -2418,48 +2499,138 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type
switch (type->u.width)
{
case 16:
- return VKD3D_DATA_HALF;
+ return VSIR_DATA_F16;
case 32:
- return VKD3D_DATA_FLOAT;
+ return VSIR_DATA_F32;
case 64:
- return VKD3D_DATA_DOUBLE;
+ return VSIR_DATA_F64;
default:
FIXME("Unhandled width %u.\n", type->u.width);
- return VKD3D_DATA_FLOAT;
+ return VSIR_DATA_F32;
}
}
FIXME("Unhandled type %u.\n", type->class);
- return VKD3D_DATA_UINT;
+ return VSIR_DATA_U32;
}
-static void sm6_register_from_value(struct vkd3d_shader_register *reg, const struct sm6_value *value)
+/* Based on the implementation in the OpenGL Mathematics library. */
+static uint32_t half_to_float(uint16_t value)
{
- enum vkd3d_data_type data_type;
+ uint32_t s = (value & 0x8000u) << 16;
+ uint32_t e = (value >> 10) & 0x1fu;
+ uint32_t m = value & 0x3ffu;
- data_type = vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(value->type, 0));
+ if (!e)
+ {
+ if (!m)
+ {
+ /* Plus or minus zero */
+ return s;
+ }
+ else
+ {
+ /* Denormalized number -- renormalize it */
+ while (!(m & 0x400u))
+ {
+ m <<= 1;
+ --e;
+ }
- switch (value->value_type)
+ ++e;
+ m &= ~0x400u;
+ }
+ }
+ else if (e == 31u)
{
- case VALUE_TYPE_REG:
- *reg = value->reg;
+ /* Positive or negative infinity for zero 'm'.
+ * Nan for non-zero 'm' -- preserve sign and significand bits */
+ return s | 0x7f800000u | (m << 13);
+ }
+
+ /* Normalized number */
+ e += 127u - 15u;
+ m <<= 13;
+
+ /* Assemble s, e and m. */
+ return s | (e << 23) | m;
+}
+
+static void register_convert_to_minimum_precision(struct vkd3d_shader_register *reg)
+{
+ unsigned int i;
+
+ switch (reg->data_type)
+ {
+ case VSIR_DATA_F16:
+ reg->data_type = VSIR_DATA_F32;
+ reg->precision = VKD3D_SHADER_REGISTER_PRECISION_MIN_FLOAT_16;
+ if (reg->type == VKD3DSPR_IMMCONST)
+ {
+ for (i = 0; i < VSIR_DIMENSION_VEC4; ++i)
+ reg->u.immconst_u32[i] = half_to_float(reg->u.immconst_u32[i]);
+ }
+ break;
+
+ case VSIR_DATA_U16:
+ reg->data_type = VSIR_DATA_U32;
+ reg->precision = VKD3D_SHADER_REGISTER_PRECISION_MIN_UINT_16;
+ if (reg->type == VKD3DSPR_IMMCONST)
+ {
+ for (i = 0; i < VSIR_DIMENSION_VEC4; ++i)
+ reg->u.immconst_u32[i] = (int16_t)reg->u.immconst_u32[i];
+ }
+ break;
+
+ default:
break;
+ }
+}
+
+static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address,
+ struct sm6_parser *sm6);
+static void sm6_register_from_value(struct vkd3d_shader_register *reg, const struct sm6_value *value,
+ struct sm6_parser *sm6)
+{
+ const struct sm6_type *scalar_type;
+ enum vsir_data_type data_type;
+
+ scalar_type = sm6_type_get_scalar_type(value->type, 0);
+ data_type = vsir_data_type_from_dxil(scalar_type);
+
+ switch (value->value_type)
+ {
case VALUE_TYPE_SSA:
register_init_with_id(reg, VKD3DSPR_SSA, data_type, value->u.ssa.id);
reg->dimension = sm6_type_is_scalar(value->type) ? VSIR_DIMENSION_SCALAR : VSIR_DIMENSION_VEC4;
break;
case VALUE_TYPE_ICB:
- register_init_with_id(reg, VKD3DSPR_IMMCONSTBUFFER, data_type, value->u.icb.id);
+ vsir_register_init(reg, VKD3DSPR_IMMCONSTBUFFER, data_type, 2);
+ reg->idx[0].offset = value->u.icb.id;
+ register_index_address_init(&reg->idx[1], value->u.icb.index.index, sm6);
+ reg->idx[1].is_in_bounds = value->u.icb.index.is_in_bounds;
break;
case VALUE_TYPE_IDXTEMP:
- register_init_with_id(reg, VKD3DSPR_IDXTEMP, data_type, value->u.idxtemp.id);
+ vsir_register_init(reg, VKD3DSPR_IDXTEMP, data_type, 2);
+ reg->idx[0].offset = value->u.idxtemp.id;
+ register_index_address_init(&reg->idx[1], value->u.idxtemp.index.index, sm6);
+ reg->idx[1].is_in_bounds = value->u.idxtemp.index.is_in_bounds;
break;
case VALUE_TYPE_GROUPSHAREDMEM:
- register_init_with_id(reg, VKD3DSPR_GROUPSHAREDMEM, data_type, value->u.groupsharedmem.id);
+ vsir_register_init(reg, VKD3DSPR_GROUPSHAREDMEM, data_type, 2);
+ reg->idx[0].offset = value->u.groupsharedmem.id;
+ register_index_address_init(&reg->idx[1], value->u.groupsharedmem.index.index, sm6);
+ reg->idx[1].is_in_bounds = value->u.groupsharedmem.index.is_in_bounds;
+ break;
+
+ case VALUE_TYPE_CONSTANT:
+ vsir_register_init(reg, scalar_type->u.width == 64 ? VKD3DSPR_IMMCONST64 : VKD3DSPR_IMMCONST,
+ data_type, 0);
+ reg->u = value->u.constant.immconst;
break;
case VALUE_TYPE_UNDEFINED:
@@ -2472,15 +2643,18 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str
case VALUE_TYPE_DATA:
vkd3d_unreachable();
}
+
+ register_convert_to_minimum_precision(reg);
+ reg->non_uniform = value->non_uniform;
}
static void sm6_parser_init_ssa_value(struct sm6_parser *sm6, struct sm6_value *value)
{
unsigned int id;
- if (register_is_ssa(&value->reg) && value->reg.idx[0].offset)
+ if (value->value_type == VALUE_TYPE_SSA && value->u.ssa.id)
{
- id = value->reg.idx[0].offset;
+ id = value->u.ssa.id;
TRACE("Using forward-allocated id %u.\n", id);
}
else
@@ -2490,12 +2664,11 @@ static void sm6_parser_init_ssa_value(struct sm6_parser *sm6, struct sm6_value *
value->value_type = VALUE_TYPE_SSA;
value->u.ssa.id = id;
- sm6_register_from_value(&value->reg, value);
}
static void register_make_constant_uint(struct vkd3d_shader_register *reg, unsigned int value)
{
- vsir_register_init(reg, VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0);
+ vsir_register_init(reg, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0);
reg->u.immconst_u32[0] = value;
}
@@ -2547,10 +2720,11 @@ static void src_param_init_vector(struct vkd3d_shader_src_param *param, unsigned
param->modifiers = VKD3DSPSM_NONE;
}
-static void src_param_init_from_value(struct vkd3d_shader_src_param *param, const struct sm6_value *src)
+static void src_param_init_from_value(struct vkd3d_shader_src_param *param, const struct sm6_value *src,
+ struct sm6_parser *sm6)
{
src_param_init(param);
- sm6_register_from_value(&param->reg, src);
+ sm6_register_from_value(&param->reg, src, sm6);
}
static void src_param_init_vector_from_reg(struct vkd3d_shader_src_param *param,
@@ -2570,12 +2744,12 @@ static void src_param_make_constant_uint(struct vkd3d_shader_src_param *param, u
static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address,
struct sm6_parser *sm6)
{
- if (sm6_value_is_constant(address))
+ if (address && sm6_value_is_constant(address))
{
- idx->offset = sm6_value_get_constant_uint(address);
+ idx->offset = sm6_value_get_constant_uint(address, sm6);
idx->rel_addr = NULL;
}
- else if (sm6_value_is_undef(address))
+ else if (!address || sm6_value_is_undef(address))
{
idx->offset = 0;
idx->rel_addr = NULL;
@@ -2584,7 +2758,7 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx,
{
struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(sm6->p.program, 1);
if (rel_addr)
- src_param_init_from_value(rel_addr, address);
+ src_param_init_from_value(rel_addr, address, sm6);
idx->offset = 0;
idx->rel_addr = rel_addr;
}
@@ -2619,7 +2793,7 @@ static bool instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instructio
dst_param_init(param);
sm6_parser_init_ssa_value(sm6, dst);
- sm6_register_from_value(&param->reg, dst);
+ sm6_register_from_value(&param->reg, dst, sm6);
return true;
}
@@ -2631,22 +2805,20 @@ static void instruction_dst_param_init_ssa_vector(struct vkd3d_shader_instructio
dst_param_init_vector(param, component_count);
sm6_parser_init_ssa_value(sm6, dst);
- sm6_register_from_value(&param->reg, dst);
+ sm6_register_from_value(&param->reg, dst, sm6);
}
-static bool instruction_dst_param_init_temp_vector(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6)
+static bool instruction_dst_param_init_uint_temp_vector(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6)
{
- struct sm6_value *dst = sm6_parser_get_current_value(sm6);
struct vkd3d_shader_dst_param *param;
if (!(param = instruction_dst_params_alloc(ins, 1, sm6)))
return false;
- vsir_dst_param_init(param, VKD3DSPR_TEMP, vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(dst->type, 0)), 1);
+ vsir_dst_param_init(param, VKD3DSPR_TEMP, VSIR_DATA_U32, 1);
param->write_mask = VKD3DSP_WRITEMASK_ALL;
param->reg.idx[0].offset = 0;
param->reg.dimension = VSIR_DIMENSION_VEC4;
- dst->reg = param->reg;
return true;
}
@@ -2928,7 +3100,6 @@ static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const stru
value->type = fwd_type;
value->value_type = VALUE_TYPE_SSA;
value->u.ssa.id = sm6_parser_alloc_ssa_id(sm6);
- sm6_register_from_value(&value->reg, value);
}
}
@@ -3017,53 +3188,13 @@ static inline uint64_t decode_rotated_signed_value(uint64_t value)
return value << 63;
}
-static float bitcast_uint_to_float(unsigned int value)
-{
- union
- {
- uint32_t uint32_value;
- float float_value;
- } u;
-
- u.uint32_value = value;
- return u.float_value;
-}
-
-static inline double bitcast_uint64_to_double(uint64_t value)
-{
- union
- {
- uint64_t uint64_value;
- double double_value;
- } u;
-
- u.uint64_value = value;
- return u.double_value;
-}
-
-static float register_get_float_value(const struct vkd3d_shader_register *reg)
-{
- if (!register_is_constant(reg) || !data_type_is_floating_point(reg->data_type))
- return 0.0;
-
- if (reg->dimension == VSIR_DIMENSION_VEC4)
- WARN("Returning vec4.x.\n");
-
- if (reg->type == VKD3DSPR_IMMCONST64)
- {
- WARN("Truncating double to float.\n");
- return bitcast_uint64_to_double(reg->u.immconst_u64[0]);
- }
-
- return bitcast_uint_to_float(reg->u.immconst_u32[0]);
-}
-
static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, const struct sm6_type *type,
const uint64_t *operands, struct sm6_parser *sm6)
{
struct vkd3d_shader_immediate_constant_buffer *icb;
const struct sm6_type *elem_type;
unsigned int i, size, count;
+ uint64_t *data64;
elem_type = type->u.array.elem_type;
/* Multidimensional arrays are emitted in flattened form. */
@@ -3106,7 +3237,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co
dst->u.data = icb;
icb->register_idx = sm6->icb_count++;
- icb->data_type = vkd3d_data_type_from_sm6_type(elem_type);
+ icb->data_type = vsir_data_type_from_dxil(elem_type);
icb->element_count = type->u.array.count;
icb->component_count = 1;
icb->is_null = !operands;
@@ -3115,28 +3246,70 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co
return VKD3D_OK;
count = type->u.array.count;
- if (size > sizeof(icb->data[0]))
+ switch (icb->data_type)
{
- uint64_t *data = (uint64_t *)icb->data;
- for (i = 0; i < count; ++i)
- data[i] = operands[i];
- }
- else
- {
- for (i = 0; i < count; ++i)
- icb->data[i] = operands[i];
+ case VSIR_DATA_F16:
+ for (i = 0; i < count; ++i)
+ icb->data[i] = half_to_float(operands[i]);
+ icb->data_type = VSIR_DATA_F32;
+ break;
+
+ case VSIR_DATA_U16:
+ for (i = 0; i < count; ++i)
+ icb->data[i] = (int16_t)operands[i];
+ icb->data_type = VSIR_DATA_U32;
+ break;
+
+ case VSIR_DATA_F32:
+ case VSIR_DATA_U32:
+ for (i = 0; i < count; ++i)
+ icb->data[i] = operands[i];
+ break;
+
+ case VSIR_DATA_F64:
+ case VSIR_DATA_U64:
+ data64 = (uint64_t *)icb->data;
+ for (i = 0; i < count; ++i)
+ data64[i] = operands[i];
+ break;
+
+ default:
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+ "Invalid array of type %u.", icb->data_type);
+ return VKD3D_ERROR_INVALID_SHADER;
}
return VKD3D_OK;
}
+static struct sm6_index *sm6_get_value_index(struct sm6_parser *sm6, struct sm6_value *value)
+{
+ switch (value->value_type)
+ {
+ case VALUE_TYPE_ICB:
+ return &value->u.icb.index;
+
+ case VALUE_TYPE_IDXTEMP:
+ return &value->u.idxtemp.index;
+
+ case VALUE_TYPE_GROUPSHAREDMEM:
+ return &value->u.groupsharedmem.index;
+
+ default:
+ WARN("Cannot index into value of type %#x.\n", value->value_type);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+ "Cannot index into value of type %#x.", value->value_type);
+ return NULL;
+ }
+}
+
static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, const struct dxil_record *record,
struct sm6_value *dst)
{
const struct sm6_type *elem_type, *pointee_type, *gep_type, *ptr_type;
- struct vkd3d_shader_register reg;
struct sm6_value *operands[3];
unsigned int i, j, offset;
+ struct sm6_index *index;
uint64_t value;
i = 0;
@@ -3178,9 +3351,13 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c
}
}
- sm6_register_from_value(&reg, operands[0]);
+ *dst = *operands[0];
+ index = sm6_get_value_index(sm6, dst);
- if (reg.idx_count > 1)
+ if (!index)
+ return VKD3D_ERROR_INVALID_SHADER;
+
+ if (index->index)
{
WARN("Unsupported stacked GEP.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
@@ -3203,8 +3380,6 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c
return VKD3D_ERROR_INVALID_SHADER;
}
- dst->structure_stride = operands[0]->structure_stride;
-
ptr_type = operands[0]->type;
if (!sm6_type_is_pointer(ptr_type))
{
@@ -3225,7 +3400,7 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c
"Explicit pointee type for constexpr GEP does not match the element type.");
}
- offset = sm6_value_get_constant_uint(operands[2]);
+ offset = sm6_value_get_constant_uint(operands[2], sm6);
if (!(gep_type = sm6_type_get_element_type_at_index(pointee_type, offset)))
{
WARN("Failed to get element type.\n");
@@ -3241,20 +3416,17 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c
"Module does not define a pointer type for a constexpr GEP result.");
return VKD3D_ERROR_INVALID_SHADER;
}
- dst->reg = reg;
- dst->reg.idx[1].offset = offset;
- dst->reg.idx[1].is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP;
- dst->reg.idx_count = 2;
+
+ index->index = operands[2];
+ index->is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP;
return VKD3D_OK;
}
static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const struct dxil_block *block)
{
- enum vkd3d_shader_register_type reg_type = VKD3DSPR_INVALID;
- const struct sm6_type *type, *elem_type, *ptr_type;
+ const struct sm6_type *type, *ptr_type;
size_t i, base_value_idx, value_idx;
- enum vkd3d_data_type reg_data_type;
const struct dxil_record *record;
const struct sm6_value *src;
enum vkd3d_result ret;
@@ -3275,18 +3447,6 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
if (!(type = sm6_parser_get_type(sm6, record->operands[0])))
return VKD3D_ERROR_INVALID_SHADER;
- elem_type = sm6_type_get_element_type(type);
- if (sm6_type_is_numeric(elem_type))
- {
- reg_data_type = vkd3d_data_type_from_sm6_type(elem_type);
- reg_type = elem_type->u.width > 32 ? VKD3DSPR_IMMCONST64 : VKD3DSPR_IMMCONST;
- }
- else
- {
- reg_data_type = VKD3D_DATA_UNUSED;
- reg_type = VKD3DSPR_INVALID;
- }
-
if (i == block->record_count - 1)
WARN("Unused SETTYPE record.\n");
@@ -3301,19 +3461,21 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
dst = sm6_parser_get_current_value(sm6);
dst->type = type;
- dst->value_type = VALUE_TYPE_REG;
dst->is_back_ref = true;
- vsir_register_init(&dst->reg, reg_type, reg_data_type, 0);
switch (record->code)
{
case CST_CODE_NULL:
- if (sm6_type_is_array(type)
- && (ret = value_allocate_constant_array(dst, type, NULL, sm6)) < 0)
+ if (sm6_type_is_array(type))
{
- return ret;
+ if ((ret = value_allocate_constant_array(dst, type, NULL, sm6)) < 0)
+ return ret;
+ }
+ else
+ {
+ dst->value_type = VALUE_TYPE_CONSTANT;
+ memset(&dst->u.constant, 0, sizeof(dst->u.constant));
}
- /* For non-aggregates, register constant data is already zero-filled. */
break;
case CST_CODE_INTEGER:
@@ -3326,11 +3488,13 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
return VKD3D_ERROR_INVALID_SHADER;
}
+ dst->value_type = VALUE_TYPE_CONSTANT;
+
value = decode_rotated_signed_value(record->operands[0]);
if (type->u.width <= 32)
- dst->reg.u.immconst_u32[0] = value & ((1ull << type->u.width) - 1);
+ dst->u.constant.immconst.immconst_u32[0] = value & ((1ull << type->u.width) - 1);
else
- dst->reg.u.immconst_u64[0] = value;
+ dst->u.constant.immconst.immconst_u64[0] = value;
break;
@@ -3344,14 +3508,13 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
return VKD3D_ERROR_INVALID_SHADER;
}
- if (type->u.width == 16)
- dst->reg.u.immconst_u32[0] = record->operands[0];
- else if (type->u.width == 32)
- dst->reg.u.immconst_f32[0] = bitcast_uint_to_float(record->operands[0]);
- else if (type->u.width == 64)
- dst->reg.u.immconst_f64[0] = bitcast_uint64_to_double(record->operands[0]);
+ dst->value_type = VALUE_TYPE_CONSTANT;
+
+ value = record->operands[0];
+ if (type->u.width <= 32)
+ dst->u.constant.immconst.immconst_u32[0] = value & ((1ull << type->u.width) - 1);
else
- vkd3d_unreachable();
+ dst->u.constant.immconst.immconst_u64[0] = value;
break;
@@ -3377,6 +3540,46 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
return ret;
break;
+ case CST_CODE_CE_CAST:
+ /* Resolve later in case forward refs exist. */
+ dst->type = type;
+ dst->value_type = VALUE_TYPE_INVALID;
+ break;
+
+ case CST_CODE_UNDEF:
+ dxil_record_validate_operand_max_count(record, 0, sm6);
+ dst->value_type = VALUE_TYPE_UNDEFINED;
+ break;
+
+ default:
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+ "Constant code %u is unhandled.", record->code);
+ dst->value_type = VALUE_TYPE_INVALID;
+ break;
+ }
+
+ if (record->attachment)
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
+ "Ignoring a metadata attachment for a constant.");
+
+ ++sm6->value_count;
+ }
+
+ value_idx = base_value_idx;
+
+ for (i = 0; i < block->record_count; ++i)
+ {
+ sm6->p.location.column = i;
+ record = block->records[i];
+
+ switch (record->code)
+ {
+ case CST_CODE_SETTYPE:
+ continue;
+
+ default:
+ break;
+
case CST_CODE_CE_CAST:
if (!dxil_record_validate_operand_count(record, 3, 3, sm6))
return VKD3D_ERROR_INVALID_SHADER;
@@ -3413,59 +3616,26 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
return VKD3D_ERROR_INVALID_SHADER;
}
- /* Resolve later in case forward refs exist. */
- dst->type = type;
- dst->reg.type = VKD3DSPR_COUNT;
- dst->reg.idx[0].offset = value;
- break;
+ dst = &sm6->values[value_idx];
+ src = &sm6->values[value];
- case CST_CODE_UNDEF:
- dxil_record_validate_operand_max_count(record, 0, sm6);
- dst->value_type = VALUE_TYPE_UNDEFINED;
- sm6_register_from_value(&dst->reg, dst);
- break;
+ if (!sm6_value_is_numeric_array(src))
+ {
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+ "Constexpr cast source value is not a global array element.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
- default:
- FIXME("Unhandled constant code %u.\n", record->code);
- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
- "Constant code %u is unhandled.", record->code);
- dst->value_type = VALUE_TYPE_INVALID;
- sm6_register_from_value(&dst->reg, dst);
+ type = dst->type;
+ *dst = *src;
+ dst->type = type;
break;
}
- if (record->attachment)
- {
- WARN("Ignoring metadata attachment.\n");
- vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT,
- "Ignoring a metadata attachment for a constant.");
- }
-
- ++sm6->value_count;
+ ++value_idx;
}
- /* Resolve cast forward refs. */
- for (i = base_value_idx; i < sm6->value_count; ++i)
- {
- dst = &sm6->values[i];
- if (dst->reg.type != VKD3DSPR_COUNT)
- continue;
-
- type = dst->type;
-
- src = &sm6->values[dst->reg.idx[0].offset];
- if (!sm6_value_is_numeric_array(src))
- {
- WARN("Value is not an array.\n");
- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
- "Constexpr cast source value is not a global array element.");
- return VKD3D_ERROR_INVALID_SHADER;
- }
-
- *dst = *src;
- dst->type = type;
- dst->reg.data_type = vkd3d_data_type_from_sm6_type(type->u.pointer.type);
- }
+ VKD3D_ASSERT(value_idx == sm6->value_count);
return VKD3D_OK;
}
@@ -3509,7 +3679,7 @@ static void sm6_parser_declare_icb(struct sm6_parser *sm6, const struct sm6_type
{
struct vkd3d_shader_instruction *ins;
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER);
+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER);
/* The icb value index will be resolved later so forward references can be handled. */
ins->declaration.icb = (void *)(intptr_t)init;
dst->value_type = VALUE_TYPE_ICB;
@@ -3520,12 +3690,12 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru
unsigned int count, unsigned int alignment, bool has_function_scope, unsigned int init,
struct vkd3d_shader_instruction *ins, struct sm6_value *dst)
{
- enum vkd3d_data_type data_type = vkd3d_data_type_from_sm6_type(elem_type);
+ enum vsir_data_type data_type = vsir_data_type_from_dxil(elem_type);
if (ins)
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_INDEXABLE_TEMP);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DCL_INDEXABLE_TEMP);
else
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_INDEXABLE_TEMP);
+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_INDEXABLE_TEMP);
ins->declaration.indexable_temp.register_idx = sm6->indexable_temp_count++;
ins->declaration.indexable_temp.register_size = count;
ins->declaration.indexable_temp.alignment = alignment;
@@ -3537,7 +3707,6 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru
dst->value_type = VALUE_TYPE_IDXTEMP;
dst->u.idxtemp.id = ins->declaration.indexable_temp.register_idx;
- sm6_register_from_value(&dst->reg, dst);
}
static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6_type *elem_type,
@@ -3546,15 +3715,17 @@ static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6
struct vkd3d_shader_instruction *ins;
unsigned int byte_count;
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TGSM_RAW);
+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TGSM_RAW);
dst_param_init(&ins->declaration.tgsm_raw.reg);
dst->value_type = VALUE_TYPE_GROUPSHAREDMEM;
dst->u.groupsharedmem.id = sm6->tgsm_count++;
dst->structure_stride = 0;
- sm6_register_from_value(&dst->reg, dst);
- sm6_register_from_value(&ins->declaration.tgsm_raw.reg.reg, dst);
+ sm6_register_from_value(&ins->declaration.tgsm_raw.reg.reg, dst, sm6);
ins->declaration.tgsm_raw.alignment = alignment;
- byte_count = elem_type->u.width / 8u;
+ byte_count = elem_type->u.width / CHAR_BIT;
+ /* Convert minimum precision types to their 32-bit equivalent. */
+ if (byte_count == 2)
+ byte_count = 4;
if (byte_count != 4)
{
FIXME("Unsupported byte count %u.\n", byte_count);
@@ -3571,13 +3742,15 @@ static void sm6_parser_declare_tgsm_structured(struct sm6_parser *sm6, const str
{
struct vkd3d_shader_instruction *ins;
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TGSM_STRUCTURED);
+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TGSM_STRUCTURED);
dst_param_init(&ins->declaration.tgsm_structured.reg);
dst->value_type = VALUE_TYPE_GROUPSHAREDMEM;
dst->u.groupsharedmem.id = sm6->tgsm_count++;
- dst->structure_stride = elem_type->u.width / 8u;
- sm6_register_from_value(&dst->reg, dst);
- sm6_register_from_value(&ins->declaration.tgsm_structured.reg.reg, dst);
+ dst->structure_stride = elem_type->u.width / CHAR_BIT;
+ /* Convert minimum precision types to their 32-bit equivalent. */
+ if (dst->structure_stride == 2)
+ dst->structure_stride = 4;
+ sm6_register_from_value(&ins->declaration.tgsm_structured.reg.reg, dst, sm6);
if (dst->structure_stride != 4)
{
FIXME("Unsupported structure stride %u.\n", dst->structure_stride);
@@ -3697,7 +3870,6 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_
dst = sm6_parser_get_current_value(sm6);
dst->type = type;
- dst->value_type = VALUE_TYPE_REG;
dst->is_back_ref = true;
if (is_constant && !init)
@@ -3797,6 +3969,7 @@ static bool resolve_forward_zero_initialiser(size_t index, struct sm6_parser *sm
static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
{
+ struct vsir_program_iterator it = vsir_program_iterator(&sm6->p.program->instructions);
size_t i, count, base_value_idx = sm6->value_count;
const struct dxil_block *block = &sm6->root_block;
struct vkd3d_shader_instruction *ins;
@@ -3856,24 +4029,23 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
}
/* Resolve initialiser forward references. */
- for (i = 0; i < sm6->p.program->instructions.count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- ins = &sm6->p.program->instructions.elements[i];
- if (ins->opcode == VKD3DSIH_DCL_INDEXABLE_TEMP && ins->declaration.indexable_temp.initialiser)
+ if (ins->opcode == VSIR_OP_DCL_INDEXABLE_TEMP && ins->declaration.indexable_temp.initialiser)
{
ins->declaration.indexable_temp.initialiser = resolve_forward_initialiser(
(uintptr_t)ins->declaration.indexable_temp.initialiser, sm6);
}
- else if (ins->opcode == VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER)
+ else if (ins->opcode == VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER)
{
ins->declaration.icb = resolve_forward_initialiser((uintptr_t)ins->declaration.icb, sm6);
}
- else if (ins->opcode == VKD3DSIH_DCL_TGSM_RAW)
+ else if (ins->opcode == VSIR_OP_DCL_TGSM_RAW)
{
ins->declaration.tgsm_raw.zero_init = resolve_forward_zero_initialiser(ins->flags, sm6);
ins->flags = 0;
}
- else if (ins->opcode == VKD3DSIH_DCL_TGSM_STRUCTURED)
+ else if (ins->opcode == VSIR_OP_DCL_TGSM_STRUCTURED)
{
ins->declaration.tgsm_structured.zero_init = resolve_forward_zero_initialiser(ins->flags, sm6);
ins->flags = 0;
@@ -3891,14 +4063,13 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
value->u.icb.id = icb->register_idx;
else
value->u.icb.id = 0;
- sm6_register_from_value(&value->reg, value);
}
return VKD3D_OK;
}
-static void dst_param_io_init(struct vkd3d_shader_dst_param *param,
- const struct signature_element *e, enum vkd3d_shader_register_type reg_type)
+static void dst_param_io_init(struct vkd3d_shader_dst_param *param, const struct signature_element *e,
+ enum vkd3d_shader_register_type reg_type, enum vsir_dimension dimension)
{
enum vkd3d_shader_component_type component_type;
@@ -3907,36 +4078,44 @@ static void dst_param_io_init(struct vkd3d_shader_dst_param *param,
param->shift = 0;
/* DXIL types do not have signedness. Load signed elements as unsigned. */
component_type = e->component_type == VKD3D_SHADER_COMPONENT_INT ? VKD3D_SHADER_COMPONENT_UINT : e->component_type;
- vsir_register_init(&param->reg, reg_type, vkd3d_data_type_from_component_type(component_type), 0);
- param->reg.dimension = VSIR_DIMENSION_VEC4;
+ vsir_register_init(&param->reg, reg_type, vsir_data_type_from_component_type(component_type), 0);
+ param->reg.dimension = dimension;
}
static void src_params_init_from_operands(struct vkd3d_shader_src_param *src_params,
- const struct sm6_value **operands, unsigned int count)
+ const struct sm6_value **operands, unsigned int count, struct sm6_parser *sm6)
{
unsigned int i;
for (i = 0; i < count; ++i)
- src_param_init_from_value(&src_params[i], operands[i]);
+ src_param_init_from_value(&src_params[i], operands[i], sm6);
}
static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind(
- enum vkd3d_shader_sysval_semantic sysval_semantic, bool is_input)
+ enum vkd3d_shader_sysval_semantic sysval_semantic, bool is_input, enum vsir_dimension *dimension)
{
+ *dimension = VSIR_DIMENSION_VEC4;
+
switch (sysval_semantic)
{
+ case VKD3D_SHADER_SV_PRIMITIVE_ID:
+ return VKD3DSPR_PRIMID;
/* VSIR does not use an I/O register for SV_SampleIndex, but its
* signature element has a register index of UINT_MAX and it is
* convenient to return a valid register type here to handle it. */
case VKD3D_SHADER_SV_SAMPLE_INDEX:
return VKD3DSPR_NULL;
case VKD3D_SHADER_SV_COVERAGE:
+ *dimension = is_input ? VSIR_DIMENSION_VEC4 : VSIR_DIMENSION_SCALAR;
return is_input ? VKD3DSPR_COVERAGE : VKD3DSPR_SAMPLEMASK;
case VKD3D_SHADER_SV_DEPTH:
+ *dimension = VSIR_DIMENSION_SCALAR;
return VKD3DSPR_DEPTHOUT;
case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL:
+ *dimension = VSIR_DIMENSION_SCALAR;
return VKD3DSPR_DEPTHOUTGE;
case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL:
+ *dimension = VSIR_DIMENSION_SCALAR;
return VKD3DSPR_DEPTHOUTLE;
default:
return VKD3DSPR_INVALID;
@@ -3976,18 +4155,21 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade
for (i = 0; i < s->element_count; ++i)
{
+ enum vsir_dimension dimension;
+
e = &s->elements[i];
param = &params[i];
if (e->register_index == UINT_MAX
- && (io_reg_type = register_type_from_dxil_semantic_kind(e->sysval_semantic, is_input)) != VKD3DSPR_NULL)
+ && (io_reg_type = register_type_from_dxil_semantic_kind(
+ e->sysval_semantic, is_input, &dimension)) != VKD3DSPR_NULL)
{
- dst_param_io_init(param, e, io_reg_type);
+ dst_param_io_init(param, e, io_reg_type, dimension);
continue;
}
- dst_param_io_init(param, e, reg_type);
+ dst_param_io_init(param, e, reg_type, VSIR_DIMENSION_VEC4);
count = 0;
if (is_control_point)
@@ -4163,7 +4345,7 @@ static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_rec
if (!(size = sm6_parser_get_value_safe(sm6, record->operands[2])))
return;
/* A size of 1 means one instance of type[0], i.e. one array. */
- if (sm6_value_get_constant_uint(size) != 1)
+ if (sm6_value_get_constant_uint(size, sm6) != 1)
{
FIXME("Allocation size is not 1.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
@@ -4186,26 +4368,26 @@ static enum vkd3d_shader_opcode map_dx_atomicrmw_op(uint64_t code)
switch (code)
{
case RMW_ADD:
- return VKD3DSIH_IMM_ATOMIC_IADD;
+ return VSIR_OP_IMM_ATOMIC_IADD;
case RMW_AND:
- return VKD3DSIH_IMM_ATOMIC_AND;
+ return VSIR_OP_IMM_ATOMIC_AND;
case RMW_MAX:
- return VKD3DSIH_IMM_ATOMIC_IMAX;
+ return VSIR_OP_IMM_ATOMIC_IMAX;
case RMW_MIN:
- return VKD3DSIH_IMM_ATOMIC_IMIN;
+ return VSIR_OP_IMM_ATOMIC_IMIN;
case RMW_OR:
- return VKD3DSIH_IMM_ATOMIC_OR;
+ return VSIR_OP_IMM_ATOMIC_OR;
case RMW_UMAX:
- return VKD3DSIH_IMM_ATOMIC_UMAX;
+ return VSIR_OP_IMM_ATOMIC_UMAX;
case RMW_UMIN:
- return VKD3DSIH_IMM_ATOMIC_UMIN;
+ return VSIR_OP_IMM_ATOMIC_UMIN;
case RMW_XCHG:
- return VKD3DSIH_IMM_ATOMIC_EXCH;
+ return VSIR_OP_IMM_ATOMIC_EXCH;
case RMW_XOR:
- return VKD3DSIH_IMM_ATOMIC_XOR;
+ return VSIR_OP_IMM_ATOMIC_XOR;
default:
/* DXIL currently doesn't use SUB and NAND. */
- return VKD3DSIH_INVALID;
+ return VSIR_OP_INVALID;
}
}
@@ -4228,7 +4410,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_
|| !sm6_value_validate_is_backward_ref(ptr, sm6))
return;
- sm6_register_from_value(&reg, ptr);
+ sm6_register_from_value(&reg, ptr, sm6);
if (reg.type != VKD3DSPR_GROUPSHAREDMEM)
{
@@ -4246,7 +4428,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_
if (!dxil_record_validate_operand_count(record, i + 4, i + 4, sm6))
return;
- if ((op = map_dx_atomicrmw_op(code = record->operands[i++])) == VKD3DSIH_INVALID)
+ if ((op = map_dx_atomicrmw_op(code = record->operands[i++])) == VSIR_OP_INVALID)
{
FIXME("Unhandled atomicrmw op %"PRIu64".\n", code);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
@@ -4284,16 +4466,16 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_
src_param_init_vector_from_reg(&src_params[0], &coord);
else
src_param_make_constant_uint(&src_params[0], 0);
- src_param_init_from_value(&src_params[1], src);
+ src_param_init_from_value(&src_params[1], src, sm6);
sm6_parser_init_ssa_value(sm6, dst);
dst_params = instruction_dst_params_alloc(ins, 2, sm6);
- sm6_register_from_value(&dst_params[0].reg, dst);
+ sm6_register_from_value(&dst_params[0].reg, dst, sm6);
dst_param_init(&dst_params[0]);
dst_params[1].reg = reg;
- dst_params[1].reg.data_type = VKD3D_DATA_UNUSED;
+ dst_params[1].reg.data_type = VSIR_DATA_UNUSED;
dst_params[1].reg.idx[1].rel_addr = NULL;
dst_params[1].reg.idx[1].offset = ~0u;
dst_params[1].reg.idx_count = 1;
@@ -4314,7 +4496,7 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty
WARN("Argument type %u is not bool, int16/32/64 or floating point.\n", type_a->class);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
"An argument to a binary operation is not bool, int16/32/64 or floating point.");
- return VKD3DSIH_INVALID;
+ return VSIR_OP_INVALID;
}
if (type_a != type_b)
{
@@ -4329,55 +4511,58 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty
case BINOP_ADD:
case BINOP_SUB:
/* NEG is applied later for subtraction. */
- op = is_int ? VKD3DSIH_IADD : (is_double ? VKD3DSIH_DADD : VKD3DSIH_ADD);
+ op = is_int ? VSIR_OP_IADD : (is_double ? VSIR_OP_DADD : VSIR_OP_ADD);
is_valid = !is_bool;
break;
case BINOP_AND:
- op = VKD3DSIH_AND;
+ op = VSIR_OP_AND;
is_valid = is_int;
break;
case BINOP_ASHR:
- op = VKD3DSIH_ISHR;
+ op = VSIR_OP_ISHR;
is_valid = is_int && !is_bool;
break;
case BINOP_LSHR:
- op = VKD3DSIH_USHR;
+ op = VSIR_OP_USHR;
is_valid = is_int && !is_bool;
break;
case BINOP_MUL:
- op = is_int ? VKD3DSIH_UMUL : (is_double ? VKD3DSIH_DMUL : VKD3DSIH_MUL);
+ op = is_int ? VSIR_OP_IMUL_LOW : (is_double ? VSIR_OP_DMUL : VSIR_OP_MUL);
is_valid = !is_bool;
break;
case BINOP_OR:
- op = VKD3DSIH_OR;
+ op = VSIR_OP_OR;
is_valid = is_int;
break;
case BINOP_SDIV:
- op = is_int ? VKD3DSIH_IDIV : (is_double ? VKD3DSIH_DDIV : VKD3DSIH_DIV);
+ op = is_int ? VSIR_OP_IDIV : (is_double ? VSIR_OP_DDIV : VSIR_OP_DIV);
is_valid = !is_bool;
break;
case BINOP_SREM:
- op = is_int ? VKD3DSIH_IDIV : VKD3DSIH_FREM;
+ op = is_int ? VSIR_OP_IREM : VSIR_OP_FREM;
is_valid = !is_bool;
break;
case BINOP_SHL:
- op = VKD3DSIH_ISHL;
+ op = VSIR_OP_ISHL;
is_valid = is_int && !is_bool;
break;
case BINOP_UDIV:
+ op = VSIR_OP_UDIV_SIMPLE;
+ is_valid = is_int && !is_bool;
+ break;
case BINOP_UREM:
- op = VKD3DSIH_UDIV;
+ op = VSIR_OP_UREM;
is_valid = is_int && !is_bool;
break;
case BINOP_XOR:
- op = VKD3DSIH_XOR;
+ op = VSIR_OP_XOR;
is_valid = is_int;
break;
default:
FIXME("Unhandled binary op %#"PRIx64".\n", code);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
"Binary operation %#"PRIx64" is unhandled.", code);
- return VKD3DSIH_INVALID;
+ return VSIR_OP_INVALID;
}
if (!is_valid)
@@ -4411,7 +4596,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
return;
code = record->operands[i++];
- if ((handler_idx = map_binary_op(code, a->type, b->type, sm6)) == VKD3DSIH_INVALID)
+ if ((handler_idx = map_binary_op(code, a->type, b->type, sm6)) == VSIR_OP_INVALID)
return;
vsir_instruction_init(ins, &sm6->p.location, handler_idx);
@@ -4421,25 +4606,27 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
switch (handler_idx)
{
- case VKD3DSIH_ADD:
- case VKD3DSIH_MUL:
- case VKD3DSIH_DIV:
- case VKD3DSIH_FREM:
+ case VSIR_OP_ADD:
+ case VSIR_OP_MUL:
+ case VSIR_OP_DIV:
+ case VSIR_OP_FREM:
if (!(flags & FP_ALLOW_UNSAFE_ALGEBRA))
ins->flags |= VKD3DSI_PRECISE_X;
flags &= ~FP_ALLOW_UNSAFE_ALGEBRA;
/* SPIR-V FPFastMathMode is only available in the Kernel execution model. */
silence_warning = !(flags & ~(FP_NO_NAN | FP_NO_INF | FP_NO_SIGNED_ZEROS | FP_ALLOW_RECIPROCAL));
break;
- case VKD3DSIH_IADD:
- case VKD3DSIH_UMUL:
- case VKD3DSIH_ISHL:
+ case VSIR_OP_IADD:
+ case VSIR_OP_IMUL_LOW:
+ case VSIR_OP_ISHL:
silence_warning = !(flags & ~(OB_NO_UNSIGNED_WRAP | OB_NO_SIGNED_WRAP));
break;
- case VKD3DSIH_ISHR:
- case VKD3DSIH_USHR:
- case VKD3DSIH_IDIV:
- case VKD3DSIH_UDIV:
+ case VSIR_OP_ISHR:
+ case VSIR_OP_USHR:
+ case VSIR_OP_IDIV:
+ case VSIR_OP_UDIV_SIMPLE:
+ case VSIR_OP_IREM:
+ case VSIR_OP_UREM:
silence_warning = !(flags & ~PEB_EXACT);
break;
default:
@@ -4459,34 +4646,21 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
return;
- src_param_init_from_value(&src_params[0], a);
- src_param_init_from_value(&src_params[1], b);
+ src_param_init_from_value(&src_params[0], a, sm6);
+ src_param_init_from_value(&src_params[1], b, sm6);
if (code == BINOP_SUB)
src_params[1].modifiers = VKD3DSPSM_NEG;
dst->type = a->type;
- if (handler_idx == VKD3DSIH_UMUL || handler_idx == VKD3DSIH_UDIV || handler_idx == VKD3DSIH_IDIV)
+ if (handler_idx == VSIR_OP_ISHL || handler_idx == VSIR_OP_ISHR || handler_idx == VSIR_OP_USHR)
{
- struct vkd3d_shader_dst_param *dst_params = instruction_dst_params_alloc(ins, 2, sm6);
- unsigned int index = code != BINOP_UDIV && code != BINOP_SDIV;
-
- dst_param_init(&dst_params[0]);
- dst_param_init(&dst_params[1]);
- sm6_parser_init_ssa_value(sm6, dst);
- sm6_register_from_value(&dst_params[index].reg, dst);
- vsir_dst_param_init_null(&dst_params[index ^ 1]);
- }
- else
- {
- if (handler_idx == VKD3DSIH_ISHL || handler_idx == VKD3DSIH_ISHR || handler_idx == VKD3DSIH_USHR)
- {
- /* DXC emits AND instructions where necessary to mask shift counts. Shift binops
- * do not imply masking the shift as the TPF equivalents do. */
- ins->flags |= VKD3DSI_SHIFT_UNMASKED;
- }
- instruction_dst_param_init_ssa_scalar(ins, sm6);
+ /* DXC emits AND instructions where necessary to mask shift counts.
+ * Shift binops do not imply masking the shift as the TPF equivalents
+ * do. */
+ ins->flags |= VKD3DSI_SHIFT_UNMASKED;
}
+ instruction_dst_param_init_ssa_scalar(ins, sm6);
}
static const struct sm6_block *sm6_function_get_block(const struct sm6_function *function, uint64_t index,
@@ -4536,12 +4710,12 @@ static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record
dxil_record_validate_operand_max_count(record, i, sm6);
code_block->terminator.type = TERMINATOR_COND_BR;
- sm6_register_from_value(&code_block->terminator.conditional_reg, value);
+ sm6_register_from_value(&code_block->terminator.conditional_reg, value, sm6);
code_block->terminator.true_block = sm6_function_get_block(function, record->operands[0], sm6);
code_block->terminator.false_block = sm6_function_get_block(function, record->operands[1], sm6);
}
- ins->opcode = VKD3DSIH_NOP;
+ ins->opcode = VSIR_OP_NOP;
}
static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6,
@@ -4579,7 +4753,7 @@ static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6,
for (i = 0; i < component_count; ++i, ++ins)
{
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (!(src_params = instruction_src_params_alloc(ins, 1, sm6)))
return false;
@@ -4607,7 +4781,7 @@ static bool sm6_parser_emit_composite_construct(struct sm6_parser *sm6, const st
unsigned int i;
for (i = 0; i < component_count; ++i)
- sm6_register_from_value(&operand_regs[i], operands[i]);
+ sm6_register_from_value(&operand_regs[i], operands[i], sm6);
return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg);
}
@@ -4623,11 +4797,11 @@ static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const s
{
if (!z_operand && operands[component_count]->value_type == VALUE_TYPE_UNDEFINED)
break;
- sm6_register_from_value(&operand_regs[component_count], operands[component_count]);
+ sm6_register_from_value(&operand_regs[component_count], operands[component_count], sm6);
}
if (z_operand)
- sm6_register_from_value(&operand_regs[component_count++], z_operand);
+ sm6_register_from_value(&operand_regs[component_count++], z_operand, sm6);
return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg);
}
@@ -4637,7 +4811,7 @@ static enum vkd3d_shader_opcode sm6_dx_map_void_op(enum dx_intrinsic_opcode op)
switch (op)
{
case DX_WAVE_IS_FIRST_LANE:
- return VKD3DSIH_WAVE_IS_FIRST_LANE;
+ return VSIR_OP_WAVE_IS_FIRST_LANE;
default:
vkd3d_unreachable();
}
@@ -4656,77 +4830,81 @@ static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op)
switch (op)
{
case DX_ISNAN:
- return VKD3DSIH_ISNAN;
+ return VSIR_OP_ISNAN;
case DX_ISINF:
- return VKD3DSIH_ISINF;
+ return VSIR_OP_ISINF;
case DX_ISFINITE:
- return VKD3DSIH_ISFINITE;
+ return VSIR_OP_ISFINITE;
+ case DX_COS:
+ return VSIR_OP_COS;
+ case DX_SIN:
+ return VSIR_OP_SIN;
case DX_TAN:
- return VKD3DSIH_TAN;
+ return VSIR_OP_TAN;
case DX_ACOS:
- return VKD3DSIH_ACOS;
+ return VSIR_OP_ACOS;
case DX_ASIN:
- return VKD3DSIH_ASIN;
+ return VSIR_OP_ASIN;
case DX_ATAN:
- return VKD3DSIH_ATAN;
+ return VSIR_OP_ATAN;
case DX_HCOS:
- return VKD3DSIH_HCOS;
+ return VSIR_OP_HCOS;
case DX_HSIN:
- return VKD3DSIH_HSIN;
+ return VSIR_OP_HSIN;
case DX_HTAN:
- return VKD3DSIH_HTAN;
+ return VSIR_OP_HTAN;
case DX_EXP:
- return VKD3DSIH_EXP;
+ return VSIR_OP_EXP;
case DX_FRC:
- return VKD3DSIH_FRC;
+ return VSIR_OP_FRC;
case DX_LOG:
- return VKD3DSIH_LOG;
+ return VSIR_OP_LOG;
case DX_SQRT:
- return VKD3DSIH_SQRT;
+ return VSIR_OP_SQRT;
case DX_RSQRT:
- return VKD3DSIH_RSQ;
+ return VSIR_OP_RSQ;
case DX_ROUND_NE:
- return VKD3DSIH_ROUND_NE;
+ return VSIR_OP_ROUND_NE;
case DX_ROUND_NI:
- return VKD3DSIH_ROUND_NI;
+ return VSIR_OP_ROUND_NI;
case DX_ROUND_PI:
- return VKD3DSIH_ROUND_PI;
+ return VSIR_OP_ROUND_PI;
case DX_ROUND_Z:
- return VKD3DSIH_ROUND_Z;
+ return VSIR_OP_ROUND_Z;
case DX_BFREV:
- return VKD3DSIH_BFREV;
+ return VSIR_OP_BFREV;
case DX_COUNT_BITS:
- return VKD3DSIH_COUNTBITS;
+ return VSIR_OP_COUNTBITS;
case DX_FIRST_BIT_LO:
- return VKD3DSIH_FIRSTBIT_LO;
+ return VSIR_OP_FIRSTBIT_LO;
case DX_FIRST_BIT_HI:
- return VKD3DSIH_FIRSTBIT_HI;
+ return VSIR_OP_FIRSTBIT_HI;
case DX_FIRST_BIT_SHI:
- return VKD3DSIH_FIRSTBIT_SHI;
+ return VSIR_OP_FIRSTBIT_SHI;
case DX_DERIV_COARSEX:
- return VKD3DSIH_DSX_COARSE;
+ return VSIR_OP_DSX_COARSE;
case DX_DERIV_COARSEY:
- return VKD3DSIH_DSY_COARSE;
+ return VSIR_OP_DSY_COARSE;
case DX_DERIV_FINEX:
- return VKD3DSIH_DSX_FINE;
+ return VSIR_OP_DSX_FINE;
case DX_DERIV_FINEY:
- return VKD3DSIH_DSY_FINE;
+ return VSIR_OP_DSY_FINE;
case DX_LEGACY_F32TOF16:
- return VKD3DSIH_F32TOF16;
+ return VSIR_OP_F32TOF16;
case DX_LEGACY_F16TOF32:
- return VKD3DSIH_F16TOF32;
+ return VSIR_OP_F16TOF32;
case DX_WAVE_ACTIVE_ALL_EQUAL:
- return VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL;
+ return VSIR_OP_WAVE_ACTIVE_ALL_EQUAL;
case DX_WAVE_ALL_BIT_COUNT:
- return VKD3DSIH_WAVE_ALL_BIT_COUNT;
+ return VSIR_OP_WAVE_ALL_BIT_COUNT;
case DX_WAVE_ALL_TRUE:
- return VKD3DSIH_WAVE_ALL_TRUE;
+ return VSIR_OP_WAVE_ALL_TRUE;
case DX_WAVE_ANY_TRUE:
- return VKD3DSIH_WAVE_ANY_TRUE;
+ return VSIR_OP_WAVE_ANY_TRUE;
case DX_WAVE_PREFIX_BIT_COUNT:
- return VKD3DSIH_WAVE_PREFIX_BIT_COUNT;
+ return VSIR_OP_WAVE_PREFIX_BIT_COUNT;
case DX_WAVE_READ_LANE_FIRST:
- return VKD3DSIH_WAVE_READ_LANE_FIRST;
+ return VSIR_OP_WAVE_READ_LANE_FIRST;
default:
vkd3d_unreachable();
}
@@ -4741,7 +4919,7 @@ static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, enum dx_intrinsic_o
vsir_instruction_init(ins, &sm6->p.location, map_dx_unary_op(op));
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
- src_param_init_from_value(src_param, operands[0]);
+ src_param_init_from_value(src_param, operands[0], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6);
}
@@ -4751,21 +4929,21 @@ static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, co
switch (op)
{
case DX_FMAX:
- return type->u.width == 64 ? VKD3DSIH_DMAX : VKD3DSIH_MAX;
+ return type->u.width == 64 ? VSIR_OP_DMAX : VSIR_OP_MAX;
case DX_FMIN:
- return type->u.width == 64 ? VKD3DSIH_DMIN : VKD3DSIH_MIN;
+ return type->u.width == 64 ? VSIR_OP_DMIN : VSIR_OP_MIN;
case DX_IMAX:
- return VKD3DSIH_IMAX;
+ return VSIR_OP_IMAX;
case DX_IMIN:
- return VKD3DSIH_IMIN;
+ return VSIR_OP_IMIN;
case DX_QUAD_READ_LANE_AT:
- return VKD3DSIH_QUAD_READ_LANE_AT;
+ return VSIR_OP_QUAD_READ_LANE_AT;
case DX_UMAX:
- return VKD3DSIH_UMAX;
+ return VSIR_OP_UMAX;
case DX_UMIN:
- return VKD3DSIH_UMIN;
+ return VSIR_OP_UMIN;
case DX_WAVE_READ_LANE_AT:
- return VKD3DSIH_WAVE_READ_LANE_AT;
+ return VSIR_OP_WAVE_READ_LANE_AT;
default:
vkd3d_unreachable();
}
@@ -4780,42 +4958,42 @@ static void sm6_parser_emit_dx_binary(struct sm6_parser *sm6, enum dx_intrinsic_
vsir_instruction_init(ins, &sm6->p.location, map_dx_binary_op(op, operands[0]->type));
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
return;
- src_param_init_from_value(&src_params[0], operands[0]);
- src_param_init_from_value(&src_params[1], operands[1]);
+ src_param_init_from_value(&src_params[0], operands[0], sm6);
+ src_param_init_from_value(&src_params[1], operands[1], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6);
}
static enum vkd3d_shader_opcode map_dx_atomic_binop(const struct sm6_value *operand, struct sm6_parser *sm6)
{
- uint64_t code = sm6_value_get_constant_uint(operand);
+ uint64_t code = sm6_value_get_constant_uint(operand, sm6);
switch (code)
{
case ATOMIC_BINOP_ADD:
- return VKD3DSIH_IMM_ATOMIC_IADD;
+ return VSIR_OP_IMM_ATOMIC_IADD;
case ATOMIC_BINOP_AND:
- return VKD3DSIH_IMM_ATOMIC_AND;
+ return VSIR_OP_IMM_ATOMIC_AND;
case ATOMIC_BINOP_IMAX:
- return VKD3DSIH_IMM_ATOMIC_IMAX;
+ return VSIR_OP_IMM_ATOMIC_IMAX;
case ATOMIC_BINOP_IMIN:
- return VKD3DSIH_IMM_ATOMIC_IMIN;
+ return VSIR_OP_IMM_ATOMIC_IMIN;
case ATOMIC_BINOP_OR:
- return VKD3DSIH_IMM_ATOMIC_OR;
+ return VSIR_OP_IMM_ATOMIC_OR;
case ATOMIC_BINOP_UMAX:
- return VKD3DSIH_IMM_ATOMIC_UMAX;
+ return VSIR_OP_IMM_ATOMIC_UMAX;
case ATOMIC_BINOP_UMIN:
- return VKD3DSIH_IMM_ATOMIC_UMIN;
+ return VSIR_OP_IMM_ATOMIC_UMIN;
case ATOMIC_BINOP_XCHG:
- return VKD3DSIH_IMM_ATOMIC_EXCH;
+ return VSIR_OP_IMM_ATOMIC_EXCH;
case ATOMIC_BINOP_XOR:
- return VKD3DSIH_IMM_ATOMIC_XOR;
+ return VSIR_OP_IMM_ATOMIC_XOR;
/* DXIL currently doesn't use SUB and NAND. */
default:
FIXME("Unhandled atomic binop %"PRIu64".\n", code);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
"Operation %"PRIu64" for an atomic binop instruction is unhandled.", code);
- return VKD3DSIH_INVALID;
+ return VSIR_OP_INVALID;
}
}
@@ -4838,8 +5016,8 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr
return;
if (is_cmp_xchg)
- handler_idx = VKD3DSIH_IMM_ATOMIC_CMP_EXCH;
- else if ((handler_idx = map_dx_atomic_binop(operands[1], sm6)) == VKD3DSIH_INVALID)
+ handler_idx = VSIR_OP_IMM_ATOMIC_CMP_EXCH;
+ else if ((handler_idx = map_dx_atomic_binop(operands[1], sm6)) == VSIR_OP_INVALID)
return;
coord_idx = 2 - is_cmp_xchg;
@@ -4852,7 +5030,7 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr
}
else
{
- sm6_register_from_value(&reg, operands[coord_idx]);
+ sm6_register_from_value(&reg, operands[coord_idx], sm6);
}
for (i = coord_idx + coord_count; i < coord_idx + 3; ++i)
@@ -4873,14 +5051,14 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr
return;
src_param_init_vector_from_reg(&src_params[0], &reg);
if (is_cmp_xchg)
- src_param_init_from_value(&src_params[1], operands[4]);
- src_param_init_from_value(&src_params[1 + is_cmp_xchg], operands[5]);
+ src_param_init_from_value(&src_params[1], operands[4], sm6);
+ src_param_init_from_value(&src_params[1 + is_cmp_xchg], operands[5], sm6);
sm6_parser_init_ssa_value(sm6, dst);
dst_params = instruction_dst_params_alloc(ins, 2, sm6);
dst_param_init(&dst_params[0]);
- sm6_register_from_value(&dst_params[0].reg, dst);
+ sm6_register_from_value(&dst_params[0].reg, dst, sm6);
dst_param_init(&dst_params[1]);
sm6_register_from_handle(sm6, &resource->u.handle, &dst_params[1].reg);
}
@@ -4891,8 +5069,8 @@ static void sm6_parser_emit_dx_barrier(struct sm6_parser *sm6, enum dx_intrinsic
struct vkd3d_shader_instruction *ins = state->ins;
enum dxil_sync_flags flags;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SYNC);
- flags = sm6_value_get_constant_uint(operands[0]);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_SYNC);
+ flags = sm6_value_get_constant_uint(operands[0], sm6);
ins->flags = flags & (SYNC_THREAD_GROUP | SYNC_THREAD_GROUP_UAV);
if (flags & SYNC_GLOBAL_UAV)
ins->flags |= VKD3DSSF_GLOBAL_UAV;
@@ -4926,7 +5104,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu
"A dynamic update value for a UAV counter operation is not supported.");
return;
}
- i = sm6_value_get_constant_uint(operands[1]);
+ i = sm6_value_get_constant_uint(operands[1], sm6);
if (i != 1 && i != 255)
{
WARN("Unexpected update value %#x.\n", i);
@@ -4935,7 +5113,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu
}
inc = i;
- vsir_instruction_init(ins, &sm6->p.location, (inc < 0) ? VKD3DSIH_IMM_ATOMIC_CONSUME : VKD3DSIH_IMM_ATOMIC_ALLOC);
+ vsir_instruction_init(ins, &sm6->p.location, (inc < 0) ? VSIR_OP_IMM_ATOMIC_CONSUME : VSIR_OP_IMM_ATOMIC_ALLOC);
if (!(src_params = instruction_src_params_alloc(ins, 1, sm6)))
return;
src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle);
@@ -4963,10 +5141,10 @@ static void sm6_parser_emit_dx_calculate_lod(struct sm6_parser *sm6, enum dx_int
if (!sm6_parser_emit_coordinate_construct(sm6, &operands[2], 3, NULL, state, &coord))
return;
- clamp = sm6_value_get_constant_uint(operands[5]);
+ clamp = sm6_value_get_constant_uint(operands[5], sm6);
ins = state->ins;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_LOD);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_LOD);
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
return;
src_param_init_vector_from_reg(&src_params[0], &coord);
@@ -4990,7 +5168,7 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr
if (!sm6_value_validate_is_handle(buffer, sm6))
return;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
@@ -5002,15 +5180,17 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr
type = sm6_type_get_scalar_type(dst->type, 0);
VKD3D_ASSERT(type);
- src_param->reg.data_type = vkd3d_data_type_from_sm6_type(type);
+ src_param->reg.data_type = vsir_data_type_from_dxil(type);
if (data_type_is_64_bit(src_param->reg.data_type))
src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle);
+ else
+ register_convert_to_minimum_precision(&src_param->reg);
instruction_dst_param_init_ssa_vector(ins, sm6_type_max_vector_size(type), sm6);
}
static void sm6_parser_dcl_register_builtin(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx,
- enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int component_count)
+ enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type, unsigned int component_count)
{
struct vkd3d_shader_dst_param *dst_param;
struct vkd3d_shader_instruction *ins;
@@ -5025,17 +5205,19 @@ static void sm6_parser_dcl_register_builtin(struct sm6_parser *sm6, enum vkd3d_s
}
}
-static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6,
- struct vkd3d_shader_instruction *ins, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type)
+static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6, struct vkd3d_shader_instruction *ins,
+ enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type, bool scalar)
{
struct vkd3d_shader_src_param *src_param;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
- sm6_parser_dcl_register_builtin(sm6, VKD3DSIH_DCL_INPUT, reg_type, data_type, 1);
+ sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_INPUT, reg_type, data_type, 1);
vsir_register_init(&src_param->reg, reg_type, data_type, 0);
+ if (!scalar)
+ src_param->reg.dimension = VSIR_DIMENSION_VEC4;
src_param_init(src_param);
instruction_dst_param_init_ssa_scalar(ins, sm6);
@@ -5044,7 +5226,7 @@ static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6,
static void sm6_parser_emit_dx_coverage(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
const struct sm6_value **operands, struct function_emission_state *state)
{
- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_COVERAGE, VKD3D_DATA_UINT);
+ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_COVERAGE, VSIR_DATA_U32, false);
}
static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_parser *sm6,
@@ -5064,7 +5246,7 @@ static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_pa
if (!sm6_value_is_constant(address))
return d;
- register_index = sm6_value_get_constant_uint(address);
+ register_index = sm6_value_get_constant_uint(address, sm6);
if (register_index >= d->range.first && register_index <= d->range.last)
return d;
}
@@ -5081,8 +5263,8 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int
struct sm6_value *dst;
unsigned int id;
- type = sm6_value_get_constant_uint(operands[0]);
- id = sm6_value_get_constant_uint(operands[1]);
+ type = sm6_value_get_constant_uint(operands[0], sm6);
+ id = sm6_value_get_constant_uint(operands[1], sm6);
if (!(d = sm6_parser_get_descriptor(sm6, type, id, operands[2])))
{
WARN("Failed to find resource type %#x, id %#x.\n", type, id);
@@ -5095,10 +5277,10 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int
dst->value_type = VALUE_TYPE_HANDLE;
dst->u.handle.d = d;
dst->u.handle.index = operands[2];
- dst->u.handle.non_uniform = !!sm6_value_get_constant_uint(operands[3]);
+ dst->u.handle.non_uniform = !!sm6_value_get_constant_uint(operands[3], sm6);
/* NOP is used to flag no instruction emitted. */
- ins->opcode = VKD3DSIH_NOP;
+ ins->opcode = VSIR_OP_NOP;
}
static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
@@ -5108,12 +5290,12 @@ static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_
struct vkd3d_shader_src_param *src_param;
unsigned int i;
- vsir_instruction_init(ins, &sm6->p.location, (op == DX_CUT_STREAM) ? VKD3DSIH_CUT_STREAM : VKD3DSIH_EMIT_STREAM);
+ vsir_instruction_init(ins, &sm6->p.location, (op == DX_CUT_STREAM) ? VSIR_OP_CUT_STREAM : VSIR_OP_EMIT_STREAM);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
- i = sm6_value_get_constant_uint(operands[0]);
+ i = sm6_value_get_constant_uint(operands[0], sm6);
if (i >= MAX_GS_OUTPUT_STREAMS)
{
WARN("Invalid stream index %u.\n", i);
@@ -5121,8 +5303,7 @@ static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_
"Output stream index %u is invalid.", i);
}
- /* VKD3D_DATA_UNUSED would be more reasonable, but TPF uses data type 0 here. */
- register_init_with_id(&src_param->reg, VKD3DSPR_STREAM, 0, i);
+ register_init_with_id(&src_param->reg, VKD3DSPR_STREAM, VSIR_DATA_UNUSED, i);
src_param_init(src_param);
if (op == DX_EMIT_THEN_CUT_STREAM)
@@ -5139,10 +5320,10 @@ static void sm6_parser_emit_dx_discard(struct sm6_parser *sm6, enum dx_intrinsic
struct vkd3d_shader_instruction *ins = state->ins;
struct vkd3d_shader_src_param *src_param;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DISCARD);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DISCARD);
if ((src_param = instruction_src_params_alloc(ins, 1, sm6)))
- src_param_init_from_value(src_param, operands[0]);
+ src_param_init_from_value(src_param, operands[0], sm6);
}
static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
@@ -5152,9 +5333,9 @@ static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_i
struct vkd3d_shader_src_param *src_param;
unsigned int component_idx;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
- if ((component_idx = sm6_value_get_constant_uint(operands[0])) >= 3)
+ if ((component_idx = sm6_value_get_constant_uint(operands[0], sm6)) >= 3)
{
WARN("Invalid component index %u.\n", component_idx);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
@@ -5164,8 +5345,8 @@ static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_i
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
- sm6_parser_dcl_register_builtin(sm6, VKD3DSIH_DCL_INPUT, VKD3DSPR_TESSCOORD, VKD3D_DATA_FLOAT, 3);
- vsir_register_init(&src_param->reg, VKD3DSPR_TESSCOORD, VKD3D_DATA_FLOAT, 0);
+ sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_INPUT, VKD3DSPR_TESSCOORD, VSIR_DATA_F32, 3);
+ vsir_register_init(&src_param->reg, VKD3DSPR_TESSCOORD, VSIR_DATA_F32, 0);
src_param->reg.dimension = VSIR_DIMENSION_VEC4;
src_param_init_scalar(src_param, component_idx);
@@ -5184,15 +5365,15 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc
switch (op)
{
case DX_DOT2:
- handler_idx = VKD3DSIH_DP2;
+ handler_idx = VSIR_OP_DP2;
component_count = 2;
break;
case DX_DOT3:
- handler_idx = VKD3DSIH_DP3;
+ handler_idx = VSIR_OP_DP3;
component_count = 3;
break;
case DX_DOT4:
- handler_idx = VKD3DSIH_DP4;
+ handler_idx = VSIR_OP_DP4;
component_count = 4;
break;
default:
@@ -5223,8 +5404,8 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri
unsigned int row_index, column_index;
const struct signature_element *e;
- row_index = sm6_value_get_constant_uint(operands[0]);
- column_index = sm6_value_get_constant_uint(operands[2]);
+ row_index = sm6_value_get_constant_uint(operands[0], sm6);
+ column_index = sm6_value_get_constant_uint(operands[2], sm6);
signature = &sm6->p.program->input_signature;
if (row_index >= signature->element_count)
@@ -5245,7 +5426,7 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri
}
vsir_instruction_init(ins, &sm6->p.location, (op == DX_EVAL_CENTROID)
- ? VKD3DSIH_EVAL_CENTROID : VKD3DSIH_EVAL_SAMPLE_INDEX);
+ ? VSIR_OP_EVAL_CENTROID : VSIR_OP_EVAL_SAMPLE_INDEX);
if (!(src_params = instruction_src_params_alloc(ins, 1 + (op == DX_EVAL_SAMPLE_INDEX), sm6)))
return;
@@ -5256,7 +5437,7 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri
register_index_address_init(&src_params[0].reg.idx[0], operands[1], sm6);
if (op == DX_EVAL_SAMPLE_INDEX)
- src_param_init_from_value(&src_params[1], operands[3]);
+ src_param_init_from_value(&src_params[1], operands[3], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6);
}
@@ -5267,10 +5448,10 @@ static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_op
struct vkd3d_shader_instruction *ins = state->ins;
struct vkd3d_shader_src_param *src_param;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
- src_param_init_from_value(src_param, operands[0]);
+ src_param_init_from_value(src_param, operands[0], sm6);
src_param->modifiers = VKD3DSPSM_ABS;
instruction_dst_param_init_ssa_scalar(ins, sm6);
@@ -5303,16 +5484,14 @@ static void sm6_parser_emit_dx_compute_builtin(struct sm6_parser *sm6, enum dx_i
vkd3d_unreachable();
}
- sm6_parser_dcl_register_builtin(sm6, VKD3DSIH_DCL_INPUT, reg_type, VKD3D_DATA_UINT, component_count);
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+ sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_INPUT, reg_type, VSIR_DATA_U32, component_count);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
- vsir_register_init(&src_param->reg, reg_type, VKD3D_DATA_UINT, 0);
+ vsir_register_init(&src_param->reg, reg_type, VSIR_DATA_U32, 0);
+ src_param->reg.dimension = VSIR_DIMENSION_VEC4;
if (component_count > 1)
- {
- src_param->reg.dimension = VSIR_DIMENSION_VEC4;
- component_idx = sm6_value_get_constant_uint(operands[0]);
- }
+ component_idx = sm6_value_get_constant_uint(operands[0], sm6);
src_param_init_scalar(src_param, component_idx);
instruction_dst_param_init_ssa_scalar(ins, sm6);
@@ -5323,12 +5502,12 @@ static enum vkd3d_shader_opcode sm6_dx_map_ma_op(enum dx_intrinsic_opcode op, co
switch (op)
{
case DX_FMA:
- return VKD3DSIH_DFMA;
+ return VSIR_OP_DFMA;
case DX_FMAD:
- return VKD3DSIH_MAD;
+ return VSIR_OP_MAD;
case DX_IMAD:
case DX_UMAD:
- return VKD3DSIH_IMAD;
+ return VSIR_OP_IMAD;
default:
vkd3d_unreachable();
}
@@ -5345,7 +5524,7 @@ static void sm6_parser_emit_dx_ma(struct sm6_parser *sm6, enum dx_intrinsic_opco
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
return;
for (i = 0; i < 3; ++i)
- src_param_init_from_value(&src_params[i], operands[i]);
+ src_param_init_from_value(&src_params[i], operands[i], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6);
}
@@ -5366,7 +5545,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in
is_texture = resource->u.handle.d->resource_type != VKD3D_SHADER_RESOURCE_BUFFER;
resource_kind = resource->u.handle.d->kind;
- instruction_init_with_resource(ins, is_texture ? VKD3DSIH_RESINFO : VKD3DSIH_BUFINFO, resource, sm6);
+ instruction_init_with_resource(ins, is_texture ? VSIR_OP_RESINFO : VSIR_OP_BUFINFO, resource, sm6);
if (!(src_params = instruction_src_params_alloc(ins, 1 + is_texture, sm6)))
return;
@@ -5375,17 +5554,17 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in
if (is_texture)
{
ins->flags = VKD3DSI_RESINFO_UINT;
- src_param_init_from_value(&src_params[0], operands[1]);
+ src_param_init_from_value(&src_params[0], operands[1], sm6);
component_count = VKD3D_VEC4_SIZE;
if (resource_kind_is_multisampled(resource_kind))
{
- instruction_dst_param_init_temp_vector(ins++, sm6);
+ instruction_dst_param_init_uint_temp_vector(ins++, sm6);
state->temp_idx = 1;
/* DXIL does not have an intrinsic for sample info, and resinfo is expected to return
* the sample count in .w for MS textures. The result is always a struct of 4 x uint32. */
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_INFO);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_SAMPLE_INFO);
ins->flags = VKD3DSI_SAMPLE_INFO_UINT;
if (!(src_params = instruction_src_params_alloc(ins, 1, sm6)))
@@ -5393,7 +5572,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in
src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle);
src_params[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
- if (!instruction_dst_param_init_temp_vector(ins, sm6))
+ if (!instruction_dst_param_init_uint_temp_vector(ins, sm6))
return;
dst = ins->dst;
dst->write_mask = VKD3DSP_WRITEMASK_3;
@@ -5401,7 +5580,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in
/* Move the result to an SSA in case another instruction overwrites r0 before
* the components are extracted for use. */
++ins;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (!(src_params = instruction_src_params_alloc(ins, 1, sm6)))
return;
src_param_init_vector_from_reg(&src_params[0], &dst->reg);
@@ -5429,9 +5608,9 @@ static enum vkd3d_shader_opcode sm6_dx_map_tertiary_op(enum dx_intrinsic_opcode
switch (op)
{
case DX_IBFE:
- return VKD3DSIH_IBFE;
+ return VSIR_OP_IBFE;
case DX_UBFE:
- return VKD3DSIH_UBFE;
+ return VSIR_OP_UBFE;
default:
vkd3d_unreachable();
}
@@ -5448,7 +5627,7 @@ static void sm6_parser_emit_dx_tertiary(struct sm6_parser *sm6, enum dx_intrinsi
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
return;
for (i = 0; i < 3; ++i)
- src_param_init_from_value(&src_params[i], operands[i]);
+ src_param_init_from_value(&src_params[i], operands[i], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6);
}
@@ -5466,8 +5645,8 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin
const struct shader_signature *signature;
const struct signature_element *e;
- row_index = sm6_value_get_constant_uint(operands[0]);
- column_index = sm6_value_get_constant_uint(operands[2]);
+ row_index = sm6_value_get_constant_uint(operands[0], sm6);
+ column_index = sm6_value_get_constant_uint(operands[2], sm6);
if (is_control_point && operands[3]->value_type == VALUE_TYPE_UNDEFINED)
{
@@ -5477,7 +5656,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin
"The index for a control point load is undefined.");
}
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (is_patch_constant)
{
@@ -5532,7 +5711,7 @@ static void sm6_parser_emit_dx_make_double(struct sm6_parser *sm6, enum dx_intri
return;
ins = state->ins;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (!(src_params = instruction_src_params_alloc(ins, 1, sm6)))
return;
src_params[0].reg = reg;
@@ -5544,13 +5723,13 @@ static void sm6_parser_emit_dx_make_double(struct sm6_parser *sm6, enum dx_intri
static void sm6_parser_emit_dx_output_control_point_id(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
const struct sm6_value **operands, struct function_emission_state *state)
{
- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_OUTPOINTID, VKD3D_DATA_UINT);
+ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_OUTPOINTID, VSIR_DATA_U32, true);
}
static void sm6_parser_emit_dx_primitive_id(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
const struct sm6_value **operands, struct function_emission_state *state)
{
- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_PRIMID, VKD3D_DATA_UINT);
+ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_PRIMID, VSIR_DATA_U32, true);
}
static enum vkd3d_shader_opcode dx_map_quad_op(enum dxil_quad_op_kind op)
@@ -5558,13 +5737,13 @@ static enum vkd3d_shader_opcode dx_map_quad_op(enum dxil_quad_op_kind op)
switch (op)
{
case QUAD_READ_ACROSS_X:
- return VKD3DSIH_QUAD_READ_ACROSS_X;
+ return VSIR_OP_QUAD_READ_ACROSS_X;
case QUAD_READ_ACROSS_Y:
- return VKD3DSIH_QUAD_READ_ACROSS_Y;
+ return VSIR_OP_QUAD_READ_ACROSS_Y;
case QUAD_READ_ACROSS_D:
- return VKD3DSIH_QUAD_READ_ACROSS_D;
+ return VSIR_OP_QUAD_READ_ACROSS_D;
default:
- return VKD3DSIH_INVALID;
+ return VSIR_OP_INVALID;
}
}
@@ -5576,8 +5755,8 @@ static void sm6_parser_emit_dx_quad_op(struct sm6_parser *sm6, enum dx_intrinsic
enum vkd3d_shader_opcode opcode;
enum dxil_quad_op_kind quad_op;
- quad_op = sm6_value_get_constant_uint(operands[1]);
- if ((opcode = dx_map_quad_op(quad_op)) == VKD3DSIH_INVALID)
+ quad_op = sm6_value_get_constant_uint(operands[1], sm6);
+ if ((opcode = dx_map_quad_op(quad_op)) == VSIR_OP_INVALID)
{
FIXME("Unhandled quad op kind %u.\n", quad_op);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC,
@@ -5589,7 +5768,7 @@ static void sm6_parser_emit_dx_quad_op(struct sm6_parser *sm6, enum dx_intrinsic
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
- src_param_init_from_value(src_param, operands[0]);
+ src_param_init_from_value(src_param, operands[0], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6);
}
@@ -5610,7 +5789,7 @@ static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_i
if (op == DX_RAW_BUFFER_LOAD)
{
- write_mask = sm6_value_get_constant_uint(operands[3]);
+ write_mask = sm6_value_get_constant_uint(operands[3], sm6);
if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL)
{
WARN("Invalid write mask %#x.\n", write_mask);
@@ -5627,11 +5806,11 @@ static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_i
component_count = vsir_write_mask_component_count(write_mask);
}
- instruction_init_with_resource(ins, raw ? VKD3DSIH_LD_RAW : VKD3DSIH_LD_STRUCTURED, resource, sm6);
+ instruction_init_with_resource(ins, raw ? VSIR_OP_LD_RAW : VSIR_OP_LD_STRUCTURED, resource, sm6);
operand_count = 2 + !raw;
if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6)))
return;
- src_params_init_from_operands(src_params, &operands[1], operand_count - 1);
+ src_params_init_from_operands(src_params, &operands[1], operand_count - 1, sm6);
src_param_init_vector_from_handle(sm6, &src_params[operand_count - 1], &resource->u.handle);
instruction_dst_param_init_ssa_vector(ins, component_count, sm6);
@@ -5653,7 +5832,7 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_
return;
raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER;
- write_mask = sm6_value_get_constant_uint(operands[7]);
+ write_mask = sm6_value_get_constant_uint(operands[7], sm6);
if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL)
{
WARN("Invalid write mask %#x.\n", write_mask);
@@ -5679,7 +5858,7 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_
"Resource for a raw buffer store is not a raw or structured buffer.");
}
- alignment = sm6_value_get_constant_uint(operands[8]);
+ alignment = sm6_value_get_constant_uint(operands[8], sm6);
if (alignment & (alignment - 1))
{
FIXME("Invalid alignment %#x.\n", alignment);
@@ -5692,13 +5871,13 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_
return;
ins = state->ins;
- vsir_instruction_init(ins, &sm6->p.location, raw ? VKD3DSIH_STORE_RAW : VKD3DSIH_STORE_STRUCTURED);
+ vsir_instruction_init(ins, &sm6->p.location, raw ? VSIR_OP_STORE_RAW : VSIR_OP_STORE_STRUCTURED);
operand_count = 2 + !raw;
if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6)))
return;
- src_params_init_from_operands(src_params, &operands[1], operand_count - 1);
- data.data_type = VKD3D_DATA_UINT;
+ src_params_init_from_operands(src_params, &operands[1], operand_count - 1, sm6);
+ data.data_type = VSIR_DATA_U32;
src_param_init_vector_from_reg(&src_params[operand_count - 1], &data);
dst_param = instruction_dst_params_alloc(ins, 1, sm6);
@@ -5732,11 +5911,11 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri
}
instruction_init_with_resource(ins, (resource->u.handle.d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV)
- ? VKD3DSIH_LD_UAV_TYPED : VKD3DSIH_LD, resource, sm6);
+ ? VSIR_OP_LD_UAV_TYPED : VSIR_OP_LD, resource, sm6);
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
return;
- src_param_init_from_value(&src_params[0], operands[1]);
+ src_param_init_from_value(&src_params[0], operands[1], sm6);
if (!sm6_value_is_undef(operands[2]))
{
/* Constant zero would be ok, but is not worth checking for unless it shows up. */
@@ -5776,7 +5955,7 @@ static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intr
"Resource for a typed buffer store is not a typed buffer.");
}
- write_mask = sm6_value_get_constant_uint(operands[7]);
+ write_mask = sm6_value_get_constant_uint(operands[7], sm6);
if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL)
{
WARN("Invalid write mask %#x.\n", write_mask);
@@ -5797,11 +5976,11 @@ static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intr
return;
ins = state->ins;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_UAV_TYPED);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_STORE_UAV_TYPED);
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
return;
- src_param_init_from_value(&src_params[0], operands[1]);
+ src_param_init_from_value(&src_params[0], operands[1], sm6);
if (!sm6_value_is_undef(operands[2]))
{
/* Constant zero would have no effect, but is not worth checking for unless it shows up. */
@@ -5822,17 +6001,17 @@ static void sm6_parser_emit_dx_get_sample_count(struct sm6_parser *sm6, enum dx_
struct vkd3d_shader_instruction *ins = state->ins;
struct vkd3d_shader_src_param *src_param;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_INFO);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_SAMPLE_INFO);
ins->flags = VKD3DSI_SAMPLE_INFO_UINT;
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
- vsir_register_init(&src_param->reg, VKD3DSPR_RASTERIZER, VKD3D_DATA_FLOAT, 0);
+ vsir_register_init(&src_param->reg, VKD3DSPR_RASTERIZER, VSIR_DATA_F32, 0);
src_param->reg.dimension = VSIR_DIMENSION_VEC4;
src_param_init(src_param);
instruction_dst_param_init_ssa_scalar(ins, sm6);
- ins->dst->reg.data_type = VKD3D_DATA_FLOAT;
+ ins->dst->reg.data_type = VSIR_DATA_U32;
}
static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
@@ -5849,37 +6028,37 @@ static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_in
return;
}
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_POS);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_SAMPLE_POS);
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
return;
if (op == DX_TEX2DMS_GET_SAMPLE_POS)
{
src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle);
- src_param_init_from_value(&src_params[1], operands[1]);
+ src_param_init_from_value(&src_params[1], operands[1], sm6);
}
else
{
src_param_init_vector(&src_params[0], 2);
- vsir_register_init(&src_params[0].reg, VKD3DSPR_RASTERIZER, VKD3D_DATA_FLOAT, 0);
+ vsir_register_init(&src_params[0].reg, VKD3DSPR_RASTERIZER, VSIR_DATA_F32, 0);
src_params[0].reg.dimension = VSIR_DIMENSION_VEC4;
- src_param_init_from_value(&src_params[1], operands[0]);
+ src_param_init_from_value(&src_params[1], operands[0], sm6);
}
instruction_dst_param_init_ssa_vector(ins, 2, sm6);
}
-static unsigned int sm6_value_get_texel_offset(const struct sm6_value *value)
+static unsigned int sm6_value_get_texel_offset(const struct sm6_value *value, struct sm6_parser *sm6)
{
- return sm6_value_is_undef(value) ? 0 : sm6_value_get_constant_uint(value);
+ return sm6_value_is_undef(value) ? 0 : sm6_value_get_constant_uint(value, sm6);
}
static void instruction_set_texel_offset(struct vkd3d_shader_instruction *ins,
const struct sm6_value **operands, struct sm6_parser *sm6)
{
- ins->texel_offset.u = sm6_value_get_texel_offset(operands[0]);
- ins->texel_offset.v = sm6_value_get_texel_offset(operands[1]);
- ins->texel_offset.w = sm6_value_get_texel_offset(operands[2]);
+ ins->texel_offset.u = sm6_value_get_texel_offset(operands[0], sm6);
+ ins->texel_offset.v = sm6_value_get_texel_offset(operands[1], sm6);
+ ins->texel_offset.w = sm6_value_get_texel_offset(operands[2], sm6);
}
static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
@@ -5914,7 +6093,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_
switch (op)
{
case DX_SAMPLE:
- instruction_init_with_resource(ins, VKD3DSIH_SAMPLE, resource, sm6);
+ instruction_init_with_resource(ins, VSIR_OP_SAMPLE, resource, sm6);
src_params = instruction_src_params_alloc(ins, 3, sm6);
clamp_idx = 9;
break;
@@ -5922,23 +6101,23 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_
clamp_idx = 10;
/* fall through */
case DX_SAMPLE_LOD:
- instruction_init_with_resource(ins, (op == DX_SAMPLE_B) ? VKD3DSIH_SAMPLE_B : VKD3DSIH_SAMPLE_LOD,
+ instruction_init_with_resource(ins, (op == DX_SAMPLE_B) ? VSIR_OP_SAMPLE_B : VSIR_OP_SAMPLE_LOD,
resource, sm6);
src_params = instruction_src_params_alloc(ins, 4, sm6);
- src_param_init_from_value(&src_params[3], operands[9]);
+ src_param_init_from_value(&src_params[3], operands[9], sm6);
break;
case DX_SAMPLE_C:
clamp_idx = 10;
/* fall through */
case DX_SAMPLE_C_LZ:
- instruction_init_with_resource(ins, (op == DX_SAMPLE_C_LZ) ? VKD3DSIH_SAMPLE_C_LZ : VKD3DSIH_SAMPLE_C,
+ instruction_init_with_resource(ins, (op == DX_SAMPLE_C_LZ) ? VSIR_OP_SAMPLE_C_LZ : VSIR_OP_SAMPLE_C,
resource, sm6);
src_params = instruction_src_params_alloc(ins, 4, sm6);
- src_param_init_from_value(&src_params[3], operands[9]);
+ src_param_init_from_value(&src_params[3], operands[9], sm6);
component_count = 1;
break;
case DX_SAMPLE_GRAD:
- instruction_init_with_resource(ins, VKD3DSIH_SAMPLE_GRAD, resource, sm6);
+ instruction_init_with_resource(ins, VSIR_OP_SAMPLE_GRAD, resource, sm6);
src_params = instruction_src_params_alloc(ins, 5, sm6);
src_param_init_vector_from_reg(&src_params[3], &ddx);
src_param_init_vector_from_reg(&src_params[4], &ddy);
@@ -5974,7 +6153,7 @@ static void sm6_parser_emit_dx_sample_index(struct sm6_parser *sm6, enum dx_intr
struct vkd3d_shader_src_param *src_param;
unsigned int element_idx;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
/* SV_SampleIndex is identified in VSIR by its signature element index,
* but the index is not supplied as a parameter to the DXIL intrinsic. */
@@ -6000,49 +6179,25 @@ static void sm6_parser_emit_dx_saturate(struct sm6_parser *sm6, enum dx_intrinsi
struct vkd3d_shader_instruction *ins = state->ins;
struct vkd3d_shader_src_param *src_param;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
- src_param_init_from_value(src_param, operands[0]);
+ src_param_init_from_value(src_param, operands[0], sm6);
if (instruction_dst_param_init_ssa_scalar(ins, sm6))
ins->dst->modifiers = VKD3DSPDM_SATURATE;
}
-static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
- const struct sm6_value **operands, struct function_emission_state *state)
-{
- struct sm6_value *dst = sm6_parser_get_current_value(sm6);
- struct vkd3d_shader_instruction *ins = state->ins;
- struct vkd3d_shader_dst_param *dst_params;
- struct vkd3d_shader_src_param *src_param;
- unsigned int index;
-
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SINCOS);
- if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
- return;
- src_param_init_from_value(src_param, operands[0]);
-
- sm6_parser_init_ssa_value(sm6, dst);
-
- index = op == DX_COS;
- dst_params = instruction_dst_params_alloc(ins, 2, sm6);
- dst_param_init(&dst_params[0]);
- dst_param_init(&dst_params[1]);
- sm6_register_from_value(&dst_params[index].reg, dst);
- vsir_dst_param_init_null(&dst_params[index ^ 1]);
-}
-
static void sm6_parser_emit_dx_split_double(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
const struct sm6_value **operands, struct function_emission_state *state)
{
struct vkd3d_shader_instruction *ins = state->ins;
struct vkd3d_shader_src_param *src_param;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
- src_param_init_from_value(src_param, operands[0]);
+ src_param_init_from_value(src_param, operands[0], sm6);
instruction_dst_param_init_ssa_vector(ins, 2, sm6);
}
@@ -6060,8 +6215,8 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr
const struct signature_element *e;
const struct sm6_value *value;
- row_index = sm6_value_get_constant_uint(operands[0]);
- column_index = sm6_value_get_constant_uint(operands[2]);
+ row_index = sm6_value_get_constant_uint(operands[0], sm6);
+ column_index = sm6_value_get_constant_uint(operands[2], sm6);
signature = is_patch_constant ? &program->patch_constant_signature : &program->output_signature;
if (row_index >= signature->element_count)
@@ -6092,7 +6247,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr
return;
}
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6)))
return;
@@ -6103,12 +6258,12 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr
if (e->register_index == UINT_MAX)
{
- sm6_parser_dcl_register_builtin(sm6, VKD3DSIH_DCL_OUTPUT, dst_param->reg.type,
+ sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_OUTPUT, dst_param->reg.type,
dst_param->reg.data_type, vsir_write_mask_component_count(e->mask));
}
if ((src_param = instruction_src_params_alloc(ins, 1, sm6)))
- src_param_init_from_value(src_param, value);
+ src_param_init_from_value(src_param, value, sm6);
}
static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
@@ -6138,19 +6293,23 @@ static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_in
return;
}
+ /* DXIL doesn't know about signedness, but vsir expects the offset to be signed. */
+ if (extended_offset)
+ offset.data_type = VSIR_DATA_I32;
+
ins = state->ins;
if (op == DX_TEXTURE_GATHER)
{
- instruction_init_with_resource(ins, extended_offset ? VKD3DSIH_GATHER4_PO : VKD3DSIH_GATHER4, resource, sm6);
+ instruction_init_with_resource(ins, extended_offset ? VSIR_OP_GATHER4_PO : VSIR_OP_GATHER4, resource, sm6);
if (!(src_params = instruction_src_params_alloc(ins, 3 + extended_offset, sm6)))
return;
}
else
{
- instruction_init_with_resource(ins, extended_offset ? VKD3DSIH_GATHER4_PO_C : VKD3DSIH_GATHER4_C, resource, sm6);
+ instruction_init_with_resource(ins, extended_offset ? VSIR_OP_GATHER4_PO_C : VSIR_OP_GATHER4_C, resource, sm6);
if (!(src_params = instruction_src_params_alloc(ins, 4 + extended_offset, sm6)))
return;
- src_param_init_from_value(&src_params[3 + extended_offset], operands[9]);
+ src_param_init_from_value(&src_params[3 + extended_offset], operands[9], sm6);
}
src_param_init_vector_from_reg(&src_params[0], &coord);
@@ -6161,7 +6320,7 @@ static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_in
src_param_init_vector_from_handle(sm6, &src_params[1 + extended_offset], &resource->u.handle);
src_param_init_vector_from_handle(sm6, &src_params[2 + extended_offset], &sampler->u.handle);
/* Swizzle stored in the sampler parameter is the scalar component index to be gathered. */
- swizzle = sm6_value_get_constant_uint(operands[8]);
+ swizzle = sm6_value_get_constant_uint(operands[8], sm6);
if (swizzle >= VKD3D_VEC4_SIZE)
{
WARN("Invalid swizzle %#x.\n", swizzle);
@@ -6201,8 +6360,8 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr
}
ins = state->ins;
- instruction_init_with_resource(ins, is_uav ? VKD3DSIH_LD_UAV_TYPED
- : is_multisample ? VKD3DSIH_LD2DMS : VKD3DSIH_LD, resource, sm6);
+ instruction_init_with_resource(ins, is_uav ? VSIR_OP_LD_UAV_TYPED
+ : is_multisample ? VSIR_OP_LD2DMS : VSIR_OP_LD, resource, sm6);
instruction_set_texel_offset(ins, &operands[5], sm6);
for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
@@ -6213,7 +6372,7 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr
src_param_init_vector_from_reg(&src_params[0], &coord);
src_param_init_vector_from_handle(sm6, &src_params[1], &resource->u.handle);
if (is_multisample)
- src_param_init_from_value(&src_params[2], mip_level_or_sample_count);
+ src_param_init_from_value(&src_params[2], mip_level_or_sample_count, sm6);
instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6);
}
@@ -6235,7 +6394,7 @@ static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_int
if (!sm6_parser_emit_coordinate_construct(sm6, &operands[1], 3, NULL, state, &coord))
return;
- write_mask = sm6_value_get_constant_uint(operands[8]);
+ write_mask = sm6_value_get_constant_uint(operands[8], sm6);
if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL)
{
WARN("Invalid write mask %#x.\n", write_mask);
@@ -6256,7 +6415,7 @@ static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_int
return;
ins = state->ins;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_UAV_TYPED);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_STORE_UAV_TYPED);
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
return;
@@ -6274,10 +6433,10 @@ static void sm6_parser_emit_dx_wave_active_ballot(struct sm6_parser *sm6, enum d
struct vkd3d_shader_instruction *ins = state->ins;
struct vkd3d_shader_src_param *src_param;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_WAVE_ACTIVE_BALLOT);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_WAVE_ACTIVE_BALLOT);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
- src_param_init_from_value(src_param, operands[0]);
+ src_param_init_from_value(src_param, operands[0], sm6);
instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6);
}
@@ -6288,16 +6447,16 @@ static enum vkd3d_shader_opcode sm6_dx_map_wave_bit_op(enum dxil_wave_bit_op_kin
switch (op)
{
case WAVE_BIT_OP_AND:
- return VKD3DSIH_WAVE_ACTIVE_BIT_AND;
+ return VSIR_OP_WAVE_ACTIVE_BIT_AND;
case WAVE_BIT_OP_OR:
- return VKD3DSIH_WAVE_ACTIVE_BIT_OR;
+ return VSIR_OP_WAVE_ACTIVE_BIT_OR;
case WAVE_BIT_OP_XOR:
- return VKD3DSIH_WAVE_ACTIVE_BIT_XOR;
+ return VSIR_OP_WAVE_ACTIVE_BIT_XOR;
default:
FIXME("Unhandled wave bit op %u.\n", op);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC,
- "Wave bit operation %u is unhandled.\n", op);
- return VKD3DSIH_INVALID;
+ "Wave bit operation %u is unhandled.", op);
+ return VSIR_OP_INVALID;
}
}
@@ -6309,15 +6468,15 @@ static void sm6_parser_emit_dx_wave_active_bit(struct sm6_parser *sm6, enum dx_i
enum dxil_wave_bit_op_kind wave_op;
enum vkd3d_shader_opcode opcode;
- wave_op = sm6_value_get_constant_uint(operands[1]);
+ wave_op = sm6_value_get_constant_uint(operands[1], sm6);
- if ((opcode = sm6_dx_map_wave_bit_op(wave_op, sm6)) == VKD3DSIH_INVALID)
+ if ((opcode = sm6_dx_map_wave_bit_op(wave_op, sm6)) == VSIR_OP_INVALID)
return;
vsir_instruction_init(ins, &sm6->p.location, opcode);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
- src_param_init_from_value(src_param, operands[0]);
+ src_param_init_from_value(src_param, operands[0], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6);
}
@@ -6328,22 +6487,22 @@ static enum vkd3d_shader_opcode sm6_dx_map_wave_op(enum dxil_wave_op_kind op, bo
switch (op)
{
case WAVE_OP_ADD:
- return VKD3DSIH_WAVE_OP_ADD;
+ return VSIR_OP_WAVE_OP_ADD;
case WAVE_OP_MUL:
- return VKD3DSIH_WAVE_OP_MUL;
+ return VSIR_OP_WAVE_OP_MUL;
case WAVE_OP_MIN:
if (is_float)
- return VKD3DSIH_WAVE_OP_MIN;
- return is_signed ? VKD3DSIH_WAVE_OP_IMIN : VKD3DSIH_WAVE_OP_UMIN;
+ return VSIR_OP_WAVE_OP_MIN;
+ return is_signed ? VSIR_OP_WAVE_OP_IMIN : VSIR_OP_WAVE_OP_UMIN;
case WAVE_OP_MAX:
if (is_float)
- return VKD3DSIH_WAVE_OP_MAX;
- return is_signed ? VKD3DSIH_WAVE_OP_IMAX : VKD3DSIH_WAVE_OP_UMAX;
+ return VSIR_OP_WAVE_OP_MAX;
+ return is_signed ? VSIR_OP_WAVE_OP_IMAX : VSIR_OP_WAVE_OP_UMAX;
default:
FIXME("Unhandled wave op %u.\n", op);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC,
- "Wave operation %u is unhandled.\n", op);
- return VKD3DSIH_INVALID;
+ "Wave operation %u is unhandled.", op);
+ return VSIR_OP_INVALID;
}
}
@@ -6356,11 +6515,11 @@ static void sm6_parser_emit_dx_wave_op(struct sm6_parser *sm6, enum dx_intrinsic
enum dxil_wave_op_kind wave_op;
bool is_signed;
- wave_op = sm6_value_get_constant_uint(operands[1]);
- is_signed = !sm6_value_get_constant_uint(operands[2]);
+ wave_op = sm6_value_get_constant_uint(operands[1], sm6);
+ is_signed = !sm6_value_get_constant_uint(operands[2], sm6);
opcode = sm6_dx_map_wave_op(wave_op, is_signed, sm6_type_is_floating_point(operands[0]->type), sm6);
- if (opcode == VKD3DSIH_INVALID)
+ if (opcode == VSIR_OP_INVALID)
return;
vsir_instruction_init(ins, &sm6->p.location, opcode);
@@ -6368,7 +6527,7 @@ static void sm6_parser_emit_dx_wave_op(struct sm6_parser *sm6, enum dx_intrinsic
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
- src_param_init_from_value(src_param, operands[0]);
+ src_param_init_from_value(src_param, operands[0], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6);
}
@@ -6390,7 +6549,7 @@ static void sm6_parser_emit_dx_wave_builtin(struct sm6_parser *sm6, enum dx_intr
vkd3d_unreachable();
}
- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, type, VKD3D_DATA_UINT);
+ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, type, VSIR_DATA_U32, true);
}
struct sm6_dx_opcode_info
@@ -6436,7 +6595,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
[DX_BUFFER_UPDATE_COUNTER ] = {"i", "H8", sm6_parser_emit_dx_buffer_update_counter},
[DX_CALCULATE_LOD ] = {"f", "HHfffb", sm6_parser_emit_dx_calculate_lod},
[DX_CBUFFER_LOAD_LEGACY ] = {"o", "Hi", sm6_parser_emit_dx_cbuffer_load},
- [DX_COS ] = {"g", "R", sm6_parser_emit_dx_sincos},
+ [DX_COS ] = {"g", "R", sm6_parser_emit_dx_unary},
[DX_COUNT_BITS ] = {"i", "m", sm6_parser_emit_dx_unary},
[DX_COVERAGE ] = {"i", "", sm6_parser_emit_dx_coverage},
[DX_CREATE_HANDLE ] = {"H", "ccib", sm6_parser_emit_dx_create_handle},
@@ -6505,7 +6664,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
[DX_SAMPLE_INDEX ] = {"i", "", sm6_parser_emit_dx_sample_index},
[DX_SAMPLE_LOD ] = {"o", "HHffffiiif", sm6_parser_emit_dx_sample},
[DX_SATURATE ] = {"g", "R", sm6_parser_emit_dx_saturate},
- [DX_SIN ] = {"g", "R", sm6_parser_emit_dx_sincos},
+ [DX_SIN ] = {"g", "R", sm6_parser_emit_dx_unary},
[DX_SPLIT_DOUBLE ] = {"S", "d", sm6_parser_emit_dx_split_double},
[DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary},
[DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output},
@@ -6539,11 +6698,13 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
};
static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_value *value, char info_type,
- const struct sm6_type *ret_type, bool is_return)
+ const struct sm6_type *ret_type)
{
const struct sm6_type *type = value->type;
- if (info_type != 'H' && !sm6_value_is_register(value))
+ if (info_type != 'H' && info_type != 'v' && !sm6_value_is_register(value))
+ return false;
+ if (!type && info_type != 'v')
return false;
switch (info_type)
@@ -6578,7 +6739,7 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc
case 'g':
return sm6_type_is_floating_point(type);
case 'H':
- return (is_return || sm6_value_is_handle(value)) && type == sm6->handle_type;
+ return sm6_value_is_handle(value) && type == sm6->handle_type;
case 'D':
return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.Dimensions");
case 'S':
@@ -6586,7 +6747,7 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc
case 'V':
return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.fouri32");
case 'v':
- return !type;
+ return sm6_value_is_invalid(value) && !type;
case 'o':
/* TODO: some type checking may be possible */
return true;
@@ -6606,18 +6767,10 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_
info = &sm6_dx_op_table[op];
- VKD3D_ASSERT(info->ret_type[0]);
- if (!sm6_parser_validate_operand_type(sm6, dst, info->ret_type[0], NULL, true))
- {
- WARN("Failed to validate return type for dx intrinsic id %u, '%s'.\n", op, name);
- /* Return type validation failure is not so critical. We only need to set
- * a data type for the SSA result. */
- }
-
for (i = 0; i < operand_count; ++i)
{
const struct sm6_value *value = operands[i];
- if (!sm6_parser_validate_operand_type(sm6, value, info->operand_info[i], dst->type, false))
+ if (!sm6_parser_validate_operand_type(sm6, value, info->operand_info[i], dst->type))
{
WARN("Failed to validate operand %u for dx intrinsic id %u, '%s'.\n", i + 1, op, name);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
@@ -6639,13 +6792,12 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_
static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shader_instruction *ins,
struct sm6_value *dst)
{
- ins->opcode = VKD3DSIH_NOP;
+ ins->opcode = VSIR_OP_NOP;
if (!dst->type)
return;
dst->value_type = VALUE_TYPE_INVALID;
- sm6_register_from_value(&dst->reg, dst);
}
static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
@@ -6661,10 +6813,22 @@ static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_op
return;
}
- if (sm6_parser_validate_dx_op(sm6, op, name, operands, operand_count, dst))
- sm6_dx_op_table[op].handler(sm6, op, operands, state);
- else
+ if (!sm6_parser_validate_dx_op(sm6, op, name, operands, operand_count, dst))
+ {
sm6_parser_emit_unhandled(sm6, state->ins, dst);
+ return;
+ }
+
+ sm6_dx_op_table[op].handler(sm6, op, operands, state);
+
+ VKD3D_ASSERT(sm6_dx_op_table[op].ret_type[0]);
+ if (!sm6_parser_validate_operand_type(sm6, dst, sm6_dx_op_table[op].ret_type[0], NULL))
+ {
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+ "Failed to validate return type for dx intrinsic id %u, '%s'.", op, name);
+ /* Return type validation failure is not so critical. We only need to set
+ * a data type for the SSA result. */
+ }
}
static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_record *record,
@@ -6750,15 +6914,16 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor
"Expected a constant integer dx intrinsic function id.");
return;
}
- sm6_parser_decode_dx_op(sm6, sm6_value_get_constant_uint(op_value),
+ sm6_parser_decode_dx_op(sm6, sm6_value_get_constant_uint(op_value, sm6),
fn_value->u.function.name, &operands[1], operand_count - 1, state, dst);
}
static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_type *from,
const struct sm6_type *to, struct sm6_parser *sm6)
{
- enum vkd3d_shader_opcode op = VKD3DSIH_INVALID;
+ enum vkd3d_shader_opcode op = VSIR_OP_INVALID;
bool from_int, to_int, from_fp, to_fp;
+ unsigned int from_width, to_width;
bool is_valid = false;
from_int = sm6_type_is_integer(from);
@@ -6772,92 +6937,98 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_
FIXME("Unhandled cast of type class %u to type class %u.\n", from->class, to->class);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
"Cast of type class %u to type class %u is not implemented.", from->class, to->class);
- return VKD3DSIH_INVALID;
+ return VSIR_OP_INVALID;
}
if (to->u.width == 8 || from->u.width == 8)
{
FIXME("Unhandled 8-bit value.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
"Cast to/from an 8-bit type is not implemented.");
- return VKD3DSIH_INVALID;
+ return VSIR_OP_INVALID;
}
- /* DXC emits minimum precision types as 16-bit. These must be emitted
- * as 32-bit in VSIR, so all width extensions to 32 bits are no-ops. */
switch (code)
{
case CAST_TRUNC:
- /* nop or min precision. TODO: native 16-bit */
- if (to->u.width == from->u.width || (to->u.width == 16 && from->u.width == 32))
- op = VKD3DSIH_NOP;
- else
- op = VKD3DSIH_UTOU;
+ op = VSIR_OP_UTOU;
is_valid = from_int && to_int && to->u.width <= from->u.width;
break;
+
case CAST_ZEXT:
+ op = VSIR_OP_UTOU;
+ is_valid = from_int && to_int && to->u.width >= from->u.width;
+ break;
+
case CAST_SEXT:
- /* nop or min precision. TODO: native 16-bit.
- * Extension instructions could be emitted for min precision, but in Windows
- * the AMD RX 580 simply drops such instructions, which makes sense as no
- * assumptions should be made about any behaviour which depends on bit width. */
- if (to->u.width == from->u.width || (to->u.width == 32 && from->u.width == 16))
- {
- op = VKD3DSIH_NOP;
- is_valid = from_int && to_int;
- }
- else if (to->u.width > from->u.width)
- {
- op = (code == CAST_ZEXT) ? VKD3DSIH_UTOU : VKD3DSIH_ITOI;
- VKD3D_ASSERT(from->u.width == 1 || to->u.width == 64);
- is_valid = from_int && to_int;
- }
+ op = VSIR_OP_ITOI;
+ is_valid = from_int && to_int && to->u.width >= from->u.width;
break;
+
case CAST_FPTOUI:
- op = VKD3DSIH_FTOU;
+ op = VSIR_OP_FTOU;
is_valid = from_fp && to_int && to->u.width > 1;
break;
+
case CAST_FPTOSI:
- op = VKD3DSIH_FTOI;
+ op = VSIR_OP_FTOI;
is_valid = from_fp && to_int && to->u.width > 1;
break;
+
case CAST_UITOFP:
- op = VKD3DSIH_UTOF;
+ op = VSIR_OP_UTOF;
is_valid = from_int && to_fp;
break;
+
case CAST_SITOFP:
- op = VKD3DSIH_ITOF;
+ op = VSIR_OP_ITOF;
is_valid = from_int && to_fp;
break;
+
case CAST_FPTRUNC:
- /* TODO: native 16-bit */
- op = (from->u.width == 64) ? VKD3DSIH_DTOF : VKD3DSIH_NOP;
- is_valid = from_fp && to_fp;
+ op = VSIR_OP_DTOF;
+ is_valid = from_fp && to_fp && to->u.width <= from->u.width;
break;
+
case CAST_FPEXT:
- /* TODO: native 16-bit */
- op = (to->u.width == 64) ? VKD3DSIH_FTOD : VKD3DSIH_NOP;
- is_valid = from_fp && to_fp;
+ op = VSIR_OP_FTOD;
+ is_valid = from_fp && to_fp && to->u.width >= from->u.width;
break;
+
case CAST_BITCAST:
- op = VKD3DSIH_MOV;
+ op = VSIR_OP_MOV;
is_valid = to->u.width == from->u.width;
break;
+
default:
FIXME("Unhandled cast op %"PRIu64".\n", code);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
- "Cast operation %"PRIu64" is unhandled.\n", code);
- return VKD3DSIH_INVALID;
+ "Cast operation %"PRIu64" is unhandled.", code);
+ return VSIR_OP_INVALID;
}
if (!is_valid)
{
FIXME("Invalid types %u and/or %u for op %"PRIu64".\n", from->class, to->class, code);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
- "Cast operation %"PRIu64" from type class %u, width %u to type class %u, width %u is invalid.\n",
+ "Cast operation %"PRIu64" from type class %u, width %u to type class %u, width %u is invalid.",
code, from->class, from->u.width, to->class, to->u.width);
- return VKD3DSIH_INVALID;
+ return VSIR_OP_INVALID;
}
+ /* 16-bit values are currently treated as 32-bit, because 16-bit is
+ * interpreted as a minimum precision hint in SM 6.0, and we don't handle
+ * SM > 6.0 yet. */
+ from_width = from->u.width;
+ if (from_width == 16)
+ from_width = 32;
+
+ to_width = to->u.width;
+ if (to_width == 16)
+ to_width = 32;
+
+ if (from->class == to->class && from_width == to_width)
+ op = VSIR_OP_NOP;
+
return op;
}
@@ -6885,33 +7056,33 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor
{
*dst = *value;
dst->type = type;
- ins->opcode = VKD3DSIH_NOP;
+ ins->opcode = VSIR_OP_NOP;
return;
}
- if ((handler_idx = sm6_map_cast_op(record->operands[i], value->type, type, sm6)) == VKD3DSIH_INVALID)
+ if ((handler_idx = sm6_map_cast_op(record->operands[i], value->type, type, sm6)) == VSIR_OP_INVALID)
return;
vsir_instruction_init(ins, &sm6->p.location, handler_idx);
- if (handler_idx == VKD3DSIH_NOP)
+ if (handler_idx == VSIR_OP_NOP)
{
- sm6_register_from_value(&dst->reg, value);
- /* Set the result type for casts from 16-bit min precision. */
- if (type->u.width != 16)
- dst->reg.data_type = vkd3d_data_type_from_sm6_type(type);
+ *dst = *value;
+ dst->type = type;
return;
}
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
- src_param_init_from_value(src_param, value);
+ src_param_init_from_value(src_param, value, sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6);
- /* bitcast */
- if (handler_idx == VKD3DSIH_MOV)
- src_param->reg.data_type = dst->reg.data_type;
+ /* VSIR bitcasts are represented by source registers with types different
+ * from the types they were written with, rather than with different types
+ * for the MOV source and destination. */
+ if (handler_idx == VSIR_OP_MOV)
+ src_param->reg.data_type = ins->dst[0].reg.data_type;
}
struct sm6_cmp_info
@@ -6924,33 +7095,33 @@ static const struct sm6_cmp_info *sm6_map_cmp2_op(uint64_t code)
{
static const struct sm6_cmp_info cmp_op_table[] =
{
- [FCMP_FALSE] = {VKD3DSIH_INVALID},
- [FCMP_OEQ] = {VKD3DSIH_EQO},
- [FCMP_OGT] = {VKD3DSIH_LTO, true},
- [FCMP_OGE] = {VKD3DSIH_GEO},
- [FCMP_OLT] = {VKD3DSIH_LTO},
- [FCMP_OLE] = {VKD3DSIH_GEO, true},
- [FCMP_ONE] = {VKD3DSIH_NEO},
- [FCMP_ORD] = {VKD3DSIH_ORD},
- [FCMP_UNO] = {VKD3DSIH_UNO},
- [FCMP_UEQ] = {VKD3DSIH_EQU},
- [FCMP_UGT] = {VKD3DSIH_LTU, true},
- [FCMP_UGE] = {VKD3DSIH_GEU},
- [FCMP_ULT] = {VKD3DSIH_LTU},
- [FCMP_ULE] = {VKD3DSIH_GEU, true},
- [FCMP_UNE] = {VKD3DSIH_NEU},
- [FCMP_TRUE] = {VKD3DSIH_INVALID},
-
- [ICMP_EQ] = {VKD3DSIH_IEQ},
- [ICMP_NE] = {VKD3DSIH_INE},
- [ICMP_UGT] = {VKD3DSIH_ULT, true},
- [ICMP_UGE] = {VKD3DSIH_UGE},
- [ICMP_ULT] = {VKD3DSIH_ULT},
- [ICMP_ULE] = {VKD3DSIH_UGE, true},
- [ICMP_SGT] = {VKD3DSIH_ILT, true},
- [ICMP_SGE] = {VKD3DSIH_IGE},
- [ICMP_SLT] = {VKD3DSIH_ILT},
- [ICMP_SLE] = {VKD3DSIH_IGE, true},
+ [FCMP_FALSE] = {VSIR_OP_INVALID},
+ [FCMP_OEQ] = {VSIR_OP_EQO},
+ [FCMP_OGT] = {VSIR_OP_LTO, true},
+ [FCMP_OGE] = {VSIR_OP_GEO},
+ [FCMP_OLT] = {VSIR_OP_LTO},
+ [FCMP_OLE] = {VSIR_OP_GEO, true},
+ [FCMP_ONE] = {VSIR_OP_NEO},
+ [FCMP_ORD] = {VSIR_OP_ORD},
+ [FCMP_UNO] = {VSIR_OP_UNO},
+ [FCMP_UEQ] = {VSIR_OP_EQU},
+ [FCMP_UGT] = {VSIR_OP_LTU, true},
+ [FCMP_UGE] = {VSIR_OP_GEU},
+ [FCMP_ULT] = {VSIR_OP_LTU},
+ [FCMP_ULE] = {VSIR_OP_GEU, true},
+ [FCMP_UNE] = {VSIR_OP_NEU},
+ [FCMP_TRUE] = {VSIR_OP_INVALID},
+
+ [ICMP_EQ] = {VSIR_OP_IEQ},
+ [ICMP_NE] = {VSIR_OP_INE},
+ [ICMP_UGT] = {VSIR_OP_ULT, true},
+ [ICMP_UGE] = {VSIR_OP_UGE},
+ [ICMP_ULT] = {VSIR_OP_ULT},
+ [ICMP_ULE] = {VSIR_OP_UGE, true},
+ [ICMP_SGT] = {VSIR_OP_ILT, true},
+ [ICMP_SGE] = {VSIR_OP_IGE},
+ [ICMP_SLT] = {VSIR_OP_ILT},
+ [ICMP_SLE] = {VSIR_OP_IGE, true},
};
return (code < ARRAY_SIZE(cmp_op_table)) ? &cmp_op_table[code] : NULL;
@@ -6996,7 +7167,7 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor
* do not otherwise occur, so deleting these avoids the need for backend support. */
if (sm6_type_is_bool(type_a) && code == ICMP_NE && sm6_value_is_constant_zero(b))
{
- ins->opcode = VKD3DSIH_NOP;
+ ins->opcode = VSIR_OP_NOP;
*dst = *a;
return;
}
@@ -7017,7 +7188,7 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor
"Type mismatch in comparison operation arguments.");
}
- if (!(cmp = sm6_map_cmp2_op(code)) || !cmp->handler_idx || cmp->handler_idx == VKD3DSIH_INVALID)
+ if (!(cmp = sm6_map_cmp2_op(code)) || !cmp->handler_idx || cmp->handler_idx == VSIR_OP_INVALID)
{
FIXME("Unhandled operation %"PRIu64".\n", code);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
@@ -7051,8 +7222,8 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6)))
return;
- src_param_init_from_value(&src_params[0 ^ cmp->src_swap], a);
- src_param_init_from_value(&src_params[1 ^ cmp->src_swap], b);
+ src_param_init_from_value(&src_params[0 ^ cmp->src_swap], a, sm6);
+ src_param_init_from_value(&src_params[1 ^ cmp->src_swap], b, sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6);
}
@@ -7074,7 +7245,7 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re
|| !sm6_value_validate_is_backward_ref(ptr, sm6))
return;
- sm6_register_from_value(&reg, ptr);
+ sm6_register_from_value(&reg, ptr, sm6);
if (reg.type != VKD3DSPR_GROUPSHAREDMEM)
{
@@ -7123,20 +7294,20 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re
if (record->operand_count > i && record->operands[i])
FIXME("Ignoring weak cmpxchg.\n");
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_IMM_ATOMIC_CMP_EXCH);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_IMM_ATOMIC_CMP_EXCH);
ins->flags = is_volatile ? VKD3DARF_SEQ_CST | VKD3DARF_VOLATILE : VKD3DARF_SEQ_CST;
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
return;
src_param_make_constant_uint(&src_params[0], 0);
- src_param_init_from_value(&src_params[1], cmp);
- src_param_init_from_value(&src_params[2], new);
+ src_param_init_from_value(&src_params[1], cmp, sm6);
+ src_param_init_from_value(&src_params[2], new, sm6);
sm6_parser_init_ssa_value(sm6, dst);
if (!(dst_params = instruction_dst_params_alloc(ins, 2, sm6)))
return;
- sm6_register_from_value(&dst_params[0].reg, dst);
+ sm6_register_from_value(&dst_params[0].reg, dst, sm6);
dst_param_init(&dst_params[0]);
dst_params[1].reg = reg;
dst_param_init(&dst_params[1]);
@@ -7191,11 +7362,11 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil
}
dst->type = type;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
- sm6_register_from_value(&src_param->reg, src);
+ sm6_register_from_value(&src_param->reg, src, sm6);
src_param_init_scalar(src_param, elem_idx);
instruction_dst_param_init_ssa_scalar(ins, sm6);
@@ -7208,9 +7379,8 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record
unsigned int elem_idx, operand_idx = 2;
enum bitcode_address_space addr_space;
const struct sm6_value *elem_value;
- struct vkd3d_shader_register reg;
const struct sm6_value *src;
- bool is_in_bounds;
+ struct sm6_index *index;
if (!dxil_record_validate_operand_min_count(record, 5, sm6)
|| !(type = sm6_parser_get_type(sm6, record->operands[1]))
@@ -7222,9 +7392,13 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record
return;
}
- sm6_register_from_value(&reg, src);
+ *dst = *src;
+ index = sm6_get_value_index(sm6, dst);
- if (reg.idx_count > 1)
+ if (!index)
+ return;
+
+ if (index->index)
{
WARN("Unsupported stacked GEP.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
@@ -7232,8 +7406,6 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record
return;
}
- is_in_bounds = record->operands[0];
-
if ((pointee_type = src->type->u.pointer.type) != type)
{
WARN("Type mismatch, type %u width %u vs type %u width %u.\n", type->class,
@@ -7247,7 +7419,7 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record
return;
/* The first index is always zero, to form a simple pointer dereference. */
- if (sm6_value_get_constant_uint(elem_value))
+ if (sm6_value_get_constant_uint(elem_value, sm6))
{
WARN("Expected constant zero.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
@@ -7267,7 +7439,7 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record
return;
/* If indexing is dynamic, just get the type at offset zero. */
- elem_idx = sm6_value_is_constant(elem_value) ? sm6_value_get_constant_uint(elem_value) : 0;
+ elem_idx = sm6_value_is_constant(elem_value) ? sm6_value_get_constant_uint(elem_value, sm6) : 0;
type = sm6_type_get_element_type_at_index(pointee_type, elem_idx);
if (!type)
{
@@ -7293,15 +7465,10 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record
return;
}
- reg.idx[1].offset = 0;
- register_index_address_init(&reg.idx[1], elem_value, sm6);
- reg.idx[1].is_in_bounds = is_in_bounds;
- reg.idx_count = 2;
-
- dst->reg = reg;
- dst->structure_stride = src->structure_stride;
+ index->index = elem_value;
+ index->is_in_bounds = record->operands[0];
- ins->opcode = VKD3DSIH_NOP;
+ ins->opcode = VSIR_OP_NOP;
}
static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_record *record,
@@ -7348,12 +7515,12 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor
if (record->operands[i])
WARN("Ignoring volatile modifier.\n");
- sm6_register_from_value(&reg, ptr);
+ sm6_register_from_value(&reg, ptr, sm6);
if (ptr->structure_stride)
{
VKD3D_ASSERT(reg.type == VKD3DSPR_GROUPSHAREDMEM);
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_LD_STRUCTURED);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_LD_STRUCTURED);
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
return;
@@ -7363,7 +7530,7 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor
src_param_make_constant_uint(&src_params[0], reg.idx[1].offset);
/* Struct offset is always zero as there is no struct, just an array. */
src_param_make_constant_uint(&src_params[1], 0);
- src_param_init_from_value(&src_params[2], ptr);
+ src_param_init_from_value(&src_params[2], ptr, sm6);
src_params[2].reg.alignment = alignment;
/* The offset is already in src_params[0]. */
src_params[2].reg.idx_count = 1;
@@ -7371,13 +7538,13 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor
else
{
operand_count = 1 + (reg.type == VKD3DSPR_GROUPSHAREDMEM);
- vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VKD3DSIH_LD_RAW : VKD3DSIH_MOV);
+ vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VSIR_OP_LD_RAW : VSIR_OP_MOV);
if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6)))
return;
if (operand_count > 1)
src_param_make_constant_uint(&src_params[0], 0);
- src_param_init_from_value(&src_params[operand_count - 1], ptr);
+ src_param_init_from_value(&src_params[operand_count - 1], ptr, sm6);
src_params[operand_count - 1].reg.alignment = alignment;
}
@@ -7425,7 +7592,6 @@ static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record
if (!(phi = sm6_block_phi_require_space(code_block, sm6)))
return;
- sm6_register_from_value(&phi->reg, dst);
phi->incoming_count = record->operand_count / 2u;
if (!vkd3d_array_reserve((void **)&phi->incoming, &phi->incoming_capacity, phi->incoming_count,
@@ -7456,7 +7622,7 @@ static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record
incoming[j].block = sm6_function_get_block(function, record->operands[i + 1], sm6);
}
- ins->opcode = VKD3DSIH_NOP;
+ ins->opcode = VSIR_OP_NOP;
qsort(incoming, phi->incoming_count, sizeof(*incoming), phi_incoming_compare);
@@ -7491,7 +7657,7 @@ static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record
code_block->terminator.type = TERMINATOR_RET;
- ins->opcode = VKD3DSIH_NOP;
+ ins->opcode = VSIR_OP_NOP;
}
static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_record *record,
@@ -7536,12 +7702,12 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco
if (record->operands[i])
WARN("Ignoring volatile modifier.\n");
- sm6_register_from_value(&reg, ptr);
+ sm6_register_from_value(&reg, ptr, sm6);
if (ptr->structure_stride)
{
VKD3D_ASSERT(reg.type == VKD3DSPR_GROUPSHAREDMEM);
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_STRUCTURED);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_STORE_STRUCTURED);
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
return;
@@ -7551,18 +7717,18 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco
src_param_make_constant_uint(&src_params[0], reg.idx[1].offset);
/* Struct offset is always zero as there is no struct, just an array. */
src_param_make_constant_uint(&src_params[1], 0);
- src_param_init_from_value(&src_params[2], src);
+ src_param_init_from_value(&src_params[2], src, sm6);
}
else
{
operand_count = 1 + (reg.type == VKD3DSPR_GROUPSHAREDMEM);
- vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VKD3DSIH_STORE_RAW : VKD3DSIH_MOV);
+ vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VSIR_OP_STORE_RAW : VSIR_OP_MOV);
if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6)))
return;
if (operand_count > 1)
src_param_make_constant_uint(&src_params[0], 0);
- src_param_init_from_value(&src_params[operand_count - 1], src);
+ src_param_init_from_value(&src_params[operand_count - 1], src, sm6);
}
dst_param = instruction_dst_params_alloc(ins, 1, sm6);
@@ -7612,7 +7778,7 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec
return;
}
- sm6_register_from_value(&terminator->conditional_reg, src);
+ sm6_register_from_value(&terminator->conditional_reg, src, sm6);
terminator->type = TERMINATOR_SWITCH;
terminator->case_count = record->operand_count / 2u;
@@ -7651,10 +7817,10 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec
"A switch case value is not a constant.");
}
- terminator->cases[i / 2u].value = sm6_value_get_constant_uint64(src);
+ terminator->cases[i / 2u].value = sm6_value_get_constant_uint64(src, sm6);
}
- ins->opcode = VKD3DSIH_NOP;
+ ins->opcode = VSIR_OP_NOP;
}
static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_record *record,
@@ -7683,12 +7849,12 @@ static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_re
if (!sm6_value_validate_is_bool(src[0], sm6))
return;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOVC);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOVC);
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
return;
for (i = 0; i < 3; ++i)
- src_param_init_from_value(&src_params[i], src[i]);
+ src_param_init_from_value(&src_params[i], src[i], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6);
}
@@ -7714,7 +7880,7 @@ static bool sm6_metadata_value_is_zero_or_undef(const struct sm6_metadata_value
&& (sm6_value_is_undef(m->u.value) || sm6_value_is_constant_zero(m->u.value));
}
-static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6,
+static bool sm6_metadata_get_uint_value(struct sm6_parser *sm6,
const struct sm6_metadata_value *m, unsigned int *u)
{
const struct sm6_value *value;
@@ -7728,12 +7894,12 @@ static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6,
if (!sm6_type_is_integer(value->type))
return false;
- *u = sm6_value_get_constant_uint(value);
+ *u = sm6_value_get_constant_uint(value, sm6);
return true;
}
-static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6,
+static bool sm6_metadata_get_uint64_value(struct sm6_parser *sm6,
const struct sm6_metadata_value *m, uint64_t *u)
{
const struct sm6_value *value;
@@ -7747,12 +7913,12 @@ static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6,
if (!sm6_type_is_integer(value->type))
return false;
- *u = sm6_value_get_constant_uint(value);
+ *u = sm6_value_get_constant_uint(value, sm6);
return true;
}
-static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6,
+static bool sm6_metadata_get_float_value(struct sm6_parser *sm6,
const struct sm6_metadata_value *m, float *f)
{
const struct sm6_value *value;
@@ -7766,7 +7932,7 @@ static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6,
if (!sm6_type_is_floating_point(value->type))
return false;
- *f = register_get_float_value(&value->reg);
+ *f = sm6_value_get_constant_float(value, sm6);
return true;
}
@@ -7951,7 +8117,7 @@ static void metadata_attachment_record_apply(const struct dxil_record *record, e
}
else if (metadata_node_get_unary_uint(node, &operand, sm6))
{
- dst->reg.non_uniform = !!operand;
+ dst->non_uniform = !!operand;
}
}
else
@@ -8023,13 +8189,13 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun
"A PHI incoming value is not a constant or SSA register.");
return VKD3D_ERROR_INVALID_SHADER;
}
- if (src->reg.data_type != phi->reg.data_type)
+ if (src->type != phi->value.type)
{
WARN("Type mismatch.\n");
vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH,
"The type of a phi incoming value does not match the result type.");
}
- sm6_register_from_value(&phi->incoming[j].reg, src);
+ sm6_register_from_value(&phi->incoming[j].reg, src, sm6);
}
}
}
@@ -8113,12 +8279,11 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
}
ins = &code_block->instructions[code_block->instruction_count];
- ins->opcode = VKD3DSIH_INVALID;
+ ins->opcode = VSIR_OP_INVALID;
dst = sm6_parser_get_current_value(sm6);
fwd_type = dst->type;
dst->type = NULL;
- dst->value_type = VALUE_TYPE_REG;
dst->is_back_ref = true;
is_terminator = false;
@@ -8196,13 +8361,17 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
if (record->attachment)
metadata_attachment_record_apply(record->attachment, record->code, ins, dst, sm6);
+ /* This is specific for PHI nodes, but must happen after attachments have been applied. */
+ if (record->code == FUNC_CODE_INST_PHI)
+ code_block->phi[code_block->phi_count - 1].value = *dst;
+
if (is_terminator)
{
++block_idx;
code_block = (block_idx < function->block_count) ? function->blocks[block_idx] : NULL;
}
if (code_block)
- code_block->instruction_count += ins->opcode != VKD3DSIH_NOP;
+ code_block->instruction_count += ins->opcode != VSIR_OP_NOP;
if (dst->type && fwd_type && dst->type != fwd_type)
{
@@ -8234,7 +8403,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_
case TERMINATOR_UNCOND_BR:
if (!block->terminator.true_block)
return;
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_BRANCH);
+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_BRANCH);
if (!(src_params = instruction_src_params_alloc(ins, 1, sm6)))
return;
vsir_src_param_init_label(&src_params[0], block->terminator.true_block->id);
@@ -8243,7 +8412,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_
case TERMINATOR_COND_BR:
if (!block->terminator.true_block || !block->terminator.false_block)
return;
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_BRANCH);
+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_BRANCH);
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6)))
return;
src_param_init(&src_params[0]);
@@ -8253,7 +8422,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_
break;
case TERMINATOR_SWITCH:
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_SWITCH_MONOLITHIC);
+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_SWITCH_MONOLITHIC);
if (!(src_params = instruction_src_params_alloc(ins, block->terminator.case_count * 2u + 1, sm6)))
return;
src_param_init(&src_params[0]);
@@ -8278,9 +8447,9 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_
continue;
}
- if (src_params[0].reg.data_type == VKD3D_DATA_UINT64)
+ if (src_params[0].reg.data_type == VSIR_DATA_U64)
{
- vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST64, VKD3D_DATA_UINT64, 0);
+ vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST64, VSIR_DATA_U64, 0);
src_params[count++].reg.u.immconst_u64[0] = switch_case->value;
}
else
@@ -8291,7 +8460,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_
vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH,
"Truncating 64-bit switch case value %"PRIx64" to 32 bits.", switch_case->value);
}
- vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0);
+ vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0);
src_params[count++].reg.u.immconst_u32[0] = switch_case->value;
}
vsir_src_param_init_label(&src_params[count++], case_block->id);
@@ -8300,7 +8469,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_
break;
case TERMINATOR_RET:
- sm6_parser_add_instruction(sm6, VKD3DSIH_RET);
+ sm6_parser_add_instruction(sm6, VSIR_OP_RET);
break;
default:
@@ -8322,7 +8491,7 @@ static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser
src_phi = &block->phi[i];
incoming_count = src_phi->incoming_count;
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_PHI);
+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_PHI);
if (!(src_params = instruction_src_params_alloc(ins, incoming_count * 2u, sm6)))
return;
if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6)))
@@ -8342,7 +8511,7 @@ static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser
}
dst_param_init(dst_param);
- dst_param->reg = src_phi->reg;
+ sm6_register_from_value(&dst_param->reg, &src_phi->value, sm6);
}
}
@@ -8408,7 +8577,7 @@ static void sm6_parser_emit_label(struct sm6_parser *sm6, unsigned int label_id)
struct vkd3d_shader_src_param *src_param;
struct vkd3d_shader_instruction *ins;
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_LABEL);
+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_LABEL);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
@@ -8738,6 +8907,7 @@ static const enum vkd3d_shader_sysval_semantic sysval_semantic_table[] =
[SEMANTIC_KIND_INSTANCEID] = VKD3D_SHADER_SV_INSTANCE_ID,
[SEMANTIC_KIND_POSITION] = VKD3D_SHADER_SV_POSITION,
[SEMANTIC_KIND_RTARRAYINDEX] = VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX,
+ [SEMANTIC_KIND_VIEWPORTARRAYINDEX] = VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX,
[SEMANTIC_KIND_CLIPDISTANCE] = VKD3D_SHADER_SV_CLIP_DISTANCE,
[SEMANTIC_KIND_CULLDISTANCE] = VKD3D_SHADER_SV_CULL_DISTANCE,
[SEMANTIC_KIND_PRIMITIVEID] = VKD3D_SHADER_SV_PRIMITIVE_ID,
@@ -8876,40 +9046,39 @@ static enum vkd3d_shader_resource_type shader_resource_type_from_dxil_resource_k
}
}
-static const enum vkd3d_data_type data_type_table[] =
-{
- [COMPONENT_TYPE_INVALID] = VKD3D_DATA_UNUSED,
- [COMPONENT_TYPE_I1] = VKD3D_DATA_UNUSED,
- [COMPONENT_TYPE_I16] = VKD3D_DATA_INT,
- [COMPONENT_TYPE_U16] = VKD3D_DATA_UINT,
- [COMPONENT_TYPE_I32] = VKD3D_DATA_INT,
- [COMPONENT_TYPE_U32] = VKD3D_DATA_UINT,
- [COMPONENT_TYPE_I64] = VKD3D_DATA_UNUSED,
- [COMPONENT_TYPE_U64] = VKD3D_DATA_UNUSED,
- [COMPONENT_TYPE_F16] = VKD3D_DATA_FLOAT,
- [COMPONENT_TYPE_F32] = VKD3D_DATA_FLOAT,
- [COMPONENT_TYPE_F64] = VKD3D_DATA_DOUBLE,
- [COMPONENT_TYPE_SNORMF16] = VKD3D_DATA_SNORM,
- [COMPONENT_TYPE_UNORMF16] = VKD3D_DATA_UNORM,
- [COMPONENT_TYPE_SNORMF32] = VKD3D_DATA_SNORM,
- [COMPONENT_TYPE_UNORMF32] = VKD3D_DATA_UNORM,
- [COMPONENT_TYPE_SNORMF64] = VKD3D_DATA_DOUBLE,
- [COMPONENT_TYPE_UNORMF64] = VKD3D_DATA_DOUBLE,
- [COMPONENT_TYPE_PACKEDS8X32] = VKD3D_DATA_UNUSED,
- [COMPONENT_TYPE_PACKEDU8X32] = VKD3D_DATA_UNUSED,
+static const enum vsir_data_type data_type_table[] =
+{
+ [COMPONENT_TYPE_INVALID] = VSIR_DATA_UNUSED,
+ [COMPONENT_TYPE_I1] = VSIR_DATA_UNUSED,
+ [COMPONENT_TYPE_I16] = VSIR_DATA_I32,
+ [COMPONENT_TYPE_U16] = VSIR_DATA_U32,
+ [COMPONENT_TYPE_I32] = VSIR_DATA_I32,
+ [COMPONENT_TYPE_U32] = VSIR_DATA_U32,
+ [COMPONENT_TYPE_I64] = VSIR_DATA_UNUSED,
+ [COMPONENT_TYPE_U64] = VSIR_DATA_UNUSED,
+ [COMPONENT_TYPE_F16] = VSIR_DATA_F32,
+ [COMPONENT_TYPE_F32] = VSIR_DATA_F32,
+ [COMPONENT_TYPE_F64] = VSIR_DATA_F64,
+ [COMPONENT_TYPE_SNORMF16] = VSIR_DATA_SNORM,
+ [COMPONENT_TYPE_UNORMF16] = VSIR_DATA_UNORM,
+ [COMPONENT_TYPE_SNORMF32] = VSIR_DATA_SNORM,
+ [COMPONENT_TYPE_UNORMF32] = VSIR_DATA_UNORM,
+ [COMPONENT_TYPE_SNORMF64] = VSIR_DATA_F64,
+ [COMPONENT_TYPE_UNORMF64] = VSIR_DATA_F64,
+ [COMPONENT_TYPE_PACKEDS8X32] = VSIR_DATA_UNUSED,
+ [COMPONENT_TYPE_PACKEDU8X32] = VSIR_DATA_UNUSED,
};
-static enum vkd3d_data_type vkd3d_data_type_from_dxil_component_type(enum dxil_component_type type,
+static enum vsir_data_type vsir_data_type_from_dxil_component_type(enum dxil_component_type type,
struct sm6_parser *sm6)
{
- enum vkd3d_data_type data_type;
+ enum vsir_data_type data_type;
- if (type >= ARRAY_SIZE(data_type_table) || (data_type = data_type_table[type]) == VKD3D_DATA_UNUSED)
+ if (type >= ARRAY_SIZE(data_type_table) || (data_type = data_type_table[type]) == VSIR_DATA_UNUSED)
{
- FIXME("Unhandled component type %u.\n", type);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
"Resource descriptor component type %u is unhandled.", type);
- return VKD3D_DATA_FLOAT;
+ return VSIR_DATA_F32;
}
return data_type;
@@ -8917,7 +9086,7 @@ static enum vkd3d_data_type vkd3d_data_type_from_dxil_component_type(enum dxil_c
struct resource_additional_values
{
- enum vkd3d_data_type data_type;
+ enum vsir_data_type data_type;
unsigned int byte_stride;
};
@@ -8926,7 +9095,7 @@ static bool resources_load_additional_values(struct resource_additional_values *
{
unsigned int i, operand_count, tag, value;
- info->data_type = VKD3D_DATA_UNUSED;
+ info->data_type = VSIR_DATA_UNUSED;
info->byte_stride = 0;
if (node->operand_count & 1)
@@ -8958,7 +9127,7 @@ static bool resources_load_additional_values(struct resource_additional_values *
"An untyped resource has type %u.", value);
return false;
}
- info->data_type = vkd3d_data_type_from_dxil_component_type(value, sm6);
+ info->data_type = vsir_data_type_from_dxil_component_type(value, sm6);
break;
case RESOURCE_TAG_ELEMENT_STRIDE:
@@ -9018,7 +9187,7 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc
if (!m)
{
- ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW;
+ ins->opcode = is_uav ? VSIR_OP_DCL_UAV_RAW : VSIR_OP_DCL_RESOURCE_RAW;
ins->declaration.raw_resource.resource.reg.write_mask = 0;
return &ins->declaration.raw_resource.resource;
}
@@ -9036,14 +9205,13 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc
if (kind == RESOURCE_KIND_TYPEDBUFFER || resource_kind_is_texture(kind))
{
- if (resource_values.data_type == VKD3D_DATA_UNUSED)
+ if (resource_values.data_type == VSIR_DATA_UNUSED)
{
- WARN("No data type defined.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
"A typed resource has no data type.");
}
- ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_TYPED : VKD3DSIH_DCL;
+ ins->opcode = is_uav ? VSIR_OP_DCL_UAV_TYPED : VSIR_OP_DCL;
for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
ins->declaration.semantic.resource_data_type[i] = resource_values.data_type;
ins->declaration.semantic.resource_type = resource_type;
@@ -9053,14 +9221,14 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc
}
else if (kind == RESOURCE_KIND_RAWBUFFER)
{
- ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW;
+ ins->opcode = is_uav ? VSIR_OP_DCL_UAV_RAW : VSIR_OP_DCL_RESOURCE_RAW;
ins->declaration.raw_resource.resource.reg.write_mask = 0;
return &ins->declaration.raw_resource.resource;
}
else if (kind == RESOURCE_KIND_STRUCTUREDBUFFER)
{
- ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_STRUCTURED : VKD3DSIH_DCL_RESOURCE_STRUCTURED;
+ ins->opcode = is_uav ? VSIR_OP_DCL_UAV_STRUCTURED : VSIR_OP_DCL_RESOURCE_STRUCTURED;
ins->declaration.structured_resource.byte_stride = resource_values.byte_stride;
ins->declaration.structured_resource.resource.reg.write_mask = 0;
@@ -9086,8 +9254,8 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc
}
static void init_resource_declaration(struct vkd3d_shader_resource *resource,
- enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int id,
- const struct vkd3d_shader_register_range *range)
+ enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type,
+ unsigned int id, const struct vkd3d_shader_register_range *range)
{
struct vkd3d_shader_dst_param *param = &resource->reg;
@@ -9129,7 +9297,7 @@ static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6,
return VKD3D_ERROR_INVALID_SHADER;
}
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_INVALID);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_INVALID);
if (!(resource = sm6_parser_resources_load_common_info(sm6, node->operands[1], false, kind,
node->operands[8], ins)))
@@ -9140,9 +9308,9 @@ static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6,
d->resource_type = ins->resource_type;
d->kind = kind;
d->reg_type = VKD3DSPR_RESOURCE;
- d->reg_data_type = VKD3D_DATA_UNUSED;
- d->resource_data_type = (ins->opcode == VKD3DSIH_DCL)
- ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED;
+ d->reg_data_type = VSIR_DATA_UNUSED;
+ d->resource_data_type = (ins->opcode == VSIR_OP_DCL)
+ ? ins->declaration.semantic.resource_data_type[0] : VSIR_DATA_UNUSED;
init_resource_declaration(resource, VKD3DSPR_RESOURCE, d->reg_data_type, d->id, &d->range);
@@ -9197,7 +9365,7 @@ static enum vkd3d_result sm6_parser_resources_load_uav(struct sm6_parser *sm6,
}
}
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_INVALID);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_INVALID);
if (values[1])
ins->flags = VKD3DSUF_GLOBALLY_COHERENT;
if (values[2])
@@ -9214,9 +9382,9 @@ static enum vkd3d_result sm6_parser_resources_load_uav(struct sm6_parser *sm6,
d->resource_type = ins->resource_type;
d->kind = values[0];
d->reg_type = VKD3DSPR_UAV;
- d->reg_data_type = VKD3D_DATA_UNUSED;
- d->resource_data_type = (ins->opcode == VKD3DSIH_DCL_UAV_TYPED)
- ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED;
+ d->reg_data_type = VSIR_DATA_UNUSED;
+ d->resource_data_type = (ins->opcode == VSIR_OP_DCL_UAV_TYPED)
+ ? ins->declaration.semantic.resource_data_type[0] : VSIR_DATA_UNUSED;
init_resource_declaration(resource, VKD3DSPR_UAV, d->reg_data_type, d->id, &d->range);
@@ -9251,14 +9419,14 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6,
return VKD3D_ERROR_INVALID_SHADER;
}
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_CONSTANT_BUFFER);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DCL_CONSTANT_BUFFER);
ins->resource_type = VKD3D_SHADER_RESOURCE_BUFFER;
ins->declaration.cb.size = buffer_size;
ins->declaration.cb.src.swizzle = VKD3D_SHADER_NO_SWIZZLE;
ins->declaration.cb.src.modifiers = VKD3DSPSM_NONE;
reg = &ins->declaration.cb.src.reg;
- vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3);
+ vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VSIR_DATA_F32, 3);
reg->idx[0].offset = d->id;
reg->idx[1].offset = d->range.first;
reg->idx[2].offset = d->range.last;
@@ -9266,8 +9434,8 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6,
ins->declaration.cb.range = d->range;
d->reg_type = VKD3DSPR_CONSTBUFFER;
- d->reg_data_type = VKD3D_DATA_FLOAT;
- d->resource_data_type = VKD3D_DATA_FLOAT;
+ d->reg_data_type = VSIR_DATA_F32;
+ d->resource_data_type = VSIR_DATA_F32;
return VKD3D_OK;
}
@@ -9292,7 +9460,7 @@ static enum vkd3d_result sm6_parser_resources_load_sampler(struct sm6_parser *sm
"Ignoring %u extra operands for a sampler descriptor.", node->operand_count - 7);
}
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_SAMPLER);
+ vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DCL_SAMPLER);
ins->resource_type = VKD3D_SHADER_RESOURCE_NONE;
if (!sm6_metadata_get_uint_value(sm6, node->operands[6], &kind))
@@ -9320,7 +9488,7 @@ static enum vkd3d_result sm6_parser_resources_load_sampler(struct sm6_parser *sm
ins->declaration.sampler.src.modifiers = VKD3DSPSM_NONE;
reg = &ins->declaration.sampler.src.reg;
- vsir_register_init(reg, VKD3DSPR_SAMPLER, VKD3D_DATA_UNUSED, 3);
+ vsir_register_init(reg, VKD3DSPR_SAMPLER, VSIR_DATA_UNUSED, 3);
reg->idx[0].offset = d->id;
reg->idx[1].offset = d->range.first;
reg->idx[2].offset = d->range.last;
@@ -9330,8 +9498,8 @@ static enum vkd3d_result sm6_parser_resources_load_sampler(struct sm6_parser *sm
d->resource_type = ins->resource_type;
d->kind = RESOURCE_KIND_SAMPLER;
d->reg_type = VKD3DSPR_SAMPLER;
- d->reg_data_type = VKD3D_DATA_UNUSED;
- d->resource_data_type = VKD3D_DATA_UNUSED;
+ d->reg_data_type = VSIR_DATA_UNUSED;
+ d->resource_data_type = VSIR_DATA_UNUSED;
return VKD3D_OK;
}
@@ -9660,7 +9828,9 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const
if ((is_register = e->register_index == UINT_MAX))
{
- if (register_type_from_dxil_semantic_kind(e->sysval_semantic, is_input) == VKD3DSPR_INVALID)
+ enum vsir_dimension dimension;
+
+ if (register_type_from_dxil_semantic_kind(e->sysval_semantic, is_input, &dimension) == VKD3DSPR_INVALID)
{
WARN("Unhandled I/O register semantic kind %u.\n", j);
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
@@ -9813,7 +9983,7 @@ static void sm6_parser_emit_global_flags(struct sm6_parser *sm6, const struct sm
rotated_flags = (rotated_flags >> 1) | ((rotated_flags & 1) << 4);
global_flags = (global_flags & ~mask) | rotated_flags;
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_GLOBAL_FLAGS);
+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_GLOBAL_FLAGS);
ins->declaration.global_flags = global_flags;
sm6->p.program->global_flags = global_flags;
}
@@ -9870,7 +10040,7 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co
}
}
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_THREAD_GROUP);
+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_THREAD_GROUP);
ins->declaration.thread_group_size.x = group_sizes[0];
ins->declaration.thread_group_size.y = group_sizes[1];
ins->declaration.thread_group_size.z = group_sizes[2];
@@ -9910,7 +10080,7 @@ static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6,
"Domain shader tessellator domain %u is unhandled.", tessellator_domain);
}
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TESSELLATOR_DOMAIN);
+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_DOMAIN);
ins->declaration.tessellator_domain = tessellator_domain;
sm6->p.program->tess_domain = tessellator_domain;
}
@@ -9938,7 +10108,7 @@ static void sm6_parser_emit_dcl_tessellator_partitioning(struct sm6_parser *sm6,
"Hull shader tessellator partitioning %u is unhandled.", tessellator_partitioning);
}
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TESSELLATOR_PARTITIONING);
+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_PARTITIONING);
ins->declaration.tessellator_partitioning = tessellator_partitioning;
sm6->p.program->tess_partitioning = tessellator_partitioning;
@@ -9956,7 +10126,7 @@ static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser *
"Hull shader tessellator output primitive %u is unhandled.", primitive);
}
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE);
+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE);
ins->declaration.tessellator_output_primitive = primitive;
sm6->p.program->tess_output_primitive = primitive;
@@ -9983,7 +10153,7 @@ static void sm6_parser_emit_dcl_max_tessellation_factor(struct sm6_parser *sm6,
"Hull shader max tessellation factor %f is invalid.", max_tessellation_factor);
}
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_HS_MAX_TESSFACTOR);
+ ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_HS_MAX_TESSFACTOR);
ins->declaration.max_tessellation_factor = max_tessellation_factor;
}
@@ -10070,7 +10240,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s
break;
}
- sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_DCL_INPUT_PRIMITIVE, input_primitive, patch_vertex_count);
+ sm6_parser_emit_dcl_primitive_topology(sm6, VSIR_OP_DCL_INPUT_PRIMITIVE, input_primitive, patch_vertex_count);
sm6->p.program->input_primitive = input_primitive;
sm6->p.program->input_control_point_count = input_control_point_count;
@@ -10082,7 +10252,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
"Geometry shader output vertex count %u is invalid.", i);
}
- sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_VERTICES_OUT, i);
+ sm6_parser_emit_dcl_count(sm6, VSIR_OP_DCL_VERTICES_OUT, i);
sm6->p.program->vertices_out_count = i;
if (operands[2] > 1)
@@ -10100,7 +10270,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s
"Geometry shader output primitive %u is unhandled.", output_primitive);
output_primitive = VKD3D_PT_TRIANGLELIST;
}
- sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_DCL_OUTPUT_TOPOLOGY, output_primitive, 0);
+ sm6_parser_emit_dcl_primitive_topology(sm6, VSIR_OP_DCL_OUTPUT_TOPOLOGY, output_primitive, 0);
sm6->p.program->output_topology = output_primitive;
i = operands[4];
@@ -10110,7 +10280,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
"Geometry shader instance count %u is invalid.", i);
}
- sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_GS_INSTANCES, i);
+ sm6_parser_emit_dcl_count(sm6, VSIR_OP_DCL_GS_INSTANCES, i);
}
static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_parser *sm6,
@@ -10217,7 +10387,7 @@ static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_pa
sm6_parser_validate_control_point_count(sm6, operands[1], false, "Hull shader input");
program->input_control_point_count = operands[1];
sm6_parser_validate_control_point_count(sm6, operands[2], false, "Hull shader output");
- sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, operands[2]);
+ sm6_parser_emit_dcl_count(sm6, VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, operands[2]);
program->output_control_point_count = operands[2];
sm6_parser_emit_dcl_tessellator_domain(sm6, operands[3]);
sm6_parser_emit_dcl_tessellator_partitioning(sm6, operands[4]);
@@ -10742,7 +10912,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro
if (version.type == VKD3D_SHADER_TYPE_HULL)
{
- sm6_parser_add_instruction(sm6, VKD3DSIH_HS_CONTROL_POINT_PHASE);
+ sm6_parser_add_instruction(sm6, VSIR_OP_HS_CONTROL_POINT_PHASE);
if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
goto fail;
@@ -10757,7 +10927,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro
goto fail;
}
- sm6_parser_add_instruction(sm6, VKD3DSIH_HS_FORK_PHASE);
+ sm6_parser_add_instruction(sm6, VSIR_OP_HS_FORK_PHASE);
if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
goto fail;
diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c
index a4f1a371299..5b776108c95 100644
--- a/libs/vkd3d/libs/vkd3d-shader/fx.c
+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c
@@ -20,6 +20,8 @@
#include "hlsl.h"
+#define TAG_FX20 0x46580200
+
static inline size_t put_u32_unaligned(struct vkd3d_bytecode_buffer *buffer, uint32_t value)
{
return bytecode_put_bytes_unaligned(buffer, &value, sizeof(value));
@@ -54,6 +56,22 @@ enum state_property_component_type
FX_COMPONENT_TYPE_COUNT,
};
+enum fxlvm_constants
+{
+ FX_FXLC_COMP_COUNT_MASK = 0xffff,
+ FX_FXLC_OPCODE_MASK = 0x7ff,
+ FX_FXLC_OPCODE_SHIFT = 20,
+ FX_FXLC_IS_SCALAR_MASK = 0x80000000,
+
+ FX_FXLC_REG_UNUSED = 0,
+ FX_FXLC_REG_LITERAL = 1,
+ FX_FXLC_REG_CB = 2,
+ FX_FXLC_REG_INPUT = 3,
+ FX_FXLC_REG_OUTPUT = 4,
+ FX_FXLC_REG_TEMP = 7,
+ FX_FXLC_REG_MAX = FX_FXLC_REG_TEMP,
+};
+
struct rhs_named_value
{
const char *name;
@@ -237,6 +255,8 @@ struct fx_write_context_ops
void (*write_technique)(struct hlsl_ir_var *var, struct fx_write_context *fx);
void (*write_pass)(struct hlsl_ir_var *var, struct fx_write_context *fx);
void (*write_annotation)(struct hlsl_ir_var *var, struct fx_write_context *fx);
+ void (*write_state_assignment)(const struct hlsl_ir_var *var,
+ struct hlsl_state_block_entry *entry, struct fx_write_context *fx);
bool are_child_effects_supported;
};
@@ -289,15 +309,6 @@ static void set_status(struct fx_write_context *fx, int status)
fx->status = status;
}
-static void fx_print_string(struct vkd3d_string_buffer *buffer, const char *prefix,
- const char *s, size_t len)
-{
- if (len)
- --len; /* Trim terminating null. */
- vkd3d_string_buffer_printf(buffer, "%s", prefix);
- vkd3d_string_buffer_print_string_escaped(buffer, s, len);
-}
-
static uint32_t write_string(const char *string, struct fx_write_context *fx)
{
return fx->ops->write_string(string, fx);
@@ -308,6 +319,15 @@ static void write_pass(struct hlsl_ir_var *var, struct fx_write_context *fx)
fx->ops->write_pass(var, fx);
}
+static void write_state_assignment(const struct hlsl_ir_var *var,
+ struct hlsl_state_block_entry *entry, struct fx_write_context *fx)
+{
+ fx->ops->write_state_assignment(var, entry, fx);
+}
+
+static uint32_t write_state_block(struct hlsl_ir_var *var,
+ unsigned int block_index, struct fx_write_context *fx);
+
static uint32_t write_annotations(struct hlsl_scope *scope, struct fx_write_context *fx)
{
struct hlsl_ctx *ctx = fx->ctx;
@@ -343,8 +363,6 @@ static void write_fx_4_annotations(struct hlsl_scope *scope, struct fx_write_con
static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_context *fx);
static const char * get_fx_4_type_name(const struct hlsl_type *type);
static void write_fx_4_annotation(struct hlsl_ir_var *var, struct fx_write_context *fx);
-static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_index,
- uint32_t count_offset, struct fx_write_context *fx);
static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context *fx)
{
@@ -369,18 +387,23 @@ static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context
name = get_fx_4_type_name(element_type);
modifiers = element_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK;
- LIST_FOR_EACH_ENTRY(type_entry, &fx->types, struct type_entry, entry)
+ /* We don't try to reuse nameless types; they will get the same
+ * "<unnamed>" name, but are not available for the type cache. */
+ if (name)
{
- if (strcmp(type_entry->name, name))
- continue;
+ LIST_FOR_EACH_ENTRY(type_entry, &fx->types, struct type_entry, entry)
+ {
+ if (strcmp(type_entry->name, name))
+ continue;
- if (type_entry->elements_count != elements_count)
- continue;
+ if (type_entry->elements_count != elements_count)
+ continue;
- if (type_entry->modifiers != modifiers)
- continue;
+ if (type_entry->modifiers != modifiers)
+ continue;
- return type_entry->offset;
+ return type_entry->offset;
+ }
}
if (!(type_entry = hlsl_alloc(fx->ctx, sizeof(*type_entry))))
@@ -391,7 +414,8 @@ static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context
type_entry->elements_count = elements_count;
type_entry->modifiers = modifiers;
- list_add_tail(&fx->types, &type_entry->entry);
+ if (name)
+ list_add_tail(&fx->types, &type_entry->entry);
return type_entry->offset;
}
@@ -491,17 +515,22 @@ static uint32_t write_fx_4_string(const char *string, struct fx_write_context *f
return string_entry->offset;
}
+static void fx_4_decompose_state_blocks(struct hlsl_ir_var *var, struct fx_write_context *fx);
+
static void write_fx_4_pass(struct hlsl_ir_var *var, struct fx_write_context *fx)
{
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
- uint32_t name_offset, count_offset;
+ uint32_t name_offset, count_offset, count;
name_offset = write_string(var->name, fx);
put_u32(buffer, name_offset);
count_offset = put_u32(buffer, 0);
+ fx_4_decompose_state_blocks(var, fx);
+
write_fx_4_annotations(var->annotations, fx);
- write_fx_4_state_block(var, 0, count_offset, fx);
+ count = write_state_block(var, 0, fx);
+ set_u32(buffer, count_offset, count);
}
static void write_fx_2_annotations(struct hlsl_ir_var *var, uint32_t count_offset, struct fx_write_context *fx)
@@ -764,208 +793,227 @@ static const struct rhs_named_value fx_2_filter_values[] =
{ NULL }
};
-static const struct fx_2_state
+struct fx_state
{
const char *name;
+ enum hlsl_type_class container;
enum hlsl_type_class class;
enum state_property_component_type type;
unsigned int dimx;
uint32_t array_size;
uint32_t id;
const struct rhs_named_value *values;
-}
-fx_2_states[] =
-{
- { "ZEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 0, fx_2_zenable_values },
- { "FillMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 1, fx_2_fillmode_values },
- { "ShadeMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 2, fx_2_shademode_values },
- { "ZWriteEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 3 },
- { "AlphaTestEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 4 },
- { "LastPixel", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 5 },
- { "SrcBlend", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 6, fx_2_blendmode_values },
- { "DestBlend", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 7, fx_2_blendmode_values },
- { "CullMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 8, fx_2_cullmode_values },
- { "ZFunc", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9, fx_2_cmpfunc_values },
- { "AlphaRef", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 10 },
- { "AlphaFunc", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 11, fx_2_cmpfunc_values },
- { "DitherEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 12 },
- { "AlphaBlendEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 13 },
- { "FogEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 14 },
- { "SpecularEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 15 },
- { "FogColor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 16 },
- { "FogTableMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 17, fx_2_fogmode_values },
- { "FogStart", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 18 },
- { "FogEnd", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 19 },
- { "FogDensity", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 20 },
- { "RangeFogEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 21 },
- { "StencilEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 22 },
- { "StencilFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 23, fx_2_stencilcaps_values },
- { "StencilZFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 24, fx_2_stencilcaps_values },
- { "StencilPass", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 25, fx_2_stencilcaps_values },
- { "StencilFunc", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 26, fx_2_cmpfunc_values },
- { "StencilRef", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 27 },
- { "StencilMask", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 28 },
- { "StencilWriteMask", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 29 },
- { "TextureFactor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 30 },
- { "Wrap0", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 31, fx_2_wrap_values },
- { "Wrap1", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 32, fx_2_wrap_values },
- { "Wrap2", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 33, fx_2_wrap_values },
- { "Wrap3", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 34, fx_2_wrap_values },
- { "Wrap4", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 35, fx_2_wrap_values },
- { "Wrap5", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 36, fx_2_wrap_values },
- { "Wrap6", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 37, fx_2_wrap_values },
- { "Wrap7", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 38, fx_2_wrap_values },
- { "Wrap8", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 39, fx_2_wrap_values },
- { "Wrap9", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 40, fx_2_wrap_values },
- { "Wrap10", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 41, fx_2_wrap_values },
- { "Wrap11", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 42, fx_2_wrap_values },
- { "Wrap12", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 43, fx_2_wrap_values },
- { "Wrap13", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 44, fx_2_wrap_values },
- { "Wrap14", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 45, fx_2_wrap_values },
- { "Wrap15", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 46, fx_2_wrap_values },
- { "Clipping", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 47 },
- { "Lighting", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 48 },
- { "Ambient", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 49 },
- { "FogVertexMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 50, fx_2_fogmode_values },
- { "ColorVertex", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 51 },
- { "LocalViewer", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 52 },
- { "NormalizeNormals", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 53 },
-
- { "DiffuseMaterialSource", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 54, fx_2_materialcolorsource_values },
- { "SpecularMaterialSource", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 55, fx_2_materialcolorsource_values },
- { "AmbientMaterialSource", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 56, fx_2_materialcolorsource_values },
- { "EmissiveMaterialSource", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 57, fx_2_materialcolorsource_values },
-
- { "VertexBlend", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 58, fx_2_vertexblend_values },
- { "ClipPlaneEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 59, fx_2_clipplane_values },
- { "PointSize", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 60 },
- { "PointSize_Min", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 61 },
- { "PointSize_Max", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 62 },
- { "PointSpriteEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 63 },
- { "PointScaleEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 64 },
- { "PointScale_A", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 65 },
- { "PointScale_B", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 66 },
- { "PointScale_C", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 67 },
-
- { "MultiSampleAntialias", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 68 },
- { "MultiSampleMask", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 69 },
- { "PatchEdgeStyle", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 70, fx_2_patchedgestyle_values },
- { "DebugMonitorToken", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 71 },
- { "IndexedVertexBlendEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 72 },
- { "ColorWriteEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 73, fx_2_colorwriteenable_values },
- { "TweenFactor", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 74 },
- { "BlendOp", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 75, fx_2_blendop_values },
- { "PositionDegree", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 76, fx_2_degree_values },
- { "NormalDegree", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 77, fx_2_degree_values },
- { "ScissorTestEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 78 },
- { "SlopeScaleDepthBias", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 79 },
-
- { "AntialiasedLineEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 80 },
- { "MinTessellationLevel", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 81 },
- { "MaxTessellationLevel", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 82 },
- { "AdaptiveTess_X", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 83 },
- { "AdaptiveTess_Y", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 84 },
- { "AdaptiveTess_Z", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 85 },
- { "AdaptiveTess_W", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 86 },
- { "EnableAdaptiveTesselation", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 87 },
- { "TwoSidedStencilMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 88 },
- { "StencilFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 89, fx_2_stencilcaps_values },
- { "StencilZFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 90, fx_2_stencilcaps_values },
- { "StencilPass", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 91, fx_2_stencilcaps_values },
- { "StencilFunc", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 92, fx_2_cmpfunc_values },
-
- { "ColorWriteEnable1", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 93, fx_2_colorwriteenable_values },
- { "ColorWriteEnable2", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 94, fx_2_colorwriteenable_values },
- { "ColorWriteEnable3", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 95, fx_2_colorwriteenable_values },
- { "BlendFactor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 96 },
- { "SRGBWriteEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 97 },
- { "DepthBias", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 98 },
- { "SeparateAlphaBlendEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 99 },
- { "SrcBlendAlpha", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 100, fx_2_blendmode_values },
- { "DestBlendAlpha", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 101, fx_2_blendmode_values },
- { "BlendOpAlpha", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 102, fx_2_blendmode_values },
-
- { "ColorOp", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 103, fx_2_textureop_values },
- { "ColorArg0", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 104, fx_2_colorarg_values },
- { "ColorArg1", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 105, fx_2_colorarg_values },
- { "ColorArg2", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 106, fx_2_colorarg_values },
- { "AlphaOp", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 107, fx_2_textureop_values },
- { "AlphaArg0", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 108, fx_2_colorarg_values },
- { "AlphaArg1", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 109, fx_2_colorarg_values },
- { "AlphaArg2", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 110, fx_2_colorarg_values },
- { "ResultArg", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 111, fx_2_colorarg_values },
- { "BumpEnvMat00", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 112 },
- { "BumpEnvMat01", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 113 },
- { "BumpEnvMat10", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 114 },
- { "BumpEnvMat11", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 115 },
- { "TextCoordIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 116 },
- { "BumpEnvLScale", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 117 },
- { "BumpEnvLOffset", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 118 },
- { "TextureTransformFlags", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 119, fx_2_texturetransform_values },
- { "Constant", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 120 },
- { "NPatchMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 121 },
- { "FVF", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 122 },
-
- { "ProjectionTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 123 },
- { "ViewTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 124 },
- { "WorldTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 125 },
- { "TextureTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 8, 126 },
-
- { "MaterialAmbient", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 127 },
- { "MaterialDiffuse", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 128 },
- { "MaterialSpecular", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 129 },
- { "MaterialEmissive", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 130 },
- { "MaterialPower", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 131 },
-
- { "LightType", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 132, fx_2_lighttype_values },
- { "LightDiffuse", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 133 },
- { "LightSpecular", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 134 },
- { "LightAmbient", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 135 },
- { "LightPosition", HLSL_CLASS_VECTOR, FX_FLOAT, 3, 1, 136 },
- { "LightDirection", HLSL_CLASS_VECTOR, FX_FLOAT, 3, 1, 137 },
- { "LightRange", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 138 },
- { "LightFalloff", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 139 },
- { "LightAttenuation0", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 140 },
- { "LightAttenuation1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 141 },
- { "LightAttenuation2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 142 },
- { "LightTheta", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 143 },
- { "LightPhi", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 144 },
- { "LightEnable", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 145 },
-
- { "VertexShader", HLSL_CLASS_SCALAR, FX_VERTEXSHADER, 1, 1, 146 },
- { "PixelShader", HLSL_CLASS_SCALAR, FX_PIXELSHADER, 1, 1, 147 },
-
- { "VertexShaderConstantF", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 148 },
- { "VertexShaderConstantB", HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u-1, 149 },
- { "VertexShaderConstantI", HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u-1, 150 },
- { "VertexShaderConstant", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 151 },
- { "VertexShaderConstant1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 152 },
- { "VertexShaderConstant2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 153 },
- { "VertexShaderConstant3", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 154 },
- { "VertexShaderConstant4", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 155 },
-
- { "PixelShaderConstantF", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 156 },
- { "PixelShaderConstantB", HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u-1, 157 },
- { "PixelShaderConstantI", HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u-1, 158 },
- { "PixelShaderConstant", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 159 },
- { "PixelShaderConstant1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 160 },
- { "PixelShaderConstant2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 161 },
- { "PixelShaderConstant3", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 162 },
- { "PixelShaderConstant4", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 163 },
-
- { "Texture", HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 164 },
- { "AddressU", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 165, fx_2_address_values },
- { "AddressV", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 166, fx_2_address_values },
- { "AddressW", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 167, fx_2_address_values },
- { "BorderColor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 168 },
- { "MagFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 169, fx_2_filter_values },
- { "MinFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 170, fx_2_filter_values },
- { "MipFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 171, fx_2_filter_values },
- { "MipMapLodBias", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 172 },
- { "MaxMipLevel", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 173 },
- { "MaxAnisotropy", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 174 },
- { "SRBTexture", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 175 },
- { "ElementIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 176 },
+};
+
+static const struct fx_state fx_2_pass_states[] =
+{
+ { "ZEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 0, fx_2_zenable_values },
+ { "FillMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 1, fx_2_fillmode_values },
+ { "ShadeMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 2, fx_2_shademode_values },
+ { "ZWriteEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 3 },
+ { "AlphaTestEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 4 },
+ { "LastPixel", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 5 },
+ { "SrcBlend", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 6, fx_2_blendmode_values },
+ { "DestBlend", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 7, fx_2_blendmode_values },
+ { "CullMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 8, fx_2_cullmode_values },
+ { "ZFunc", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9, fx_2_cmpfunc_values },
+ { "AlphaRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 10 },
+ { "AlphaFunc", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 11, fx_2_cmpfunc_values },
+ { "DitherEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 12 },
+ { "AlphaBlendEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 13 },
+ { "FogEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 14 },
+ { "SpecularEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 15 },
+ { "FogColor", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 16 },
+ { "FogTableMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 17, fx_2_fogmode_values },
+ { "FogStart", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 18 },
+ { "FogEnd", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 19 },
+ { "FogDensity", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 20 },
+ { "RangeFogEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 21 },
+ { "StencilEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 22 },
+ { "StencilFail", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 23, fx_2_stencilcaps_values },
+ { "StencilZFail", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 24, fx_2_stencilcaps_values },
+ { "StencilPass", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 25, fx_2_stencilcaps_values },
+ { "StencilFunc", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 26, fx_2_cmpfunc_values },
+ { "StencilRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 27 },
+ { "StencilMask", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 28 },
+ { "StencilWriteMask", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 29 },
+ { "TextureFactor", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 30 },
+ { "Wrap0", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 31, fx_2_wrap_values },
+ { "Wrap1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 32, fx_2_wrap_values },
+ { "Wrap2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 33, fx_2_wrap_values },
+ { "Wrap3", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 34, fx_2_wrap_values },
+ { "Wrap4", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 35, fx_2_wrap_values },
+ { "Wrap5", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 36, fx_2_wrap_values },
+ { "Wrap6", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 37, fx_2_wrap_values },
+ { "Wrap7", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 38, fx_2_wrap_values },
+ { "Wrap8", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 39, fx_2_wrap_values },
+ { "Wrap9", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 40, fx_2_wrap_values },
+ { "Wrap10", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 41, fx_2_wrap_values },
+ { "Wrap11", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 42, fx_2_wrap_values },
+ { "Wrap12", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 43, fx_2_wrap_values },
+ { "Wrap13", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 44, fx_2_wrap_values },
+ { "Wrap14", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 45, fx_2_wrap_values },
+ { "Wrap15", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 46, fx_2_wrap_values },
+ { "Clipping", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 47 },
+ { "Lighting", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 48 },
+ { "Ambient", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 49 },
+ { "FogVertexMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 50, fx_2_fogmode_values },
+ { "ColorVertex", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 51 },
+ { "LocalViewer", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 52 },
+ { "NormalizeNormals", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 53 },
+
+ { "DiffuseMaterialSource", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 54, fx_2_materialcolorsource_values },
+ { "SpecularMaterialSource", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 55, fx_2_materialcolorsource_values },
+ { "AmbientMaterialSource", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 56, fx_2_materialcolorsource_values },
+ { "EmissiveMaterialSource", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 57, fx_2_materialcolorsource_values },
+
+ { "VertexBlend", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 58, fx_2_vertexblend_values },
+ { "ClipPlaneEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 59, fx_2_clipplane_values },
+ { "PointSize", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 60 },
+ { "PointSize_Min", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 61 },
+ { "PointSize_Max", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 62 },
+ { "PointSpriteEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 63 },
+ { "PointScaleEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 64 },
+ { "PointScale_A", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 65 },
+ { "PointScale_B", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 66 },
+ { "PointScale_C", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 67 },
+
+ { "MultiSampleAntialias", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 68 },
+ { "MultiSampleMask", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 69 },
+ { "PatchEdgeStyle", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 70, fx_2_patchedgestyle_values },
+ { "DebugMonitorToken", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 71 },
+ { "IndexedVertexBlendEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 72 },
+ { "ColorWriteEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 73, fx_2_colorwriteenable_values },
+ { "TweenFactor", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 74 },
+ { "BlendOp", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 75, fx_2_blendop_values },
+ { "PositionDegree", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 76, fx_2_degree_values },
+ { "NormalDegree", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 77, fx_2_degree_values },
+ { "ScissorTestEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 78 },
+ { "SlopeScaleDepthBias", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 79 },
+
+ { "AntialiasedLineEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 80 },
+ { "MinTessellationLevel", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 81 },
+ { "MaxTessellationLevel", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 82 },
+ { "AdaptiveTess_X", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 83 },
+ { "AdaptiveTess_Y", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 84 },
+ { "AdaptiveTess_Z", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 85 },
+ { "AdaptiveTess_W", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 86 },
+ { "EnableAdaptiveTessellation",HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 87 },
+ { "TwoSidedStencilMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 88 },
+ { "StencilFail", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 89, fx_2_stencilcaps_values },
+ { "StencilZFail", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 90, fx_2_stencilcaps_values },
+ { "StencilPass", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 91, fx_2_stencilcaps_values },
+ { "StencilFunc", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 92, fx_2_cmpfunc_values },
+
+ { "ColorWriteEnable1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 93, fx_2_colorwriteenable_values },
+ { "ColorWriteEnable2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 94, fx_2_colorwriteenable_values },
+ { "ColorWriteEnable3", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 95, fx_2_colorwriteenable_values },
+ { "BlendFactor", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 96 },
+ { "SRGBWriteEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 97 },
+ { "DepthBias", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 98 },
+ { "SeparateAlphaBlendEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 99 },
+ { "SrcBlendAlpha", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 100, fx_2_blendmode_values },
+ { "DestBlendAlpha", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 101, fx_2_blendmode_values },
+ { "BlendOpAlpha", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 102, fx_2_blendmode_values },
+
+ { "ColorOp", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 103, fx_2_textureop_values },
+ { "ColorArg0", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 104, fx_2_colorarg_values },
+ { "ColorArg1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 105, fx_2_colorarg_values },
+ { "ColorArg2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 106, fx_2_colorarg_values },
+ { "AlphaOp", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 107, fx_2_textureop_values },
+ { "AlphaArg0", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 108, fx_2_colorarg_values },
+ { "AlphaArg1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 109, fx_2_colorarg_values },
+ { "AlphaArg2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 110, fx_2_colorarg_values },
+ { "ResultArg", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 111, fx_2_colorarg_values },
+ { "BumpEnvMat00", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 112 },
+ { "BumpEnvMat01", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 113 },
+ { "BumpEnvMat10", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 114 },
+ { "BumpEnvMat11", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 115 },
+ { "TexCoordIndex", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 116 },
+ { "BumpEnvLScale", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 117 },
+ { "BumpEnvLOffset", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 118 },
+ { "TextureTransformFlags", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 119, fx_2_texturetransform_values },
+ { "Constant", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 120 },
+ { "PatchSegments", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 121 },
+ { "FVF", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 122 },
+
+ { "ProjectionTransform", HLSL_CLASS_PASS, HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 123 },
+ { "ViewTransform", HLSL_CLASS_PASS, HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 124 },
+ { "WorldTransform", HLSL_CLASS_PASS, HLSL_CLASS_MATRIX, FX_FLOAT, 4, 256, 125 },
+ { "TextureTransform", HLSL_CLASS_PASS, HLSL_CLASS_MATRIX, FX_FLOAT, 4, 8, 126 },
+
+ { "MaterialDiffuse", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 127 },
+ { "MaterialAmbient", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 128 },
+ { "MaterialSpecular", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 129 },
+ { "MaterialEmissive", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 130 },
+ { "MaterialPower", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 131 },
+
+ { "LightType", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u, 132, fx_2_lighttype_values },
+ { "LightDiffuse", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, ~0u, 133 },
+ { "LightSpecular", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, ~0u, 134 },
+ { "LightAmbient", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, ~0u, 135 },
+ { "LightPosition", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 3, ~0u, 136 },
+ { "LightDirection", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 3, ~0u, 137 },
+ { "LightRange", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 138 },
+ { "LightFalloff", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 139 },
+ { "LightAttenuation0", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 140 },
+ { "LightAttenuation1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 141 },
+ { "LightAttenuation2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 142 },
+ { "LightTheta", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 143 },
+ { "LightPhi", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 144 },
+ { "LightEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 145 },
+
+ { "VertexShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_VERTEXSHADER, 1, 1, 146 },
+ { "PixelShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_PIXELSHADER, 1, 1, 147 },
+
+ { "VertexShaderConstantF", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 148 },
+ { "VertexShaderConstantB", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u, 149 },
+ { "VertexShaderConstantI", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u, 150 },
+ { "VertexShaderConstant", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 151 },
+ { "VertexShaderConstant1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 152 },
+ { "VertexShaderConstant2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 153 },
+ { "VertexShaderConstant3", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 154 },
+ { "VertexShaderConstant4", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 155 },
+
+ { "PixelShaderConstantF", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 156 },
+ { "PixelShaderConstantB", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u, 157 },
+ { "PixelShaderConstantI", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u, 158 },
+ { "PixelShaderConstant", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 159 },
+ { "PixelShaderConstant1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 160 },
+ { "PixelShaderConstant2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 161 },
+ { "PixelShaderConstant3", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 162 },
+ { "PixelShaderConstant4", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 163 },
+
+ { "Texture", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 261, 164 },
+ { "AddressU", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 165, fx_2_address_values },
+ { "AddressV", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 166, fx_2_address_values },
+ { "AddressW", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 167, fx_2_address_values },
+ { "BorderColor", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 168 },
+ { "MagFilter", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 169, fx_2_filter_values },
+ { "MinFilter", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 170, fx_2_filter_values },
+ { "MipFilter", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 171, fx_2_filter_values },
+ { "MipMapLodBias", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 172 },
+ { "MaxMipLevel", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 173 },
+ { "MaxAnisotropy", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 174 },
+ { "SRGBTexture", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 175 },
+ { "ElementIndex", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 176 },
+};
+
+static const struct fx_state fx_2_sampler_states[] =
+{
+ { "Texture", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 164 },
+ { "AddressU", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 165, fx_2_address_values },
+ { "AddressV", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 166, fx_2_address_values },
+ { "AddressW", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 167, fx_2_address_values },
+ { "BorderColor", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 168 },
+ { "MagFilter", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 169, fx_2_filter_values },
+ { "MinFilter", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 170, fx_2_filter_values },
+ { "MipFilter", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 171, fx_2_filter_values },
+ { "MipMapLodBias", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 172 },
+ { "MaxMipLevel", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 173 },
+ { "MaxAnisotropy", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 174 },
+ { "SRGBTexture", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 175 },
+ { "ElementIndex", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 176 },
};
static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx)
@@ -988,16 +1036,6 @@ static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx
fx->shader_count++;
}
-static uint32_t get_fx_4_type_size(const struct hlsl_type *type)
-{
- uint32_t elements_count;
-
- elements_count = hlsl_get_multiarray_size(type);
- type = hlsl_get_multiarray_element_type(type);
-
- return type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float) * elements_count;
-}
-
enum fx_4_type_constants
{
/* Numeric types encoding */
@@ -1015,6 +1053,9 @@ enum fx_4_type_constants
FX_4_NUMERIC_COLUMNS_SHIFT = 11,
FX_4_NUMERIC_COLUMN_MAJOR_MASK = 0x4000,
+ /* Variable flags */
+ FX_4_HAS_EXPLICIT_BIND_POINT = 0x4,
+
/* Object types */
FX_4_OBJECT_TYPE_STRING = 0x1,
FX_4_OBJECT_TYPE_BLEND_STATE = 0x2,
@@ -1071,17 +1112,6 @@ enum fx_4_type_constants
FX_4_ASSIGNMENT_VALUE_EXPRESSION = 0x6,
FX_4_ASSIGNMENT_INLINE_SHADER = 0x7,
FX_5_ASSIGNMENT_INLINE_SHADER = 0x8,
-
- /* FXLVM constants */
- FX_4_FXLC_COMP_COUNT_MASK = 0xffff,
- FX_4_FXLC_OPCODE_MASK = 0x7ff,
- FX_4_FXLC_OPCODE_SHIFT = 20,
- FX_4_FXLC_IS_SCALAR_MASK = 0x80000000,
-
- FX_4_FXLC_REG_LITERAL = 1,
- FX_4_FXLC_REG_CB = 2,
- FX_4_FXLC_REG_OUTPUT = 4,
- FX_4_FXLC_REG_TEMP = 7,
};
static const uint32_t fx_4_numeric_base_types[] =
@@ -1238,7 +1268,7 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
name = get_fx_4_type_name(element_type);
- name_offset = write_string(name, fx);
+ name_offset = write_string(name ? name : "<unnamed>", fx);
if (element_type->class == HLSL_CLASS_STRUCT)
{
if (!(field_offsets = hlsl_calloc(ctx, element_type->e.record.field_count, sizeof(*field_offsets))))
@@ -1541,12 +1571,33 @@ static uint32_t get_fx_2_type_class(const struct hlsl_type *type)
return hlsl_sm1_class(type);
}
-static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *name,
- const struct hlsl_semantic *semantic, bool is_combined_sampler, struct fx_write_context *fx)
+struct fx_2_write_type_context
{
- struct vkd3d_bytecode_buffer *buffer = &fx->unstructured;
- uint32_t semantic_offset, offset, elements_count = 0, name_offset;
- size_t i;
+ uint32_t *names;
+ uint32_t *semantics;
+ uint32_t count;
+
+ uint32_t offset;
+
+ bool is_combined_sampler;
+ struct fx_write_context *fx;
+};
+
+static void count_type_iter(const struct hlsl_type *type, const char *name,
+ const struct hlsl_semantic *semantic, void *context)
+{
+ struct fx_2_write_type_context *ctx = context;
+
+ ++ctx->count;
+}
+
+static void write_fx_2_type_iter(const struct hlsl_type *type, const char *name,
+ const struct hlsl_semantic *semantic, void *context)
+{
+ struct fx_2_write_type_context *ctx = context;
+ struct fx_write_context *fx = ctx->fx;
+ struct vkd3d_bytecode_buffer *buffer;
+ uint32_t offset, elements_count = 0;
/* Resolve arrays to element type and number of elements. */
if (type->class == HLSL_CLASS_ARRAY)
@@ -1555,13 +1606,11 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n
type = hlsl_get_multiarray_element_type(type);
}
- name_offset = write_string(name, fx);
- semantic_offset = semantic->raw_name ? write_string(semantic->raw_name, fx) : 0;
-
- offset = put_u32(buffer, hlsl_sm1_base_type(type, is_combined_sampler));
+ buffer = &fx->unstructured;
+ offset = put_u32(buffer, hlsl_sm1_base_type(type, ctx->is_combined_sampler));
put_u32(buffer, get_fx_2_type_class(type));
- put_u32(buffer, name_offset);
- put_u32(buffer, semantic_offset);
+ *ctx->names++ = put_u32(buffer, 0);
+ *ctx->semantics++ = put_u32(buffer, 0);
put_u32(buffer, elements_count);
switch (type->class)
@@ -1586,19 +1635,68 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n
;
}
+ /* Save the offset of the top level type. */
+ if (!ctx->offset)
+ ctx->offset = offset;
+}
+
+static void write_fx_2_type_strings_iter(const struct hlsl_type *type, const char *name,
+ const struct hlsl_semantic *semantic, void *context)
+{
+ struct fx_2_write_type_context *ctx = context;
+ struct fx_write_context *fx = ctx->fx;
+ struct vkd3d_bytecode_buffer *buffer;
+
+ buffer = &fx->unstructured;
+ set_u32(buffer, *ctx->names++, write_string(name, fx));
+ set_u32(buffer, *ctx->semantics++, semantic->raw_name ? write_string(semantic->raw_name, fx) : 0);
+}
+
+static void foreach_type(const struct hlsl_type *type, const char *name, const struct hlsl_semantic *semantic,
+ void (*iter_func)(const struct hlsl_type *type, const char *name, const struct hlsl_semantic *semantic, void *context),
+ void *context)
+{
+ iter_func(type, name, semantic, context);
+
+ type = hlsl_get_multiarray_element_type(type);
if (type->class == HLSL_CLASS_STRUCT)
{
- for (i = 0; i < type->e.record.field_count; ++i)
+ for (size_t i = 0; i < type->e.record.field_count; ++i)
{
const struct hlsl_struct_field *field = &type->e.record.fields[i];
-
- /* Validated in check_invalid_object_fields(). */
- VKD3D_ASSERT(hlsl_is_numeric_type(field->type));
- write_fx_2_parameter(field->type, field->name, &field->semantic, false, fx);
+ foreach_type(field->type, field->name, &field->semantic, iter_func, context);
}
}
+}
- return offset;
+static uint32_t write_fx_2_parameter(const struct hlsl_ir_var *var, struct fx_write_context *fx)
+{
+ struct fx_2_write_type_context ctx = { .fx = fx, .is_combined_sampler = var->is_combined_sampler };
+ uint32_t *offsets;
+
+ /* Parameter type information has to be stored in a contiguous segment, so
+ * that any structure fields come right after each other. To achieve that
+ * the variable length string data is written after the type data. */
+
+ /* Calculate the number of string entries needed for this type. */
+ foreach_type(var->data_type, var->name, &var->semantic, count_type_iter, &ctx);
+
+ if (!(offsets = calloc(ctx.count, 2 * sizeof(*offsets))))
+ return 0;
+
+ /* Writing type information also sets string offsets. */
+ ctx.names = offsets;
+ ctx.semantics = &offsets[ctx.count];
+ foreach_type(var->data_type, var->name, &var->semantic, write_fx_2_type_iter, &ctx);
+
+ /* Now the final pass to write the string data. */
+ ctx.names = offsets;
+ ctx.semantics = &offsets[ctx.count];
+ foreach_type(var->data_type, var->name, &var->semantic, write_fx_2_type_strings_iter, &ctx);
+
+ free(offsets);
+
+ return ctx.offset;
}
static void write_fx_2_technique(struct hlsl_ir_var *var, struct fx_write_context *fx)
@@ -1623,6 +1721,15 @@ static void write_fx_2_technique(struct hlsl_ir_var *var, struct fx_write_contex
set_u32(buffer, pass_count_offset, count);
}
+/* Effects represent bool values as 1/0, as opposed to ~0u/0 as used by
+ * Direct3D shader model 4+. */
+static uint32_t get_fx_default_numeric_value(const struct hlsl_type *type, uint32_t value)
+{
+ if (type->e.numeric.type == HLSL_TYPE_BOOL)
+ return !!value;
+ return value;
+}
+
static uint32_t write_fx_2_default_value(struct hlsl_type *value_type, struct hlsl_default_value *value,
struct fx_write_context *fx)
{
@@ -1656,7 +1763,7 @@ static uint32_t write_fx_2_default_value(struct hlsl_type *value_type, struct hl
for (j = 0; j < comp_count; ++j)
{
- put_u32(buffer, value->number.u);
+ put_u32(buffer, get_fx_default_numeric_value(type, value->number.u));
value++;
}
break;
@@ -1673,8 +1780,8 @@ static uint32_t write_fx_2_default_value(struct hlsl_type *value_type, struct hl
for (j = 0; j < type->e.record.field_count; ++j)
{
- write_fx_2_default_value(fields[i].type, value, fx);
- value += hlsl_type_component_count(fields[i].type);
+ write_fx_2_default_value(fields[j].type, value, fx);
+ value += hlsl_type_component_count(fields[j].type);
}
break;
}
@@ -1861,7 +1968,7 @@ static void write_fx_2_parameters(struct fx_write_context *fx)
if (!is_type_supported_fx_2(ctx, var->data_type, &var->loc))
continue;
- desc_offset = write_fx_2_parameter(var->data_type, var->name, &var->semantic, var->is_combined_sampler, fx);
+ desc_offset = write_fx_2_parameter(var, fx);
value_offset = write_fx_2_initial_value(var, fx);
flags = 0;
@@ -1884,19 +1991,28 @@ static void write_fx_2_annotation(struct hlsl_ir_var *var, struct fx_write_conte
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
uint32_t desc_offset, value_offset;
- desc_offset = write_fx_2_parameter(var->data_type, var->name, &var->semantic, var->is_combined_sampler, fx);
+ desc_offset = write_fx_2_parameter(var, fx);
value_offset = write_fx_2_initial_value(var, fx);
put_u32(buffer, desc_offset);
put_u32(buffer, value_offset);
}
+static void write_fx_2_state_assignment(const struct hlsl_ir_var *var,
+ struct hlsl_state_block_entry *entry, struct fx_write_context *fx)
+{
+ struct hlsl_ctx *ctx = fx->ctx;
+
+ hlsl_fixme(ctx, &var->loc, "Writing fx_2_0 state assignments is not implemented.");
+}
+
static const struct fx_write_context_ops fx_2_ops =
{
.write_string = write_fx_2_string,
.write_technique = write_fx_2_technique,
.write_pass = write_fx_2_pass,
.write_annotation = write_fx_2_annotation,
+ .write_state_assignment = write_fx_2_state_assignment,
};
static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
@@ -1959,12 +2075,16 @@ static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
return fx_write_context_cleanup(&fx);
}
+static void write_fx_4_state_assignment(const struct hlsl_ir_var *var,
+ struct hlsl_state_block_entry *entry, struct fx_write_context *fx);
+
static const struct fx_write_context_ops fx_4_ops =
{
.write_string = write_fx_4_string,
.write_technique = write_fx_4_technique,
.write_pass = write_fx_4_pass,
.write_annotation = write_fx_4_annotation,
+ .write_state_assignment = write_fx_4_state_assignment,
.are_child_effects_supported = true,
};
@@ -2001,7 +2121,7 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl
for (j = 0; j < comp_count; ++j)
{
- put_u32_unaligned(buffer, value->number.u);
+ put_u32_unaligned(buffer, get_fx_default_numeric_value(type, value->number.u));
value++;
}
break;
@@ -2018,8 +2138,8 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl
for (j = 0; j < type->e.record.field_count; ++j)
{
- write_fx_4_default_value(fields[i].type, value, fx);
- value += hlsl_type_component_count(fields[i].type);
+ write_fx_4_default_value(fields[j].type, value, fx);
+ value += hlsl_type_component_count(fields[j].type);
}
break;
}
@@ -2057,13 +2177,9 @@ static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, st
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
uint32_t name_offset, type_offset, value_offset;
uint32_t semantic_offset, flags = 0;
- enum fx_4_numeric_variable_flags
- {
- HAS_EXPLICIT_BIND_POINT = 0x4,
- };
if (var->has_explicit_bind_point)
- flags |= HAS_EXPLICIT_BIND_POINT;
+ flags |= FX_4_HAS_EXPLICIT_BIND_POINT;
type_offset = write_type(var->data_type, fx);
name_offset = write_string(var->name, fx);
@@ -2163,7 +2279,7 @@ static uint32_t write_fx_4_state_numeric_value(struct hlsl_ir_constant *value, s
}
put_u32_unaligned(buffer, type);
- put_u32_unaligned(buffer, value->value.u[i].u);
+ put_u32_unaligned(buffer, get_fx_default_numeric_value(data_type, value->value.u[i].u));
}
return offset;
@@ -2576,18 +2692,7 @@ static const struct rhs_named_value null_values[] =
{ NULL }
};
-static const struct fx_4_state
-{
- const char *name;
- enum hlsl_type_class container;
- enum hlsl_type_class class;
- enum state_property_component_type type;
- unsigned int dimx;
- unsigned int array_size;
- int id;
- const struct rhs_named_value *values;
-}
-fx_4_states[] =
+static const struct fx_state fx_4_states[] =
{
{ "RasterizerState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RASTERIZER, 1, 1, 0 },
{ "DepthStencilState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCIL, 1, 1, 1 },
@@ -2655,7 +2760,7 @@ fx_4_states[] =
{ "ComputeShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_COMPUTESHADER, 1, 1, 58 },
};
-static const struct fx_4_state fx_5_blend_states[] =
+static const struct fx_state fx_5_blend_states[] =
{
{ "AlphaToCoverageEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 36, bool_values },
{ "BlendEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 8, 37, bool_values },
@@ -2668,45 +2773,61 @@ static const struct fx_4_state fx_5_blend_states[] =
{ "RenderTargetWriteMask", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 8, 44 },
};
-struct fx_4_state_table
+struct fx_state_table
{
- const struct fx_4_state *ptr;
+ const struct fx_state *ptr;
unsigned int count;
};
-static struct fx_4_state_table fx_4_get_state_table(enum hlsl_type_class type_class,
+static struct fx_state_table fx_get_state_table(enum hlsl_type_class type_class,
unsigned int major, unsigned int minor)
{
- struct fx_4_state_table table;
+ struct fx_state_table table;
- if (type_class == HLSL_CLASS_BLEND_STATE && (major == 5 || (major == 4 && minor == 1)))
+ if (major == 2)
{
- table.ptr = fx_5_blend_states;
- table.count = ARRAY_SIZE(fx_5_blend_states);
+ if (type_class == HLSL_CLASS_PASS)
+ {
+ table.ptr = fx_2_pass_states;
+ table.count = ARRAY_SIZE(fx_2_pass_states);
+ }
+ else
+ {
+ table.ptr = fx_2_sampler_states;
+ table.count = ARRAY_SIZE(fx_2_sampler_states);
+ }
}
else
{
- table.ptr = fx_4_states;
- table.count = ARRAY_SIZE(fx_4_states);
+ if (type_class == HLSL_CLASS_BLEND_STATE && (major == 5 || (major == 4 && minor == 1)))
+ {
+ table.ptr = fx_5_blend_states;
+ table.count = ARRAY_SIZE(fx_5_blend_states);
+ }
+ else
+ {
+ table.ptr = fx_4_states;
+ table.count = ARRAY_SIZE(fx_4_states);
+ }
}
return table;
}
-static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var,
+static void resolve_fx_state_block_values(struct hlsl_ir_var *var,
struct hlsl_state_block_entry *entry, struct fx_write_context *fx)
{
const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type);
struct replace_state_context replace_context;
- const struct fx_4_state *state = NULL;
+ const struct fx_state *state = NULL;
struct hlsl_type *state_type = NULL;
struct hlsl_ctx *ctx = fx->ctx;
enum hlsl_base_type base_type;
- struct fx_4_state_table table;
+ struct fx_state_table table;
struct hlsl_ir_node *node;
unsigned int i;
- table = fx_4_get_state_table(type->class, ctx->profile->major_version, ctx->profile->minor_version);
+ table = fx_get_state_table(type->class, ctx->profile->major_version, ctx->profile->minor_version);
for (i = 0; i < table.count; ++i)
{
@@ -2992,21 +3113,34 @@ static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct h
return decompose_fx_4_state_block_expand_array(var, block, entry_index, fx);
}
-static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_index,
- uint32_t count_offset, struct fx_write_context *fx)
+static void fx_4_decompose_state_blocks(struct hlsl_ir_var *var, struct fx_write_context *fx)
{
- struct vkd3d_bytecode_buffer *buffer = &fx->structured;
+ unsigned int block_count = hlsl_get_multiarray_size(var->data_type);
struct hlsl_state_block *block;
- uint32_t i, count = 0;
- if (var->state_blocks)
+ if (!var->state_blocks)
+ return;
+
+ for (unsigned int i = 0; i < block_count; ++i)
{
- block = var->state_blocks[block_index];
+ block = var->state_blocks[i];
- for (i = 0; i < block->count;)
+ for (unsigned int j = 0; j < block->count;)
{
- i += decompose_fx_4_state_block(var, block, i, fx);
+ j += decompose_fx_4_state_block(var, block, j, fx);
}
+ }
+}
+
+static uint32_t write_state_block(struct hlsl_ir_var *var, unsigned int block_index,
+ struct fx_write_context *fx)
+{
+ struct hlsl_state_block *block;
+ uint32_t i, count = 0;
+
+ if (var->state_blocks)
+ {
+ block = var->state_blocks[block_index];
for (i = 0; i < block->count; ++i)
{
@@ -3017,27 +3151,29 @@ static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_i
continue;
/* Resolve special constant names and property names. */
- resolve_fx_4_state_block_values(var, entry, fx);
+ resolve_fx_state_block_values(var, entry, fx);
- write_fx_4_state_assignment(var, entry, fx);
+ write_state_assignment(var, entry, fx);
++count;
}
}
- set_u32(buffer, count_offset, count);
+ return count;
}
static void write_fx_4_state_object_initializer(struct hlsl_ir_var *var, struct fx_write_context *fx)
{
uint32_t elements_count = hlsl_get_multiarray_size(var->data_type), i;
struct vkd3d_bytecode_buffer *buffer = &fx->structured;
- uint32_t count_offset;
+ uint32_t count_offset, count;
+
+ fx_4_decompose_state_blocks(var, fx);
for (i = 0; i < elements_count; ++i)
{
count_offset = put_u32(buffer, 0);
-
- write_fx_4_state_block(var, i, count_offset, fx);
+ count = write_state_block(var, i, fx);
+ set_u32(buffer, count_offset, count);
}
}
@@ -3212,6 +3348,8 @@ static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx
size = 0;
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
+ uint32_t unpacked_size;
+
if (!is_numeric_fx_4_type(var->data_type))
continue;
@@ -3219,7 +3357,9 @@ static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx
continue;
write_fx_4_numeric_variable(var, shared, fx);
- size += get_fx_4_type_size(var->data_type);
+
+ unpacked_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float);
+ size = max(size, unpacked_size + var->buffer_offset * 4);
++count;
}
@@ -3446,6 +3586,7 @@ int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
struct fx_parser
{
+ enum vkd3d_shader_source_type source_type;
const uint8_t *ptr, *start, *end;
struct vkd3d_shader_message_context *message_context;
struct vkd3d_string_buffer buffer;
@@ -3572,20 +3713,43 @@ static void parse_fx_print_indent(struct fx_parser *parser)
vkd3d_string_buffer_printf(&parser->buffer, "%*s", 4 * parser->indent, "");
}
-static const char *fx_2_get_string(struct fx_parser *parser, uint32_t offset, uint32_t *size)
+static void fx_2_print_string_literal(struct fx_parser *parser, const char *prefix,
+ const char *s, uint32_t max_len, const char *suffix)
{
- const char *ptr;
+ uint32_t len;
- fx_parser_read_unstructured(parser, size, offset, sizeof(*size));
- ptr = fx_parser_get_unstructured_ptr(parser, offset + 4, *size);
+ if (s)
+ len = strnlen(s, max_len);
+ if (!s || len == max_len)
+ {
+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, "Failed to parse a string entry.");
+ return;
+ }
- if (!ptr)
+ vkd3d_string_buffer_printf(&parser->buffer, "%s", prefix);
+ vkd3d_string_buffer_print_string_escaped(&parser->buffer, s, len);
+ vkd3d_string_buffer_printf(&parser->buffer, "%s", suffix);
+}
+
+static void fx_2_parse_string_literal(struct fx_parser *parser, uint32_t offset,
+ bool unstructured, const char *prefix, const char *suffix)
+{
+ uint32_t max_len;
+ const char *s;
+
+ if (unstructured)
{
- parser->failed = true;
- return "<invalid>";
+ fx_parser_read_unstructured(parser, &max_len, offset, sizeof(max_len));
+ s = fx_parser_get_unstructured_ptr(parser, offset + 4, max_len);
+ }
+ else
+ {
+ max_len = fx_parser_read_u32(parser);
+ s = fx_parser_get_ptr(parser, max_len);
+ fx_parser_skip(parser, align(max_len, 4));
}
- return ptr;
+ fx_2_print_string_literal(parser, prefix, s, max_len, suffix);
}
static unsigned int fx_get_fx_2_type_size(struct fx_parser *parser, uint32_t *offset)
@@ -3742,15 +3906,12 @@ static void fx_parse_fx_2_parameter(struct fx_parser *parser, uint32_t offset)
uint32_t semantic;
uint32_t element_count;
} var;
- const char *name;
- uint32_t size;
fx_parser_read_unstructured(parser, &var, offset, sizeof(var));
fx_parse_fx_2_type(parser, offset);
- name = fx_2_get_string(parser, var.name, &size);
- fx_print_string(&parser->buffer, " ", name, size);
+ fx_2_parse_string_literal(parser, var.name, true, " ", "");
if (var.element_count)
vkd3d_string_buffer_printf(&parser->buffer, "[%u]", var.element_count);
}
@@ -3764,7 +3925,8 @@ static bool is_fx_2_sampler(uint32_t type)
|| type == D3DXPT_SAMPLERCUBE;
}
-static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_assignment *entry);
+static void fx_parse_fx_2_assignment(struct fx_parser *parser, enum hlsl_type_class container,
+ const struct fx_assignment *entry);
static void parse_fx_2_sampler(struct fx_parser *parser, uint32_t element_count,
uint32_t offset)
@@ -3789,7 +3951,7 @@ static void parse_fx_2_sampler(struct fx_parser *parser, uint32_t element_count,
fx_parser_read_unstructured(parser, &entry, offset, sizeof(entry));
parse_fx_print_indent(parser);
- fx_parse_fx_2_assignment(parser, &entry);
+ fx_parse_fx_2_assignment(parser, HLSL_CLASS_SAMPLER, &entry);
}
parse_fx_end_indent(parser);
parse_fx_print_indent(parser);
@@ -3867,15 +4029,25 @@ static void fx_parse_fx_2_annotations(struct fx_parser *parser, uint32_t count)
vkd3d_string_buffer_printf(&parser->buffer, ">");
}
-static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_assignment *entry)
+static const struct fx_state *fx_2_get_state_by_id(enum hlsl_type_class container, uint32_t id)
+{
+ struct fx_state_table table = fx_get_state_table(container, 2, 0);
+
+ /* State identifiers are sequential, no gaps */
+ if (id >= table.ptr[0].id && id <= table.ptr[table.count - 1].id)
+ return &table.ptr[id - table.ptr[0].id];
+
+ return NULL;
+}
+
+static void fx_parse_fx_2_assignment(struct fx_parser *parser, enum hlsl_type_class container,
+ const struct fx_assignment *entry)
{
const struct rhs_named_value *named_value = NULL;
- const struct fx_2_state *state = NULL;
+ const struct fx_state *state;
- if (entry->id <= ARRAY_SIZE(fx_2_states))
+ if ((state = fx_2_get_state_by_id(container, entry->id)))
{
- state = &fx_2_states[entry->id];
-
vkd3d_string_buffer_printf(&parser->buffer, "%s", state->name);
if (state->array_size > 1)
vkd3d_string_buffer_printf(&parser->buffer, "[%u]", entry->lhs_index);
@@ -3886,7 +4058,7 @@ static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_a
}
vkd3d_string_buffer_printf(&parser->buffer, " = ");
- if (state && state->type == FX_UINT)
+ if (state && state->type == FX_UINT && state->values)
{
const struct rhs_named_value *ptr = state->values;
uint32_t value;
@@ -3910,13 +4082,14 @@ static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_a
}
else if (state)
{
- if (state->type == FX_UINT || state->type == FX_FLOAT)
+ if (state->type == FX_UINT || state->type == FX_FLOAT || state->type == FX_BOOL)
{
- uint32_t offset = entry->type;
+ uint32_t offset = entry->type, base_type;
unsigned int size;
size = fx_get_fx_2_type_size(parser, &offset);
- parse_fx_2_numeric_value(parser, entry->value, size, entry->type);
+ fx_parser_read_unstructured(parser, &base_type, entry->type, sizeof(base_type));
+ parse_fx_2_numeric_value(parser, entry->value, size, base_type);
}
else if (state->type == FX_VERTEXSHADER || state->type == FX_PIXELSHADER)
{
@@ -3951,18 +4124,14 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser)
uint32_t annotation_count;
uint32_t assignment_count;
} pass;
- const char *name;
- uint32_t size;
if (parser->failed)
return;
fx_parser_read_u32s(parser, &technique, sizeof(technique));
- name = fx_2_get_string(parser, technique.name, &size);
-
parse_fx_print_indent(parser);
- fx_print_string(&parser->buffer, "technique ", name, size);
+ fx_2_parse_string_literal(parser, technique.name, true, "technique ", "");
fx_parse_fx_2_annotations(parser, technique.annotation_count);
vkd3d_string_buffer_printf(&parser->buffer, "\n");
@@ -3973,10 +4142,9 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser)
for (uint32_t i = 0; i < technique.pass_count; ++i)
{
fx_parser_read_u32s(parser, &pass, sizeof(pass));
- name = fx_2_get_string(parser, pass.name, &size);
parse_fx_print_indent(parser);
- fx_print_string(&parser->buffer, "pass ", name, size);
+ fx_2_parse_string_literal(parser, pass.name, true, "pass ", "");
fx_parse_fx_2_annotations(parser, pass.annotation_count);
vkd3d_string_buffer_printf(&parser->buffer, "\n");
@@ -3990,7 +4158,7 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser)
parse_fx_print_indent(parser);
fx_parser_read_u32s(parser, &entry, sizeof(entry));
- fx_parse_fx_2_assignment(parser, &entry);
+ fx_parse_fx_2_assignment(parser, HLSL_CLASS_PASS, &entry);
}
parse_fx_end_indent(parser);
@@ -4112,8 +4280,7 @@ static void fx_parse_fx_2_data_blob(struct fx_parser *parser)
{
parse_fx_start_indent(parser);
parse_fx_print_indent(parser);
- fx_print_string(&parser->buffer, "\"", (const char *)data, size);
- vkd3d_string_buffer_printf(&parser->buffer, "\"");
+ fx_2_print_string_literal(parser, "\"", (const char *)data, size, "\"");
parse_fx_end_indent(parser);
}
else if (type == D3DXPT_PIXELSHADER || type == D3DXPT_VERTEXSHADER)
@@ -4135,38 +4302,18 @@ static void fx_parse_fx_2_data_blob(struct fx_parser *parser)
fx_parser_skip(parser, align(size, 4));
}
-static void fx_dump_blob(struct fx_parser *parser, const void *blob, uint32_t size)
-{
- const uint32_t *data = blob;
- unsigned int i, j, n;
+static void fx_2_parse_fxlvm_expression(struct fx_parser *parser, const uint32_t *blob, uint32_t size);
- size /= sizeof(*data);
- i = 0;
- while (i < size)
- {
- parse_fx_print_indent(parser);
- n = min(size - i, 8);
- for (j = 0; j < n; ++j)
- vkd3d_string_buffer_printf(&parser->buffer, "0x%08x,", data[i + j]);
- i += n;
- vkd3d_string_buffer_printf(&parser->buffer, "\n");
- }
-}
-
-static void fx_parse_fx_2_array_selector(struct fx_parser *parser, uint32_t size)
+static void fx_parse_fx_2_array_selector(struct fx_parser *parser)
{
- const uint8_t *end = parser->ptr + size;
- uint32_t name_size, blob_size = 0;
+ uint32_t size, blob_size = 0;
const void *blob = NULL;
- const char *name;
+ const uint8_t *end;
- name_size = fx_parser_read_u32(parser);
- name = fx_parser_get_ptr(parser, name_size);
- fx_parser_skip(parser, name_size);
+ size = fx_parser_read_u32(parser);
+ end = parser->ptr + size;
- if (!name || (uint8_t *)name >= end)
- fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA,
- "Malformed name entry in the array selector.");
+ fx_2_parse_string_literal(parser, 0, false, "array \"", "\"\n");
if (parser->ptr <= end)
{
@@ -4180,17 +4327,38 @@ static void fx_parse_fx_2_array_selector(struct fx_parser *parser, uint32_t size
"Malformed blob entry in the array selector.");
}
- if (name)
- {
- fx_print_string(&parser->buffer, "array \"", name, name_size);
- vkd3d_string_buffer_printf(&parser->buffer, "\"\n");
- }
if (blob)
{
parse_fx_print_indent(parser);
vkd3d_string_buffer_printf(&parser->buffer, "selector blob size %u\n", blob_size);
- fx_dump_blob(parser, blob, blob_size);
+ fx_2_parse_fxlvm_expression(parser, blob, blob_size);
+ }
+}
+
+static void fx_2_parse_code_blob(struct fx_parser *parser, const uint32_t *blob, uint32_t size)
+{
+ uint32_t tag;
+
+ if (size < sizeof(tag))
+ return;
+
+ tag = *blob;
+
+ if (tag == TAG_FX20)
+ {
+ fx_2_parse_fxlvm_expression(parser, blob, size);
+ return;
}
+
+ tag >>= 16;
+ if (tag == 0xfffe || tag == 0xffff)
+ {
+ fx_parse_shader_blob(parser, VKD3D_SHADER_SOURCE_D3D_BYTECODE, blob, size);
+ vkd3d_string_buffer_printf(&parser->buffer, "\n");
+ return;
+ }
+
+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, "Unrecognized code blob type, tag 0x%08x.", *blob);
}
static void fx_parse_fx_2_complex_state(struct fx_parser *parser)
@@ -4203,7 +4371,7 @@ static void fx_parse_fx_2_complex_state(struct fx_parser *parser)
uint32_t state;
uint32_t assignment_type;
} state;
- const char *data;
+ const uint32_t *data;
uint32_t size;
fx_parser_read_u32s(parser, &state, sizeof(state));
@@ -4219,28 +4387,29 @@ static void fx_parse_fx_2_complex_state(struct fx_parser *parser)
state.technique, state.index, state.state);
}
- size = fx_parser_read_u32(parser);
-
parse_fx_print_indent(parser);
if (state.assignment_type == FX_2_ASSIGNMENT_PARAMETER)
{
- data = fx_parser_get_ptr(parser, size);
- fx_print_string(&parser->buffer, "parameter \"", data, size);
- vkd3d_string_buffer_printf(&parser->buffer, "\"\n");
- fx_parser_skip(parser, align(size, 4));
+ fx_2_parse_string_literal(parser, 0, false, "parameter \"", "\"\n");
}
else if (state.assignment_type == FX_2_ASSIGNMENT_ARRAY_SELECTOR)
{
- fx_parse_fx_2_array_selector(parser, size);
+ fx_parse_fx_2_array_selector(parser);
}
- else
+ else if (state.assignment_type == FX_2_ASSIGNMENT_CODE_BLOB)
{
- vkd3d_string_buffer_printf(&parser->buffer, "blob size %u\n", size);
+ size = fx_parser_read_u32(parser);
data = fx_parser_get_ptr(parser, size);
- fx_dump_blob(parser, data, size);
+ vkd3d_string_buffer_printf(&parser->buffer, "blob size %u\n", size);
+ fx_2_parse_code_blob(parser, data, size);
fx_parser_skip(parser, align(size, 4));
}
+ else
+ {
+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA,
+ "Unknown state assignment type %u.", state.assignment_type);
+ }
}
static void fx_2_parse(struct fx_parser *parser)
@@ -4457,6 +4626,11 @@ static void fx_parse_fx_4_numeric_variables(struct fx_parser *parser, uint32_t c
semantic = fx_4_get_string(parser, var.semantic);
vkd3d_string_buffer_printf(&parser->buffer, " : %s", semantic);
}
+ if (var.flags & FX_4_HAS_EXPLICIT_BIND_POINT)
+ {
+ vkd3d_string_buffer_printf(&parser->buffer, " : packoffset(c%u.%c)",
+ var.offset / 16, "xyzw"[(var.offset % 16) / 4]);
+ }
fx_parse_fx_4_annotations(parser);
if (var.value)
@@ -4492,6 +4666,8 @@ static void fx_parse_buffers(struct fx_parser *parser)
name = fx_4_get_string(parser, buffer.name);
vkd3d_string_buffer_printf(&parser->buffer, "cbuffer %s", name);
+ if (buffer.bind_point != ~0u)
+ vkd3d_string_buffer_printf(&parser->buffer, " : register(b%u)", buffer.bind_point);
fx_parse_fx_4_annotations(parser);
vkd3d_string_buffer_printf(&parser->buffer, "\n{\n");
@@ -4598,7 +4774,7 @@ static bool fx_4_object_has_initializer(const struct fx_4_binary_type *type)
static int fx_4_state_id_compare(const void *a, const void *b)
{
- const struct fx_4_state *state = b;
+ const struct fx_state *state = b;
int id = *(int *)a;
return id - state->id;
@@ -4609,7 +4785,7 @@ static const struct
uint32_t opcode;
const char *name;
}
-fx_4_fxlc_opcodes[] =
+fxlc_opcodes[] =
{
{ 0x100, "mov" },
{ 0x101, "neg" },
@@ -4634,6 +4810,8 @@ fx_4_fxlc_opcodes[] =
{ 0x13a, "ceil" },
{ 0x200, "min" },
{ 0x201, "max" },
+ { 0x202, "lt" },
+ { 0x203, "ge" },
{ 0x204, "add" },
{ 0x205, "mul" },
{ 0x206, "atan2" },
@@ -4659,29 +4837,24 @@ fx_4_fxlc_opcodes[] =
{ 0x236, "ushr" },
{ 0x301, "movc" },
{ 0x500, "dot" },
+ { 0x502, "noise" },
{ 0x70e, "d3ds_dotswiz" },
+ { 0x711, "d3ds_noiseswiz" },
};
-static const char *fx_4_get_fxlc_opcode_name(uint32_t opcode)
+static const char *get_fxlc_opcode_name(uint32_t opcode)
{
size_t i;
- for (i = 0; i < ARRAY_SIZE(fx_4_fxlc_opcodes); ++i)
+ for (i = 0; i < ARRAY_SIZE(fxlc_opcodes); ++i)
{
- if (fx_4_fxlc_opcodes[i].opcode == opcode)
- return fx_4_fxlc_opcodes[i].name;
+ if (fxlc_opcodes[i].opcode == opcode)
+ return fxlc_opcodes[i].name;
}
return "<unrecognized>";
}
-struct fx_4_fxlc_argument
-{
- uint32_t flags;
- uint32_t reg_type;
- uint32_t address;
-};
-
struct fx_4_ctab_entry
{
uint32_t name;
@@ -4693,10 +4866,29 @@ struct fx_4_ctab_entry
uint32_t default_value;
};
+struct fxlc_arg
+{
+ uint32_t reg_type;
+ uint32_t address;
+ bool indexed;
+ struct
+ {
+ uint32_t reg_type;
+ uint32_t address;
+ } index;
+};
+
struct fxlvm_code
{
- const float *cli4;
- uint32_t cli4_count;
+ const uint32_t *ptr, *end;
+ bool failed;
+
+ union
+ {
+ const float *_4;
+ const double *_8;
+ } cli;
+ uint32_t cli_count;
const struct fx_4_ctab_entry *constants;
uint32_t ctab_offset;
@@ -4707,7 +4899,45 @@ struct fxlvm_code
bool scalar;
};
-static void fx_4_parse_print_swizzle(struct fx_parser *parser, const struct fxlvm_code *code, unsigned int addr)
+static uint32_t fxlvm_read_u32(struct fxlvm_code *code)
+{
+ if (code->end == code->ptr)
+ {
+ code->failed = true;
+ return 0;
+ }
+
+ return *code->ptr++;
+}
+
+static const uint32_t *find_d3dbc_section(const uint32_t *ptr, uint32_t count, uint32_t tag, uint32_t *size)
+{
+ if (!count)
+ return NULL;
+
+ /* Skip version tag */
+ ptr++;
+ count--;
+
+ while (count > 2 && (*ptr & 0xffff) == 0xfffe)
+ {
+ unsigned int section_size;
+
+ section_size = (*ptr >> 16);
+ if (!section_size || section_size + 1 > count)
+ break;
+ if (*(ptr + 1) == tag)
+ {
+ *size = section_size;
+ return ptr + 2;
+ }
+ count -= section_size + 1;
+ ptr += section_size + 1;
+ }
+ return NULL;
+}
+
+static void fx_parse_print_swizzle(struct fx_parser *parser, const struct fxlvm_code *code, unsigned int addr)
{
unsigned int comp_count = code->scalar ? 1 : code->comp_count;
static const char comp[] = "xyzw";
@@ -4716,44 +4946,137 @@ static void fx_4_parse_print_swizzle(struct fx_parser *parser, const struct fxlv
vkd3d_string_buffer_printf(&parser->buffer, ".%.*s", comp_count, &comp[addr % 4]);
}
-static void fx_4_parse_fxlc_constant_argument(struct fx_parser *parser,
- const struct fx_4_fxlc_argument *arg, const struct fxlvm_code *code)
+static void fx_print_fxlc_register(struct fx_parser *parser, uint32_t reg_type,
+ uint32_t address, uint32_t index_type, uint32_t index_address, struct fxlvm_code *code)
+{
+ static const char *table_names[FX_FXLC_REG_MAX + 1] =
+ {
+ [FX_FXLC_REG_LITERAL] = "imm",
+ [FX_FXLC_REG_CB] = "c",
+ [FX_FXLC_REG_INPUT] = "i",
+ [FX_FXLC_REG_OUTPUT] = "expr",
+ [FX_FXLC_REG_TEMP] = "r",
+ };
+ uint32_t reg_index = address / 4;
+
+ if (parser->source_type == VKD3D_SHADER_SOURCE_TX
+ && (reg_type == FX_FXLC_REG_INPUT || reg_type == FX_FXLC_REG_OUTPUT))
+ {
+ if (reg_type == FX_FXLC_REG_INPUT)
+ {
+ if (reg_index == 0)
+ vkd3d_string_buffer_printf(&parser->buffer, "vPos");
+ else if (reg_index == 1)
+ vkd3d_string_buffer_printf(&parser->buffer, "vPSize");
+ }
+ else
+ {
+ vkd3d_string_buffer_printf(&parser->buffer, "oC%u", reg_index);
+ }
+ }
+ else
+ {
+ vkd3d_string_buffer_printf(&parser->buffer, "%s%u", table_names[reg_type], reg_index);
+ }
+ if (index_type != FX_FXLC_REG_UNUSED)
+ {
+ vkd3d_string_buffer_printf(&parser->buffer, "[%s%u.%c]", table_names[index_type],
+ index_address / 4, "xyzw"[index_address % 4]);
+ }
+ fx_parse_print_swizzle(parser, code, address);
+}
+
+static void fx_parse_fxlc_constant_argument(struct fx_parser *parser,
+ const struct fxlc_arg *arg, const struct fxlvm_code *code)
{
- uint32_t i, offset, register_index = arg->address / 4; /* Address counts in components. */
+ uint32_t register_index = arg->address / 4; /* Address counts in components. */
- for (i = 0; i < code->ctab_count; ++i)
+ if (code->ctab_count)
{
- const struct fx_4_ctab_entry *c = &code->constants[i];
+ uint32_t i, offset;
- if (register_index < c->register_index || register_index - c->register_index >= c->register_count)
- continue;
+ for (i = 0; i < code->ctab_count; ++i)
+ {
+ const struct fx_4_ctab_entry *c = &code->constants[i];
- vkd3d_string_buffer_printf(&parser->buffer, "%s", &code->ctab[c->name]);
+ if (register_index < c->register_index || register_index - c->register_index >= c->register_count)
+ continue;
- /* Register offset within variable */
- offset = arg->address - c->register_index * 4;
+ vkd3d_string_buffer_printf(&parser->buffer, "%s", &code->ctab[c->name]);
- if (offset / 4)
- vkd3d_string_buffer_printf(&parser->buffer, "[%u]", offset / 4);
- fx_4_parse_print_swizzle(parser, code, offset);
- return;
+ /* Register offset within variable */
+ offset = arg->address - c->register_index * 4;
+
+ if (offset / 4)
+ vkd3d_string_buffer_printf(&parser->buffer, "[%u]", offset / 4);
+ fx_parse_print_swizzle(parser, code, offset);
+ return;
+ }
+
+ vkd3d_string_buffer_printf(&parser->buffer, "(var-not-found)");
+ }
+ else
+ {
+ vkd3d_string_buffer_printf(&parser->buffer, "c%u", register_index);
+ fx_parse_print_swizzle(parser, code, arg->address);
+ }
+}
+
+static void fx_parse_fxlc_argument(struct fx_parser *parser, struct fxlc_arg *arg, struct fxlvm_code *code)
+{
+ uint32_t flags;
+
+ memset(arg, 0, sizeof(*arg));
+
+ flags = fxlvm_read_u32(code);
+ if (flags)
+ {
+ arg->indexed = true;
+ arg->index.reg_type = fxlvm_read_u32(code);
+ arg->index.address = fxlvm_read_u32(code);
}
+ arg->reg_type = fxlvm_read_u32(code);
+ arg->address = fxlvm_read_u32(code);
+}
- vkd3d_string_buffer_printf(&parser->buffer, "(var-not-found)");
+static void fx_print_fxlc_literal(struct fx_parser *parser, uint32_t address, struct fxlvm_code *code)
+{
+ if (parser->version.major >= 4)
+ vkd3d_string_buffer_print_f32(&parser->buffer, code->cli._4[address]);
+ else
+ vkd3d_string_buffer_print_f64(&parser->buffer, code->cli._8[address]);
}
-static void fx_4_parse_fxlc_argument(struct fx_parser *parser, uint32_t offset, const struct fxlvm_code *code)
+static void fx_print_fxlc_argument(struct fx_parser *parser, const struct fxlc_arg *arg, struct fxlvm_code *code)
{
- struct fx_4_fxlc_argument arg;
uint32_t count;
- fx_parser_read_unstructured(parser, &arg, offset, sizeof(arg));
+ if (arg->reg_type > FX_FXLC_REG_MAX)
+ {
+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA,
+ "Unexpected register type %u.", arg->reg_type);
+ return;
+ }
- switch (arg.reg_type)
+ if (arg->index.reg_type > FX_FXLC_REG_MAX)
{
- case FX_4_FXLC_REG_LITERAL:
+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA,
+ "Unexpected index register type %u.", arg->index.reg_type);
+ return;
+ }
+
+ if (arg->indexed)
+ {
+ fx_print_fxlc_register(parser, arg->reg_type, arg->address, arg->index.reg_type,
+ arg->index.address, code);
+ return;
+ }
+
+ switch (arg->reg_type)
+ {
+ case FX_FXLC_REG_LITERAL:
count = code->scalar ? 1 : code->comp_count;
- if (arg.address >= code->cli4_count || count > code->cli4_count - arg.address)
+ if (arg->address >= code->cli_count || count > code->cli_count - arg->address)
{
vkd3d_string_buffer_printf(&parser->buffer, "(<out-of-bounds>)");
parser->failed = true;
@@ -4761,42 +5084,131 @@ static void fx_4_parse_fxlc_argument(struct fx_parser *parser, uint32_t offset,
}
vkd3d_string_buffer_printf(&parser->buffer, "(");
- vkd3d_string_buffer_print_f32(&parser->buffer, code->cli4[arg.address]);
+ fx_print_fxlc_literal(parser, arg->address, code);
for (unsigned int i = 1; i < code->comp_count; ++i)
{
vkd3d_string_buffer_printf(&parser->buffer, ", ");
- vkd3d_string_buffer_print_f32(&parser->buffer, code->cli4[arg.address + (code->scalar ? 0 : i)]);
+ fx_print_fxlc_literal(parser, arg->address + (code->scalar ? 0 : i), code);
}
vkd3d_string_buffer_printf(&parser->buffer, ")");
break;
- case FX_4_FXLC_REG_CB:
- fx_4_parse_fxlc_constant_argument(parser, &arg, code);
+ case FX_FXLC_REG_CB:
+ fx_parse_fxlc_constant_argument(parser, arg, code);
break;
- case FX_4_FXLC_REG_OUTPUT:
- case FX_4_FXLC_REG_TEMP:
- if (arg.reg_type == FX_4_FXLC_REG_OUTPUT)
- vkd3d_string_buffer_printf(&parser->buffer, "expr");
- else
- vkd3d_string_buffer_printf(&parser->buffer, "r%u", arg.address / 4);
- fx_4_parse_print_swizzle(parser, code, arg.address);
+ case FX_FXLC_REG_INPUT:
+ case FX_FXLC_REG_OUTPUT:
+ case FX_FXLC_REG_TEMP:
+ fx_print_fxlc_register(parser, arg->reg_type, arg->address, FX_FXLC_REG_UNUSED, 0, code);
break;
default:
- vkd3d_string_buffer_printf(&parser->buffer, "<unknown register %u>", arg.reg_type);
+ vkd3d_string_buffer_printf(&parser->buffer, "<unknown register %u>", arg->reg_type);
break;
}
}
+static void fx_parse_fxlvm_expression(struct fx_parser *parser, struct fxlvm_code *code)
+{
+ struct fxlc_arg args[9];
+ uint32_t ins_count;
+ size_t i, j;
+
+ parse_fx_start_indent(parser);
+ if (parser->source_type == VKD3D_SHADER_SOURCE_TX)
+ {
+ parse_fx_print_indent(parser);
+ vkd3d_string_buffer_printf(&parser->buffer, "tx_1_0\n");
+ }
+
+ ins_count = fxlvm_read_u32(code);
+
+ for (i = 0; i < ins_count; ++i)
+ {
+ uint32_t instr, opcode, src_count;
+
+ instr = fxlvm_read_u32(code);
+ src_count = fxlvm_read_u32(code);
+
+ if (src_count >= ARRAY_SIZE(args))
+ {
+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA,
+ "Unexpected instruction source count %u.", src_count);
+ break;
+ }
+
+ /* Sources entries are followed by the destination, first read them all.
+ Output format is "opcode dst, src[0]...src[n]". */
+ for (j = 0; j < src_count; ++j)
+ fx_parse_fxlc_argument(parser, &args[j], code);
+ fx_parse_fxlc_argument(parser, &args[src_count], code);
+
+ opcode = (instr >> FX_FXLC_OPCODE_SHIFT) & FX_FXLC_OPCODE_MASK;
+ code->comp_count = instr & FX_FXLC_COMP_COUNT_MASK;
+
+ parse_fx_print_indent(parser);
+ vkd3d_string_buffer_printf(&parser->buffer, "%s ", get_fxlc_opcode_name(opcode));
+
+ code->scalar = false;
+ fx_print_fxlc_argument(parser, &args[src_count], code);
+ vkd3d_string_buffer_printf(&parser->buffer, ", ");
+
+ for (j = 0; j < src_count; ++j)
+ {
+ /* Scalar modifier applies only to the first source. */
+ code->scalar = j == 0 && !!(instr & FX_FXLC_IS_SCALAR_MASK);
+ fx_print_fxlc_argument(parser, &args[j], code);
+ if (j < src_count - 1)
+ vkd3d_string_buffer_printf(&parser->buffer, ", ");
+ }
+
+ vkd3d_string_buffer_printf(&parser->buffer, "\n");
+ }
+
+ parse_fx_end_indent(parser);
+}
+
+static void fx_2_parse_fxlvm_expression(struct fx_parser *parser, const uint32_t *blob, uint32_t size)
+{
+ uint32_t count = size / sizeof(uint32_t);
+ struct fxlvm_code code = { 0 };
+ uint32_t section_size;
+ const uint32_t *data;
+
+ if (!blob)
+ return;
+
+ /* Literal constants, using 64-bit floats. */
+ if ((data = find_d3dbc_section(blob, count, TAG_CLIT, &section_size)))
+ {
+ code.cli_count = *data++;
+ code.cli._8 = (const double *)data;
+ }
+
+ /* CTAB does not contain variable names */
+
+ /* Code blob */
+ code.ptr = find_d3dbc_section(blob, count, TAG_FXLC, &count);
+ code.end = code.ptr + count;
+
+ if (!code.ptr)
+ {
+ fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, "Failed to locate expression code section.");
+ return;
+ }
+
+ fx_parse_fxlvm_expression(parser, &code);
+}
+
static void fx_4_parse_fxlvm_expression(struct fx_parser *parser, uint32_t offset)
{
struct vkd3d_shader_dxbc_section_desc *section, fxlc, cli4, ctab;
struct vkd3d_shader_dxbc_desc dxbc_desc;
+ struct fxlvm_code code = { 0 };
struct vkd3d_shader_code dxbc;
- uint32_t size, ins_count;
- struct fxlvm_code code;
- size_t i, j;
+ uint32_t size;
+ size_t i;
offset = fx_parser_read_unstructured(parser, &size, offset, sizeof(size));
@@ -4832,8 +5244,8 @@ static void fx_4_parse_fxlvm_expression(struct fx_parser *parser, uint32_t offse
{
uint32_t cli4_offset = offset + (size_t)cli4.data.code - (size_t)dxbc.code;
- fx_parser_read_unstructured(parser, &code.cli4_count, cli4_offset, sizeof(code.cli4_count));
- code.cli4 = fx_parser_get_unstructured_ptr(parser, cli4_offset + 4, code.cli4_count * sizeof(float));
+ fx_parser_read_unstructured(parser, &code.cli_count, cli4_offset, sizeof(code.cli_count));
+ code.cli._4 = fx_parser_get_unstructured_ptr(parser, cli4_offset + 4, code.cli_count * sizeof(float));
}
if (ctab.data.code)
@@ -4849,47 +5261,10 @@ static void fx_4_parse_fxlvm_expression(struct fx_parser *parser, uint32_t offse
ctab_offset + consts_offset, code.ctab_count * sizeof(*code.constants));
}
- offset += (size_t)fxlc.data.code - (size_t)dxbc.code;
- offset = fx_parser_read_unstructured(parser, &ins_count, offset, sizeof(ins_count));
-
- parse_fx_start_indent(parser);
+ code.ptr = fxlc.data.code;
+ code.end = (uint32_t *)((uint8_t *)fxlc.data.code + fxlc.data.size);
- for (i = 0; i < ins_count; ++i)
- {
- uint32_t instr, opcode, src_count;
- struct fx_4_fxlc_argument arg;
-
- offset = fx_parser_read_unstructured(parser, &instr, offset, sizeof(instr));
- offset = fx_parser_read_unstructured(parser, &src_count, offset, sizeof(src_count));
-
- opcode = (instr >> FX_4_FXLC_OPCODE_SHIFT) & FX_4_FXLC_OPCODE_MASK;
- code.comp_count = instr & FX_4_FXLC_COMP_COUNT_MASK;
- code.scalar = false;
-
- parse_fx_print_indent(parser);
- vkd3d_string_buffer_printf(&parser->buffer, "%s ", fx_4_get_fxlc_opcode_name(opcode));
-
- /* Destination first. */
- fx_4_parse_fxlc_argument(parser, offset + sizeof(arg) * src_count, &code);
-
- for (j = 0; j < src_count; ++j)
- {
- vkd3d_string_buffer_printf(&parser->buffer, ", ");
-
- /* Scalar modifier applies only to first source. */
- code.scalar = j == 0 && !!(instr & FX_4_FXLC_IS_SCALAR_MASK);
- fx_4_parse_fxlc_argument(parser, offset, &code);
-
- offset += sizeof(arg);
- }
-
- /* Destination */
- offset += sizeof(arg);
-
- vkd3d_string_buffer_printf(&parser->buffer, "\n");
- }
-
- parse_fx_end_indent(parser);
+ fx_parse_fxlvm_expression(parser, &code);
}
static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32_t count,
@@ -4919,12 +5294,12 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32
};
const struct rhs_named_value *named_value;
struct fx_5_shader shader = { 0 };
- struct fx_4_state_table table;
+ struct fx_state_table table;
unsigned int shader_type = 0;
uint32_t i, j, comp_count;
- struct fx_4_state *state;
+ struct fx_state *state;
- table = fx_4_get_state_table(type_class, parser->version.major, parser->version.minor);
+ table = fx_get_state_table(type_class, parser->version.major, parser->version.minor);
for (i = 0; i < count; ++i)
{
@@ -4995,6 +5370,8 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32
vkd3d_string_buffer_printf(&parser->buffer, "0x%.2x", value.u);
else if (state->type == FX_UINT)
vkd3d_string_buffer_printf(&parser->buffer, "%u", value.u);
+ else if (state->type == FX_BOOL)
+ vkd3d_string_buffer_printf(&parser->buffer, "%s", value.u ? "true" : "false");
else if (state->type == FX_FLOAT)
vkd3d_string_buffer_printf(&parser->buffer, "%g", value.f);
@@ -5374,6 +5751,7 @@ static void fx_parser_init(struct fx_parser *parser, const struct vkd3d_shader_c
struct vkd3d_shader_message_context *message_context)
{
memset(parser, 0, sizeof(*parser));
+ parser->source_type = compile_info->source_type;
parser->start = compile_info->source.code;
parser->ptr = compile_info->source.code;
parser->end = (uint8_t *)compile_info->source.code + compile_info->source.size;
@@ -5434,3 +5812,38 @@ int fx_parse(const struct vkd3d_shader_compile_info *compile_info,
return VKD3D_ERROR_INVALID_SHADER;
return VKD3D_OK;
}
+
+int tx_parse(const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context)
+{
+ struct fx_parser parser;
+ uint32_t version;
+
+ fx_parser_init(&parser, compile_info, message_context);
+
+ if (parser.end - parser.start < sizeof(version))
+ {
+ fx_parser_error(&parser, VKD3D_SHADER_ERROR_FX_INVALID_SIZE,
+ "Source size %zu is smaller than the TX header size.", compile_info->source.size);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ version = *(uint32_t *)parser.ptr;
+
+ switch (version)
+ {
+ case 0x54580100:
+ fx_2_parse_fxlvm_expression(&parser, (const uint32_t *)parser.ptr, parser.end - parser.ptr);
+ break;
+ default:
+ fx_parser_error(&parser, VKD3D_SHADER_ERROR_FX_INVALID_VERSION,
+ "Invalid texture shader binary version value 0x%08x.", version);
+ break;
+ }
+
+ vkd3d_shader_code_from_string_buffer(out, &parser.buffer);
+ fx_parser_cleanup(&parser);
+
+ if (parser.failed)
+ return VKD3D_ERROR_INVALID_SHADER;
+ return VKD3D_OK;
+}
diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c
index e4497b9ac5b..dfe0a40ddf0 100644
--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c
@@ -328,12 +328,12 @@ static void glsl_src_cleanup(struct glsl_src *src, struct vkd3d_string_buffer_ca
}
static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vkd3d_glsl_generator *gen,
- const char *src, enum vkd3d_data_type dst_data_type, enum vkd3d_data_type src_data_type, unsigned int size)
+ const char *src, enum vsir_data_type dst_data_type, enum vsir_data_type src_data_type, unsigned int size)
{
- if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM)
- dst_data_type = VKD3D_DATA_FLOAT;
- if (src_data_type == VKD3D_DATA_UNORM || src_data_type == VKD3D_DATA_SNORM)
- src_data_type = VKD3D_DATA_FLOAT;
+ if (dst_data_type == VSIR_DATA_UNORM || dst_data_type == VSIR_DATA_SNORM)
+ dst_data_type = VSIR_DATA_F32;
+ if (src_data_type == VSIR_DATA_UNORM || src_data_type == VSIR_DATA_SNORM)
+ src_data_type = VSIR_DATA_F32;
if (dst_data_type == src_data_type)
{
@@ -341,14 +341,14 @@ static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vk
return;
}
- if (src_data_type == VKD3D_DATA_FLOAT)
+ if (src_data_type == VSIR_DATA_F32)
{
switch (dst_data_type)
{
- case VKD3D_DATA_INT:
+ case VSIR_DATA_I32:
vkd3d_string_buffer_printf(dst, "floatBitsToInt(%s)", src);
return;
- case VKD3D_DATA_UINT:
+ case VSIR_DATA_U32:
vkd3d_string_buffer_printf(dst, "floatBitsToUint(%s)", src);
return;
default:
@@ -356,14 +356,14 @@ static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vk
}
}
- if (src_data_type == VKD3D_DATA_UINT)
+ if (src_data_type == VSIR_DATA_U32)
{
switch (dst_data_type)
{
- case VKD3D_DATA_FLOAT:
+ case VSIR_DATA_F32:
vkd3d_string_buffer_printf(dst, "uintBitsToFloat(%s)", src);
return;
- case VKD3D_DATA_INT:
+ case VSIR_DATA_I32:
if (size == 1)
vkd3d_string_buffer_printf(dst, "int(%s)", src);
else
@@ -381,11 +381,11 @@ static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vk
}
static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen,
- const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vkd3d_data_type data_type)
+ const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vsir_data_type data_type)
{
const struct vkd3d_shader_register *reg = &vsir_src->reg;
struct vkd3d_string_buffer *register_name, *str;
- enum vkd3d_data_type src_data_type;
+ enum vsir_data_type src_data_type;
unsigned int size;
register_name = vkd3d_string_buffer_get(&gen->string_buffers);
@@ -395,9 +395,9 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd
"Internal compiler error: Unhandled 'non-uniform' modifier.");
if (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_THREADID)
- src_data_type = VKD3D_DATA_UINT;
+ src_data_type = VSIR_DATA_U32;
else
- src_data_type = VKD3D_DATA_FLOAT;
+ src_data_type = VSIR_DATA_F32;
shader_glsl_print_register_name(register_name, gen, reg);
@@ -421,6 +421,9 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd
case VKD3DSPSM_ABS:
vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer);
break;
+ case VKD3DSPSM_ABSNEG:
+ vkd3d_string_buffer_printf(buffer, "-abs(%s)", str->buffer);
+ break;
default:
vkd3d_string_buffer_printf(buffer, "<unhandled modifier %#x>(%s)",
vsir_src->modifiers, str->buffer);
@@ -489,12 +492,15 @@ static void shader_glsl_print_subscript(struct vkd3d_string_buffer *buffer, stru
}
static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_glsl_generator *gen,
- struct glsl_dst *dst, enum vkd3d_data_type data_type, const char *format, va_list args)
+ struct glsl_dst *dst, enum vsir_data_type data_type, const char *format, va_list args)
{
struct vkd3d_string_buffer *buffer = gen->buffer;
uint32_t modifiers = dst->vsir->modifiers;
bool close = true;
+ /* It is always legitimate to ignore _pp. */
+ modifiers &= ~VKD3DSPDM_PARTIALPRECISION;
+
if (dst->vsir->shift)
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled destination shift %#x.", dst->vsir->shift);
@@ -513,13 +519,13 @@ static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_g
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled destination register data type %#x.", data_type);
/* fall through */
- case VKD3D_DATA_FLOAT:
+ case VSIR_DATA_F32:
close = false;
break;
- case VKD3D_DATA_INT:
+ case VSIR_DATA_I32:
vkd3d_string_buffer_printf(buffer, "intBitsToFloat(");
break;
- case VKD3D_DATA_UINT:
+ case VSIR_DATA_U32:
vkd3d_string_buffer_printf(buffer, "uintBitsToFloat(");
break;
}
@@ -544,7 +550,7 @@ static void VKD3D_PRINTF_FUNC(3, 4) shader_glsl_print_assignment(
}
static void VKD3D_PRINTF_FUNC(4, 5) shader_glsl_print_assignment_ext(struct vkd3d_glsl_generator *gen,
- struct glsl_dst *dst, enum vkd3d_data_type data_type, const char *format, ...)
+ struct glsl_dst *dst, enum vsir_data_type data_type, const char *format, ...)
{
va_list args;
@@ -555,10 +561,12 @@ static void VKD3D_PRINTF_FUNC(4, 5) shader_glsl_print_assignment_ext(struct vkd3
static void shader_glsl_unhandled(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins)
{
+ const char *name = vsir_opcode_get_name(ins->opcode, "<unknown>");
+
shader_glsl_print_indent(gen->buffer, gen->indent);
- vkd3d_string_buffer_printf(gen->buffer, "/* <unhandled instruction %#x> */\n", ins->opcode);
+ vkd3d_string_buffer_printf(gen->buffer, "/* <unhandled instruction \"%s\" (%#x)> */\n", name, ins->opcode);
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
- "Internal compiler error: Unhandled instruction %#x.", ins->opcode);
+ "Internal compiler error: Unhandled instruction \"%s\" (%#x).", name, ins->opcode);
}
static void shader_glsl_binop(struct vkd3d_glsl_generator *gen,
@@ -789,7 +797,7 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_
const struct vkd3d_shader_descriptor_info1 *d;
enum vkd3d_shader_resource_type resource_type;
struct vkd3d_string_buffer *fetch;
- enum vkd3d_data_type data_type;
+ enum vsir_data_type data_type;
struct glsl_src coord;
struct glsl_dst dst;
uint32_t coord_mask;
@@ -818,7 +826,7 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_
resource_space = 0;
resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D;
sample_count = 1;
- data_type = VKD3D_DATA_FLOAT;
+ data_type = VSIR_DATA_F32;
}
if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type)))
@@ -843,7 +851,7 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_
if (resource_type != VKD3D_SHADER_RESOURCE_BUFFER)
{
vkd3d_string_buffer_printf(fetch, ", ");
- if (ins->opcode != VKD3DSIH_LD2DMS)
+ if (ins->opcode != VSIR_OP_LD2DMS)
shader_glsl_print_src(fetch, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, ins->src[0].reg.data_type);
else if (sample_count == 1)
/* If the resource isn't a true multisample resource, this is the
@@ -904,17 +912,17 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk
enum vkd3d_shader_resource_type resource_type;
unsigned int component_idx, coord_size;
struct vkd3d_string_buffer *sample;
- enum vkd3d_data_type data_type;
+ enum vsir_data_type data_type;
struct glsl_dst dst;
- bias = ins->opcode == VKD3DSIH_SAMPLE_B;
- dynamic_offset = ins->opcode == VKD3DSIH_GATHER4_PO;
- gather = ins->opcode == VKD3DSIH_GATHER4 || ins->opcode == VKD3DSIH_GATHER4_PO;
- grad = ins->opcode == VKD3DSIH_SAMPLE_GRAD;
- lod = ins->opcode == VKD3DSIH_SAMPLE_LOD || ins->opcode == VKD3DSIH_SAMPLE_C_LZ;
- lod_zero = ins->opcode == VKD3DSIH_SAMPLE_C_LZ;
+ bias = ins->opcode == VSIR_OP_SAMPLE_B;
+ dynamic_offset = ins->opcode == VSIR_OP_GATHER4_PO;
+ gather = ins->opcode == VSIR_OP_GATHER4 || ins->opcode == VSIR_OP_GATHER4_PO;
+ grad = ins->opcode == VSIR_OP_SAMPLE_GRAD;
+ lod = ins->opcode == VSIR_OP_SAMPLE_LOD || ins->opcode == VSIR_OP_SAMPLE_C_LZ;
+ lod_zero = ins->opcode == VSIR_OP_SAMPLE_C_LZ;
offset = dynamic_offset || vkd3d_shader_instruction_has_texel_offset(ins);
- shadow = ins->opcode == VKD3DSIH_SAMPLE_C || ins->opcode == VKD3DSIH_SAMPLE_C_LZ;
+ shadow = ins->opcode == VSIR_OP_SAMPLE_C || ins->opcode == VSIR_OP_SAMPLE_C_LZ;
resource = &ins->src[1 + dynamic_offset];
sampler = &ins->src[2 + dynamic_offset];
@@ -938,7 +946,7 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk
"Internal compiler error: Undeclared resource descriptor %u.", resource_id);
resource_space = 0;
resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D;
- data_type = VKD3D_DATA_FLOAT;
+ data_type = VSIR_DATA_F32;
}
if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type)))
@@ -1053,7 +1061,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s
enum vkd3d_shader_resource_type resource_type;
unsigned int uav_id, uav_idx, uav_space;
struct vkd3d_string_buffer *load;
- enum vkd3d_data_type data_type;
+ enum vsir_data_type data_type;
struct glsl_src coord;
struct glsl_dst dst;
uint32_t coord_mask;
@@ -1076,7 +1084,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s
"Internal compiler error: Undeclared UAV descriptor %u.", uav_id);
uav_space = 0;
resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D;
- data_type = VKD3D_DATA_FLOAT;
+ data_type = VSIR_DATA_F32;
}
if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type)))
@@ -1113,7 +1121,7 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const
enum vkd3d_shader_resource_type resource_type;
unsigned int uav_id, uav_idx, uav_space;
struct vkd3d_string_buffer *image_data;
- enum vkd3d_data_type data_type;
+ enum vsir_data_type data_type;
struct glsl_src image_coord;
uint32_t coord_mask;
@@ -1135,7 +1143,7 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const
"Internal compiler error: Undeclared UAV descriptor %u.", uav_id);
uav_space = 0;
resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D;
- data_type = VKD3D_DATA_FLOAT;
+ data_type = VSIR_DATA_F32;
}
if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type)))
@@ -1156,19 +1164,19 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const
{
switch (data_type)
{
- case VKD3D_DATA_UINT:
- vkd3d_string_buffer_printf(image_data, "uvec4(");
- break;
- case VKD3D_DATA_INT:
+ case VSIR_DATA_I32:
vkd3d_string_buffer_printf(image_data, "ivec4(");
break;
+ case VSIR_DATA_U32:
+ vkd3d_string_buffer_printf(image_data, "uvec4(");
+ break;
default:
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled data type %#x.", data_type);
/* fall through */
- case VKD3D_DATA_FLOAT:
- case VKD3D_DATA_UNORM:
- case VKD3D_DATA_SNORM:
+ case VSIR_DATA_F32:
+ case VSIR_DATA_SNORM:
+ case VSIR_DATA_UNORM:
vkd3d_string_buffer_printf(image_data, "vec4(");
break;
}
@@ -1242,37 +1250,6 @@ static void shader_glsl_movc(struct vkd3d_glsl_generator *gen, const struct vkd3
glsl_dst_cleanup(&dst, &gen->string_buffers);
}
-static void shader_glsl_mul_extended(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins)
-{
- struct glsl_src src[2];
- struct glsl_dst dst;
- uint32_t mask;
-
- if (ins->dst[0].reg.type != VKD3DSPR_NULL)
- {
- /* FIXME: imulExtended()/umulExtended() from ARB_gpu_shader5/GLSL 4.00+. */
- mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]);
- shader_glsl_print_assignment(gen, &dst, "<unhandled 64-bit multiplication>");
- glsl_dst_cleanup(&dst, &gen->string_buffers);
-
- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
- "Internal compiler error: Unhandled 64-bit integer multiplication.");
- }
-
- if (ins->dst[1].reg.type != VKD3DSPR_NULL)
- {
- mask = glsl_dst_init(&dst, gen, ins, &ins->dst[1]);
- glsl_src_init(&src[0], gen, &ins->src[0], mask);
- glsl_src_init(&src[1], gen, &ins->src[1], mask);
-
- shader_glsl_print_assignment(gen, &dst, "%s * %s", src[0].str->buffer, src[1].str->buffer);
-
- glsl_src_cleanup(&src[1], &gen->string_buffers);
- glsl_src_cleanup(&src[0], &gen->string_buffers);
- glsl_dst_cleanup(&dst, &gen->string_buffers);
- }
-}
-
static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen,
enum vkd3d_shader_sysval_semantic sysval, unsigned int idx)
{
@@ -1482,177 +1459,177 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen,
switch (ins->opcode)
{
- case VKD3DSIH_ADD:
- case VKD3DSIH_IADD:
+ case VSIR_OP_ADD:
+ case VSIR_OP_IADD:
shader_glsl_binop(gen, ins, "+");
break;
- case VKD3DSIH_AND:
+ case VSIR_OP_AND:
shader_glsl_binop(gen, ins, "&");
break;
- case VKD3DSIH_BREAK:
+ case VSIR_OP_BREAK:
shader_glsl_break(gen);
break;
- case VKD3DSIH_CASE:
+ case VSIR_OP_CASE:
shader_glsl_case(gen, ins);
break;
- case VKD3DSIH_CONTINUE:
+ case VSIR_OP_CONTINUE:
shader_glsl_continue(gen);
break;
- case VKD3DSIH_DCL_INDEXABLE_TEMP:
+ case VSIR_OP_DCL_INDEXABLE_TEMP:
shader_glsl_dcl_indexable_temp(gen, ins);
break;
- case VKD3DSIH_NOP:
+ case VSIR_OP_NOP:
break;
- case VKD3DSIH_DEFAULT:
+ case VSIR_OP_DEFAULT:
shader_glsl_default(gen);
break;
- case VKD3DSIH_DIV:
+ case VSIR_OP_DIV:
shader_glsl_binop(gen, ins, "/");
break;
- case VKD3DSIH_DP2:
+ case VSIR_OP_DP2:
shader_glsl_dot(gen, ins, vkd3d_write_mask_from_component_count(2));
break;
- case VKD3DSIH_DP3:
+ case VSIR_OP_DP3:
shader_glsl_dot(gen, ins, vkd3d_write_mask_from_component_count(3));
break;
- case VKD3DSIH_DP4:
+ case VSIR_OP_DP4:
shader_glsl_dot(gen, ins, VKD3DSP_WRITEMASK_ALL);
break;
- case VKD3DSIH_ELSE:
+ case VSIR_OP_ELSE:
shader_glsl_else(gen, ins);
break;
- case VKD3DSIH_ENDIF:
- case VKD3DSIH_ENDLOOP:
- case VKD3DSIH_ENDSWITCH:
+ case VSIR_OP_ENDIF:
+ case VSIR_OP_ENDLOOP:
+ case VSIR_OP_ENDSWITCH:
shader_glsl_end_block(gen);
break;
- case VKD3DSIH_EQO:
- case VKD3DSIH_IEQ:
+ case VSIR_OP_EQO:
+ case VSIR_OP_IEQ:
shader_glsl_relop(gen, ins, "==", "equal");
break;
- case VKD3DSIH_EXP:
+ case VSIR_OP_EXP:
shader_glsl_intrinsic(gen, ins, "exp2");
break;
- case VKD3DSIH_FRC:
+ case VSIR_OP_FRC:
shader_glsl_intrinsic(gen, ins, "fract");
break;
- case VKD3DSIH_FTOI:
+ case VSIR_OP_FTOI:
shader_glsl_cast(gen, ins, "int", "ivec");
break;
- case VKD3DSIH_FTOU:
+ case VSIR_OP_FTOU:
shader_glsl_cast(gen, ins, "uint", "uvec");
break;
- case VKD3DSIH_GATHER4:
- case VKD3DSIH_GATHER4_PO:
- case VKD3DSIH_SAMPLE:
- case VKD3DSIH_SAMPLE_B:
- case VKD3DSIH_SAMPLE_C:
- case VKD3DSIH_SAMPLE_C_LZ:
- case VKD3DSIH_SAMPLE_GRAD:
- case VKD3DSIH_SAMPLE_LOD:
+ case VSIR_OP_GATHER4:
+ case VSIR_OP_GATHER4_PO:
+ case VSIR_OP_SAMPLE:
+ case VSIR_OP_SAMPLE_B:
+ case VSIR_OP_SAMPLE_C:
+ case VSIR_OP_SAMPLE_C_LZ:
+ case VSIR_OP_SAMPLE_GRAD:
+ case VSIR_OP_SAMPLE_LOD:
shader_glsl_sample(gen, ins);
break;
- case VKD3DSIH_GEO:
- case VKD3DSIH_IGE:
+ case VSIR_OP_GEO:
+ case VSIR_OP_IGE:
shader_glsl_relop(gen, ins, ">=", "greaterThanEqual");
break;
- case VKD3DSIH_IF:
+ case VSIR_OP_IF:
shader_glsl_if(gen, ins);
break;
- case VKD3DSIH_MAD:
+ case VSIR_OP_MAD:
shader_glsl_intrinsic(gen, ins, "fma");
break;
- case VKD3DSIH_ILT:
- case VKD3DSIH_LTO:
- case VKD3DSIH_ULT:
+ case VSIR_OP_ILT:
+ case VSIR_OP_LTO:
+ case VSIR_OP_ULT:
shader_glsl_relop(gen, ins, "<", "lessThan");
break;
- case VKD3DSIH_IMAX:
- case VKD3DSIH_MAX:
- case VKD3DSIH_UMAX:
+ case VSIR_OP_IMAX:
+ case VSIR_OP_MAX:
+ case VSIR_OP_UMAX:
shader_glsl_intrinsic(gen, ins, "max");
break;
- case VKD3DSIH_MIN:
- case VKD3DSIH_UMIN:
+ case VSIR_OP_MIN:
+ case VSIR_OP_UMIN:
shader_glsl_intrinsic(gen, ins, "min");
break;
- case VKD3DSIH_IMUL:
- shader_glsl_mul_extended(gen, ins);
+ case VSIR_OP_IMUL_LOW:
+ shader_glsl_binop(gen, ins, "*");
break;
- case VKD3DSIH_INE:
- case VKD3DSIH_NEU:
+ case VSIR_OP_INE:
+ case VSIR_OP_NEU:
shader_glsl_relop(gen, ins, "!=", "notEqual");
break;
- case VKD3DSIH_INEG:
+ case VSIR_OP_INEG:
shader_glsl_unary_op(gen, ins, "-");
break;
- case VKD3DSIH_ISHL:
+ case VSIR_OP_ISHL:
shader_glsl_binop(gen, ins, "<<");
break;
- case VKD3DSIH_ISHR:
- case VKD3DSIH_USHR:
+ case VSIR_OP_ISHR:
+ case VSIR_OP_USHR:
shader_glsl_binop(gen, ins, ">>");
break;
- case VKD3DSIH_ITOF:
- case VKD3DSIH_UTOF:
+ case VSIR_OP_ITOF:
+ case VSIR_OP_UTOF:
shader_glsl_cast(gen, ins, "float", "vec");
break;
- case VKD3DSIH_LD:
- case VKD3DSIH_LD2DMS:
+ case VSIR_OP_LD:
+ case VSIR_OP_LD2DMS:
shader_glsl_ld(gen, ins);
break;
- case VKD3DSIH_LD_UAV_TYPED:
+ case VSIR_OP_LD_UAV_TYPED:
shader_glsl_load_uav_typed(gen, ins);
break;
- case VKD3DSIH_LOG:
+ case VSIR_OP_LOG:
shader_glsl_intrinsic(gen, ins, "log2");
break;
- case VKD3DSIH_LOOP:
+ case VSIR_OP_LOOP:
shader_glsl_loop(gen);
break;
- case VKD3DSIH_MOV:
+ case VSIR_OP_MOV:
shader_glsl_mov(gen, ins);
break;
- case VKD3DSIH_MOVC:
+ case VSIR_OP_MOVC:
shader_glsl_movc(gen, ins);
break;
- case VKD3DSIH_MUL:
+ case VSIR_OP_MUL:
shader_glsl_binop(gen, ins, "*");
break;
- case VKD3DSIH_NOT:
+ case VSIR_OP_NOT:
shader_glsl_unary_op(gen, ins, "~");
break;
- case VKD3DSIH_OR:
+ case VSIR_OP_OR:
shader_glsl_binop(gen, ins, "|");
break;
- case VKD3DSIH_RET:
+ case VSIR_OP_RET:
shader_glsl_ret(gen, ins);
break;
- case VKD3DSIH_ROUND_NE:
+ case VSIR_OP_ROUND_NE:
shader_glsl_intrinsic(gen, ins, "roundEven");
break;
- case VKD3DSIH_ROUND_NI:
+ case VSIR_OP_ROUND_NI:
shader_glsl_intrinsic(gen, ins, "floor");
break;
- case VKD3DSIH_ROUND_PI:
+ case VSIR_OP_ROUND_PI:
shader_glsl_intrinsic(gen, ins, "ceil");
break;
- case VKD3DSIH_ROUND_Z:
+ case VSIR_OP_ROUND_Z:
shader_glsl_intrinsic(gen, ins, "trunc");
break;
- case VKD3DSIH_RSQ:
+ case VSIR_OP_RSQ:
shader_glsl_intrinsic(gen, ins, "inversesqrt");
break;
- case VKD3DSIH_SQRT:
+ case VSIR_OP_SQRT:
shader_glsl_intrinsic(gen, ins, "sqrt");
break;
- case VKD3DSIH_STORE_UAV_TYPED:
+ case VSIR_OP_STORE_UAV_TYPED:
shader_glsl_store_uav_typed(gen, ins);
break;
- case VKD3DSIH_SWITCH:
+ case VSIR_OP_SWITCH:
shader_glsl_switch(gen, ins);
break;
- case VKD3DSIH_XOR:
+ case VSIR_OP_XOR:
shader_glsl_binop(gen, ins, "^");
break;
default:
@@ -1789,22 +1766,22 @@ static void shader_glsl_generate_uav_declaration(struct vkd3d_glsl_generator *ge
switch (uav->resource_data_type)
{
- case VKD3D_DATA_UINT:
- image_type_prefix = "u";
- read_format = "r32ui";
- break;
- case VKD3D_DATA_INT:
+ case VSIR_DATA_I32:
image_type_prefix = "i";
read_format = "r32i";
break;
+ case VSIR_DATA_U32:
+ image_type_prefix = "u";
+ read_format = "r32ui";
+ break;
default:
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled data type %#x for UAV %u.",
uav->resource_data_type, uav->register_id);
/* fall through */
- case VKD3D_DATA_FLOAT:
- case VKD3D_DATA_UNORM:
- case VKD3D_DATA_SNORM:
+ case VSIR_DATA_F32:
+ case VSIR_DATA_SNORM:
+ case VSIR_DATA_UNORM:
image_type_prefix = "";
read_format = "r32f";
break;
@@ -2018,16 +1995,16 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator
switch (srv->resource_data_type)
{
- case VKD3D_DATA_UINT:
- sampler_type_prefix = "u";
+ case VSIR_DATA_F32:
+ case VSIR_DATA_SNORM:
+ case VSIR_DATA_UNORM:
+ sampler_type_prefix = "";
break;
- case VKD3D_DATA_INT:
+ case VSIR_DATA_I32:
sampler_type_prefix = "i";
break;
- case VKD3D_DATA_FLOAT:
- case VKD3D_DATA_UNORM:
- case VKD3D_DATA_SNORM:
- sampler_type_prefix = "";
+ case VSIR_DATA_U32:
+ sampler_type_prefix = "u";
break;
default:
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
@@ -2313,7 +2290,7 @@ static void shader_glsl_handle_global_flags(struct vkd3d_string_buffer *buffer,
flags &= ~VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL;
}
- if (flags)
+ if (flags & ~VKD3DSGF_REFACTORING_ALLOWED)
vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL,
"Internal compiler error: Unhandled global flags %#"PRIx64".", (uint64_t)flags);
}
@@ -2348,9 +2325,9 @@ static void shader_glsl_generate_declarations(struct vkd3d_glsl_generator *gen)
static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struct vkd3d_shader_code *out)
{
- const struct vkd3d_shader_instruction_array *instructions = &gen->program->instructions;
struct vkd3d_string_buffer *buffer = gen->buffer;
- unsigned int i;
+ struct vkd3d_shader_instruction *ins;
+ struct vsir_program_iterator it;
void *code;
MESSAGE("Generating a GLSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n");
@@ -2365,9 +2342,11 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struc
++gen->indent;
shader_glsl_shader_prologue(gen);
- for (i = 0; i < instructions->count; ++i)
+
+ it = vsir_program_iterator(&gen->program->instructions);
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- vkd3d_glsl_handle_instruction(gen, &instructions->elements[i]);
+ vkd3d_glsl_handle_instruction(gen, ins);
}
vkd3d_string_buffer_printf(buffer, "}\n");
@@ -2465,6 +2444,9 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags,
if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0)
return ret;
+ if ((ret = vsir_allocate_temp_registers(program, message_context)) < 0)
+ return ret;
+
VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6);
VKD3D_ASSERT(program->has_descriptor_info);
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
index 653ddd2e8be..62335086e20 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
@@ -2062,7 +2062,7 @@ struct hlsl_ir_node *hlsl_block_add_load_component(struct hlsl_ctx *ctx, struct
return &load->node;
}
-static struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx,
+static struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx,
const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc)
{
struct hlsl_ir_resource_load *load;
@@ -2098,18 +2098,23 @@ static struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx,
load->sampling_dim = params->sampling_dim;
if (load->sampling_dim == HLSL_SAMPLER_DIM_GENERIC)
load->sampling_dim = hlsl_deref_get_type(ctx, &load->resource)->sampler_dim;
- return &load->node;
+ return load;
}
struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block,
const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc)
{
- return append_new_instr(ctx, block, hlsl_new_resource_load(ctx, params, loc));
+ struct hlsl_ir_resource_load *load = hlsl_new_resource_load(ctx, params, loc);
+
+ if (load && load->sampling_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
+ hlsl_src_from_node(&load->byte_offset, hlsl_block_add_uint_constant(ctx, block, 0, loc));
+
+ return append_new_instr(ctx, block, &load->node);
}
-static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum hlsl_resource_store_type type,
- const struct hlsl_deref *resource, struct hlsl_ir_node *coords, struct hlsl_ir_node *value,
- const struct vkd3d_shader_location *loc)
+static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx,
+ enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords,
+ struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc)
{
struct hlsl_ir_resource_store *store;
@@ -2117,6 +2122,7 @@ static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum h
return NULL;
init_node(&store->node, HLSL_IR_RESOURCE_STORE, NULL, loc);
store->store_type = type;
+ store->writemask = writemask;
hlsl_copy_deref(ctx, &store->resource, resource);
hlsl_src_from_node(&store->coords, coords);
@@ -2126,9 +2132,9 @@ static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum h
void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords,
- struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc)
+ struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc)
{
- append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, loc));
+ append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, writemask, loc));
}
struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int component_count,
@@ -2377,6 +2383,19 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index)
return false;
}
+bool hlsl_index_chain_has_tgsm_access(struct hlsl_ir_index *index)
+{
+ if (index->val.node->type == HLSL_IR_LOAD)
+ {
+ struct hlsl_ir_load *load = hlsl_ir_load(index->val.node);
+ return load->src.var->storage_modifiers & HLSL_STORAGE_GROUPSHARED;
+ }
+
+ if (index->val.node->type == HLSL_IR_INDEX)
+ return hlsl_index_chain_has_tgsm_access(hlsl_ir_index(index->val.node));
+ return false;
+}
+
static struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val,
struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc)
{
@@ -2648,6 +2667,7 @@ static struct hlsl_ir_node *clone_resource_load(struct hlsl_ctx *ctx,
vkd3d_free(dst);
return NULL;
}
+ clone_src(map, &dst->byte_offset, &src->byte_offset);
clone_src(map, &dst->coords, &src->coords);
clone_src(map, &dst->lod, &src->lod);
clone_src(map, &dst->ddx, &src->ddx);
@@ -2668,6 +2688,7 @@ static struct hlsl_ir_node *clone_resource_store(struct hlsl_ctx *ctx,
return NULL;
init_node(&dst->node, HLSL_IR_RESOURCE_STORE, NULL, &src->node.loc);
dst->store_type = src->store_type;
+ dst->writemask = src->writemask;
if (!clone_deref(ctx, map, &dst->resource, &src->resource))
{
vkd3d_free(dst);
@@ -2985,6 +3006,17 @@ bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const
return ret;
}
+struct hlsl_ir_node *hlsl_clone_instr(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr)
+{
+ struct clone_instr_map map = {0};
+ struct hlsl_ir_node *ret;
+
+ ret = clone_instr(ctx, &map, instr);
+ vkd3d_free(map.instrs);
+
+ return ret;
+}
+
struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx,
struct hlsl_type *return_type, const struct hlsl_func_parameters *parameters,
const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc)
@@ -2998,7 +3030,6 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx,
decl->return_type = return_type;
decl->parameters = *parameters;
decl->loc = *loc;
- list_init(&decl->extern_vars);
if (!hlsl_types_are_equal(return_type, ctx->builtin_types.Void))
{
@@ -3220,12 +3251,14 @@ static void hlsl_dump_type(struct vkd3d_string_buffer *buffer, const struct hlsl
return;
}
- VKD3D_ASSERT(hlsl_is_numeric_type(type->e.resource.format));
- VKD3D_ASSERT(type->e.resource.format->e.numeric.type < ARRAY_SIZE(base_types));
if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER)
{
vkd3d_string_buffer_printf(buffer, "Buffer<");
}
+ else if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
+ {
+ vkd3d_string_buffer_printf(buffer, "StructuredBuffer<");
+ }
else
{
VKD3D_ASSERT(type->sampler_dim < ARRAY_SIZE(dimensions));
@@ -3531,21 +3564,7 @@ static void dump_deref(struct vkd3d_string_buffer *buffer, const struct hlsl_der
const char *debug_hlsl_writemask(unsigned int writemask)
{
- static const char components[] = {'x', 'y', 'z', 'w'};
- char string[5];
- unsigned int i = 0, pos = 0;
-
- VKD3D_ASSERT(!(writemask & ~VKD3DSP_WRITEMASK_ALL));
-
- while (writemask)
- {
- if (writemask & 1)
- string[pos++] = components[i];
- writemask >>= 1;
- i++;
- }
- string[pos] = '\0';
- return vkd3d_dbg_sprintf(".%s", string);
+ return debug_vsir_writemask(writemask);
}
const char *debug_hlsl_swizzle(uint32_t swizzle, unsigned int size)
@@ -3652,6 +3671,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op)
[HLSL_OP1_LOG2] = "log2",
[HLSL_OP1_LOGIC_NOT] = "!",
[HLSL_OP1_NEG] = "-",
+ [HLSL_OP1_NOISE] = "noise",
[HLSL_OP1_RCP] = "rcp",
[HLSL_OP1_REINTERPRET] = "reinterpret",
[HLSL_OP1_ROUND] = "round",
@@ -3776,6 +3796,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru
dump_deref(buffer, &load->resource);
vkd3d_string_buffer_printf(buffer, ", sampler = ");
dump_deref(buffer, &load->sampler);
+ if (load->byte_offset.node)
+ {
+ vkd3d_string_buffer_printf(buffer, ", byte_offset = ");
+ dump_src(buffer, &load->byte_offset);
+ }
if (load->coords.node)
{
vkd3d_string_buffer_printf(buffer, ", coords = ");
@@ -3814,7 +3839,8 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru
vkd3d_string_buffer_printf(buffer, ")");
}
-static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store)
+static void dump_ir_resource_store(struct hlsl_ctx *ctx,
+ struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store)
{
static const char *const type_names[] =
{
@@ -3826,6 +3852,8 @@ static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const str
VKD3D_ASSERT(store->store_type < ARRAY_SIZE(type_names));
vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[store->store_type]);
dump_deref(buffer, &store->resource);
+ if (store->writemask != VKD3DSP_WRITEMASK_ALL && type_is_single_reg(hlsl_deref_get_type(ctx, &store->resource)))
+ vkd3d_string_buffer_printf(buffer, "%s", debug_hlsl_writemask(store->writemask));
if (store->coords.node)
{
vkd3d_string_buffer_printf(buffer, ", coords = ");
@@ -3844,11 +3872,11 @@ static void dump_ir_string(struct vkd3d_string_buffer *buffer, const struct hlsl
vkd3d_string_buffer_printf(buffer, "\"%s\"", debugstr_a(string->string));
}
-static void dump_ir_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_store *store)
+static void dump_ir_store(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_store *store)
{
vkd3d_string_buffer_printf(buffer, "= (");
dump_deref(buffer, &store->lhs);
- if (store->writemask != VKD3DSP_WRITEMASK_ALL)
+ if (store->writemask != VKD3DSP_WRITEMASK_ALL && type_is_single_reg(hlsl_deref_get_type(ctx, &store->lhs)))
vkd3d_string_buffer_printf(buffer, "%s", debug_hlsl_writemask(store->writemask));
vkd3d_string_buffer_printf(buffer, " ");
dump_src(buffer, &store->rhs);
@@ -4038,7 +4066,7 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
break;
case HLSL_IR_RESOURCE_STORE:
- dump_ir_resource_store(buffer, hlsl_ir_resource_store(instr));
+ dump_ir_resource_store(ctx, buffer, hlsl_ir_resource_store(instr));
break;
case HLSL_IR_STRING_CONSTANT:
@@ -4046,7 +4074,7 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
break;
case HLSL_IR_STORE:
- dump_ir_store(buffer, hlsl_ir_store(instr));
+ dump_ir_store(ctx, buffer, hlsl_ir_store(instr));
break;
case HLSL_IR_SWITCH:
@@ -4079,20 +4107,23 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer,
}
}
-void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func)
+void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func,
+ const char *description, const struct hlsl_block *processed_block)
{
struct vkd3d_string_buffer buffer;
size_t i;
vkd3d_string_buffer_init(&buffer);
- vkd3d_string_buffer_printf(&buffer, "Dumping function %s.\n", func->func->name);
+ vkd3d_string_buffer_printf(&buffer, "Dumping %s \"%s\".\n", description, func->func->name);
vkd3d_string_buffer_printf(&buffer, "Function parameters:\n");
for (i = 0; i < func->parameters.count; ++i)
{
dump_ir_var(ctx, &buffer, func->parameters.vars[i]);
vkd3d_string_buffer_printf(&buffer, "\n");
}
- if (func->has_body)
+ if (processed_block)
+ dump_block(ctx, &buffer, processed_block);
+ else if (func->has_body)
dump_block(ctx, &buffer, &func->body);
vkd3d_string_buffer_trace(&buffer);
@@ -4137,7 +4168,7 @@ void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new)
const struct hlsl_type *old_type = old->data_type, *new_type = new->data_type;
struct hlsl_src *src, *next;
- if (hlsl_is_numeric_type(old_type))
+ if (old_type && hlsl_is_numeric_type(old_type))
{
VKD3D_ASSERT(hlsl_is_numeric_type(new_type));
VKD3D_ASSERT(old_type->e.numeric.dimx == new_type->e.numeric.dimx);
@@ -4241,6 +4272,7 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load)
{
hlsl_cleanup_deref(&load->sampler);
hlsl_cleanup_deref(&load->resource);
+ hlsl_src_remove(&load->byte_offset);
hlsl_src_remove(&load->coords);
hlsl_src_remove(&load->lod);
hlsl_src_remove(&load->ddx);
@@ -4865,8 +4897,9 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
hlsl_release_string_buffer(ctx, name);
}
-static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info,
- const struct hlsl_profile_info *profile, struct vkd3d_shader_message_context *message_context)
+static bool hlsl_ctx_init(struct hlsl_ctx *ctx, struct vkd3d_shader_source_list *source_files,
+ const struct vkd3d_shader_compile_info *compile_info, const struct hlsl_profile_info *profile,
+ struct vkd3d_shader_message_context *message_context)
{
unsigned int i;
@@ -4876,15 +4909,12 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil
ctx->message_context = message_context;
- if (!(ctx->source_files = hlsl_alloc(ctx, sizeof(*ctx->source_files))))
- return false;
- if (!(ctx->source_files[0] = hlsl_strdup(ctx, compile_info->source_name ? compile_info->source_name : "<anonymous>")))
- {
- vkd3d_free(ctx->source_files);
+ ctx->source_files = source_files;
+ if (!vkd3d_shader_source_list_append(source_files,
+ compile_info->source_name ? compile_info->source_name : "<anonymous>"))
return false;
- }
- ctx->source_files_count = 1;
- ctx->location.source_name = ctx->source_files[0];
+
+ ctx->location.source_name = source_files->sources[0];
ctx->location.line = ctx->location.column = 1;
vkd3d_string_buffer_cache_init(&ctx->string_buffers);
@@ -4892,8 +4922,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil
if (!(ctx->dummy_scope = hlsl_new_scope(ctx, NULL)))
{
- vkd3d_free((void *)ctx->source_files[0]);
- vkd3d_free(ctx->source_files);
+ vkd3d_string_buffer_cache_cleanup(&ctx->string_buffers);
return false;
}
hlsl_push_scope(ctx);
@@ -4978,9 +5007,6 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx)
struct hlsl_type *type, *next_type;
unsigned int i;
- for (i = 0; i < ctx->source_files_count; ++i)
- vkd3d_free((void *)ctx->source_files[i]);
- vkd3d_free(ctx->source_files);
vkd3d_string_buffer_cache_cleanup(&ctx->string_buffers);
rb_destroy(&ctx->functions, free_function_rb, NULL);
@@ -5022,31 +5048,13 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx)
vkd3d_free(ctx->constant_defs.regs);
}
-int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info,
- struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context)
+static int hlsl_ctx_parse(struct hlsl_ctx *ctx, struct vkd3d_shader_source_list *source_list,
+ const struct vkd3d_shader_compile_info *compile_info, const struct hlsl_profile_info *profile,
+ struct vkd3d_shader_message_context *message_context)
{
enum vkd3d_shader_target_type target_type = compile_info->target_type;
- const struct vkd3d_shader_hlsl_source_info *hlsl_source_info;
- struct hlsl_ir_function_decl *decl, *entry_func = NULL;
- const struct hlsl_profile_info *profile;
- struct hlsl_ir_function *func;
- const char *entry_point;
- struct hlsl_ctx ctx;
int ret;
- if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO)))
- {
- ERR("No HLSL source info given.\n");
- return VKD3D_ERROR_INVALID_ARGUMENT;
- }
- entry_point = hlsl_source_info->entry_point ? hlsl_source_info->entry_point : "main";
-
- if (!(profile = hlsl_get_target_info(hlsl_source_info->profile)))
- {
- FIXME("Unknown compilation target %s.\n", debugstr_a(hlsl_source_info->profile));
- return VKD3D_ERROR_NOT_IMPLEMENTED;
- }
-
if (target_type != VKD3D_SHADER_TARGET_FX && profile->type == VKD3D_SHADER_TYPE_EFFECT)
{
vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
@@ -5072,37 +5080,115 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
return VKD3D_ERROR_INVALID_ARGUMENT;
}
- if (!hlsl_ctx_init(&ctx, compile_info, profile, message_context))
+ if (!hlsl_ctx_init(ctx, source_list, compile_info, profile, message_context))
return VKD3D_ERROR_OUT_OF_MEMORY;
- if ((ret = hlsl_lexer_compile(&ctx, hlsl)) == 2)
+ if ((ret = hlsl_lexer_compile(ctx, &compile_info->source)) == 2)
{
- hlsl_ctx_cleanup(&ctx);
+ hlsl_ctx_cleanup(ctx);
return VKD3D_ERROR_OUT_OF_MEMORY;
}
- if (ctx.result)
+ if (ctx->result)
{
- hlsl_ctx_cleanup(&ctx);
- return ctx.result;
+ hlsl_ctx_cleanup(ctx);
+ return ctx->result;
}
/* If parsing failed without an error condition being recorded, we
* plausibly hit some unimplemented feature. */
if (ret)
{
- hlsl_ctx_cleanup(&ctx);
+ hlsl_ctx_cleanup(ctx);
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
+ }
+
+ return VKD3D_OK;
+}
+
+int hlsl_compile_effect(const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out)
+{
+ const struct vkd3d_shader_hlsl_source_info *hlsl_source_info;
+ struct vkd3d_shader_source_list source_list;
+ const struct hlsl_profile_info *profile;
+ struct hlsl_ctx ctx;
+ int ret;
+
+ if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO)))
+ {
+ WARN("No HLSL source info given.\n");
+ return VKD3D_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (!(profile = hlsl_get_target_info(hlsl_source_info->profile)))
+ {
+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE,
+ "Unknown target profile '%s'.", hlsl_source_info->profile);
return VKD3D_ERROR_NOT_IMPLEMENTED;
}
- if (ctx.profile->type == VKD3D_SHADER_TYPE_EFFECT)
+ vkd3d_shader_source_list_init(&source_list);
+ if ((ret = hlsl_ctx_parse(&ctx, &source_list, compile_info, profile, message_context)) < 0)
{
- ret = hlsl_emit_effect_binary(&ctx, out);
+ vkd3d_shader_source_list_cleanup(&source_list);
+ return ret;
+ }
- hlsl_ctx_cleanup(&ctx);
+ ret = hlsl_emit_effect_binary(&ctx, out);
+ hlsl_ctx_cleanup(&ctx);
+ vkd3d_shader_source_list_cleanup(&source_list);
+
+ return ret;
+}
+
+int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_message_context *message_context,
+ struct vsir_program *program, struct vkd3d_shader_code *reflection_data)
+{
+ const struct vkd3d_shader_hlsl_source_info *hlsl_source_info;
+ struct hlsl_ir_function_decl *decl, *entry_func = NULL;
+ enum vsir_normalisation_level normalisation_level;
+ const struct hlsl_profile_info *profile;
+ struct vkd3d_shader_version version;
+ struct hlsl_ir_function *func;
+ const char *entry_point;
+ struct hlsl_ctx ctx;
+ int ret;
+
+ if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO)))
+ {
+ WARN("No HLSL source info given.\n");
+ return VKD3D_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (!(profile = hlsl_get_target_info(hlsl_source_info->profile)))
+ {
+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE,
+ "Unknown target profile '%s'.", hlsl_source_info->profile);
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
+ }
+
+ version = (struct vkd3d_shader_version)
+ {
+ .type = profile->type,
+ .major = profile->major_version,
+ .minor = profile->minor_version,
+ };
+ normalisation_level = VSIR_NORMALISED_SM4;
+ if (version.major < 4 && (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_ASM
+ || compile_info->target_type == VKD3D_SHADER_TARGET_D3D_BYTECODE))
+ normalisation_level = VSIR_NORMALISED_SM1;
+ if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, normalisation_level))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ if ((ret = hlsl_ctx_parse(&ctx, &program->source_files, compile_info, profile, message_context)) < 0)
+ {
+ vsir_program_cleanup(program);
return ret;
}
+ entry_point = hlsl_source_info->entry_point ? hlsl_source_info->entry_point : "main";
if ((func = hlsl_get_function(&ctx, entry_point)))
{
LIST_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry)
@@ -5126,46 +5212,17 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
hlsl_error(&ctx, &loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED,
"Entry point \"%s\" is not defined.", entry_point);
hlsl_ctx_cleanup(&ctx);
+ vsir_program_cleanup(program);
return VKD3D_ERROR_INVALID_SHADER;
}
- if (target_type == VKD3D_SHADER_TARGET_SPIRV_BINARY
- || target_type == VKD3D_SHADER_TARGET_SPIRV_TEXT
- || target_type == VKD3D_SHADER_TARGET_GLSL
- || target_type == VKD3D_SHADER_TARGET_D3D_ASM)
- {
- uint64_t config_flags = vkd3d_shader_init_config_flags();
- struct vkd3d_shader_compile_info info = *compile_info;
- struct vsir_program program;
-
- if (profile->major_version < 4)
- {
- if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_D3D_BYTECODE, &info.source)) < 0)
- goto done;
- info.source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE;
- ret = d3dbc_parse(&info, config_flags, message_context, &program);
- }
- else
- {
- if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_DXBC_TPF, &info.source)) < 0)
- goto done;
- info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF;
- ret = tpf_parse(&info, config_flags, message_context, &program);
- }
- if (ret >= 0)
- {
- ret = vsir_program_compile(&program, config_flags, &info, out, message_context);
- vsir_program_cleanup(&program);
- }
- vkd3d_shader_free_shader_code(&info.source);
- }
+ ret = hlsl_emit_vsir(&ctx, compile_info, entry_func, program, reflection_data);
+ hlsl_ctx_cleanup(&ctx);
+ if (ret < 0)
+ vsir_program_cleanup(program);
else
- {
- ret = hlsl_emit_bytecode(&ctx, entry_func, target_type, out);
- }
+ vsir_program_trace(program);
-done:
- hlsl_ctx_cleanup(&ctx);
return ret;
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index 58f579cd9f9..d67f820fe8b 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -59,8 +59,7 @@ static inline unsigned int hlsl_swizzle_get_component(uint32_t swizzle, unsigned
static inline void hlsl_swizzle_set_component(uint32_t *swizzle, unsigned int idx, unsigned int component)
{
- *swizzle &= ~(VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(idx));
- *swizzle |= component << VKD3D_SHADER_SWIZZLE_SHIFT(idx);
+ vsir_swizzle_set_component(swizzle, idx, component);
}
enum hlsl_type_class
@@ -126,7 +125,7 @@ enum hlsl_sampler_dim
HLSL_SAMPLER_DIM_STRUCTURED_BUFFER,
HLSL_SAMPLER_DIM_RAW_BUFFER,
HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_RAW_BUFFER,
- /* NOTE: Remember to update object_methods[] in hlsl.y if this enum is modified. */
+ /* NOTE: Remember to update texture_methods[] and uav_methods[] in hlsl.y if this is modified. */
};
enum hlsl_so_object_type
@@ -245,6 +244,7 @@ struct hlsl_semantic
{
const char *name;
uint32_t index;
+ uint32_t stream_index;
/* Name exactly as it appears in the sources. */
const char *raw_name;
@@ -278,11 +278,12 @@ struct hlsl_struct_field
size_t name_bytecode_offset;
};
-/* Information of the register(s) allocated for an instruction node or variable.
- * These values are initialized at the end of hlsl_emit_bytecode(), after the compilation passes,
- * just before writing the bytecode.
- * The type of register (register class) is implied from its use, so it is not stored in this
- * struct. */
+/* Information about the register(s) allocated for an instruction node or
+ * variable. These values are initialised at the end of hlsl_emit_vsir(),
+ * after the compilation passes, as vsir starts being generated from HLSL IR.
+ *
+ * The type of register (register class) is implied by its usage, so it is not
+ * stored in this structure. */
struct hlsl_reg
{
/* Register number of the first register allocated. */
@@ -308,6 +309,8 @@ struct hlsl_reg
unsigned int writemask;
/* Whether the register has been allocated. */
bool allocated;
+ /* Currently only used for numeric registers. */
+ enum vkd3d_shader_register_type type;
};
/* Types of instruction nodes for the IR.
@@ -551,6 +554,7 @@ struct hlsl_ir_var
uint32_t is_param : 1;
uint32_t is_separated_resource : 1;
uint32_t is_synthetic : 1;
+ uint32_t is_tgsm : 1;
uint32_t has_explicit_bind_point : 1;
};
@@ -643,12 +647,6 @@ struct hlsl_ir_function_decl
* executed. Needed to deal with return statements in non-uniform control
* flow, since some backends can't handle them. */
struct hlsl_ir_var *early_return_var;
-
- /* List of all the extern semantic variables; linked by the
- * hlsl_ir_var.extern_entry fields. This exists as a convenience because
- * it is often necessary to iterate all extern variables and these can be
- * declared in as function parameters, or as the function return value. */
- struct list extern_vars;
};
struct hlsl_ir_call
@@ -733,6 +731,7 @@ enum hlsl_ir_expr_op
HLSL_OP1_ISINF,
HLSL_OP1_LOG2,
HLSL_OP1_LOGIC_NOT,
+ HLSL_OP1_NOISE,
HLSL_OP1_NEG,
HLSL_OP1_RCP,
HLSL_OP1_REINTERPRET,
@@ -895,7 +894,7 @@ struct hlsl_ir_resource_load
struct hlsl_ir_node node;
enum hlsl_resource_load_type load_type;
struct hlsl_deref resource, sampler;
- struct hlsl_src coords, lod, ddx, ddy, cmp, sample_index, texel_offset;
+ struct hlsl_src byte_offset, coords, lod, ddx, ddy, cmp, sample_index, texel_offset;
enum hlsl_sampler_dim sampling_dim;
};
@@ -912,6 +911,7 @@ struct hlsl_ir_resource_store
enum hlsl_resource_store_type store_type;
struct hlsl_deref resource;
struct hlsl_src coords, value;
+ uint8_t writemask;
};
struct hlsl_ir_store
@@ -1093,8 +1093,7 @@ struct hlsl_ctx
{
const struct hlsl_profile_info *profile;
- const char **source_files;
- unsigned int source_files_count;
+ struct vkd3d_shader_source_list *source_files;
/* Current location being read in the HLSL source, updated while parsing. */
struct vkd3d_shader_location location;
/* Stores the logging messages and logging configuration. */
@@ -1185,6 +1184,8 @@ struct hlsl_ctx
} constant_defs;
/* 'c' registers where the constants expected by SM2 sincos are stored. */
struct hlsl_reg d3dsincosconst1, d3dsincosconst2;
+ /* Number of allocated SSA IDs, used in translation to vsir. */
+ unsigned int ssa_count;
/* Number of threads to be executed (on the X, Y, and Z dimensions) in a single thread group in
* compute shader profiles. It is set using the numthreads() attribute in the entry point. */
@@ -1586,7 +1587,7 @@ struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct h
const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc);
void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords,
- struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc);
+ struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_block_add_simple_load(struct hlsl_ctx *ctx, struct hlsl_block *block,
struct hlsl_ir_var *var, const struct vkd3d_shader_location *loc);
void hlsl_block_add_simple_store(struct hlsl_ctx *ctx, struct hlsl_block *block,
@@ -1609,8 +1610,10 @@ struct hlsl_ir_node *hlsl_block_add_unary_expr(struct hlsl_ctx *ctx, struct hlsl
enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc);
void hlsl_block_cleanup(struct hlsl_block *block);
bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const struct hlsl_block *src_block);
+struct hlsl_ir_node *hlsl_clone_instr(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr);
-void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func);
+void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func,
+ const char *description, const struct hlsl_block *processed_block);
void hlsl_dump_ir_function_decl(struct hlsl_ctx *ctx,
struct vkd3d_string_buffer *buffer, const struct hlsl_ir_function_decl *f);
void hlsl_dump_var_default_values(const struct hlsl_ir_var *var);
@@ -1625,9 +1628,10 @@ struct hlsl_state_block_entry *clone_stateblock_entry(struct hlsl_ctx *ctx,
void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body);
void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body);
-int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
- enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out);
int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out);
+int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info,
+ struct hlsl_ir_function_decl *entry_func, struct vsir_program *program,
+ struct vkd3d_shader_code *reflection_data);
bool hlsl_init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var, unsigned int path_len);
bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_node *chain);
@@ -1707,6 +1711,7 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls
bool hlsl_index_is_noncontiguous(struct hlsl_ir_index *index);
bool hlsl_index_is_resource_access(struct hlsl_ir_index *index);
bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index);
+bool hlsl_index_chain_has_tgsm_access(struct hlsl_ir_index *index);
struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type,
const char *profile_name, struct hlsl_ir_node **args, unsigned int args_count,
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
index d9fd43b5e78..0cdebb8a657 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
@@ -158,6 +158,7 @@ static {return KW_STATIC; }
string {return KW_STRING; }
String {return KW_STRING; }
struct {return KW_STRUCT; }
+StructuredBuffer {return KW_STRUCTUREDBUFFER; }
switch {return KW_SWITCH; }
tbuffer {return KW_TBUFFER; }
(?i:technique) {return KW_TECHNIQUE; }
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index 5aee1e701cd..024d96c5663 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -2117,7 +2117,8 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc
VKD3D_ASSERT(coords->data_type->e.numeric.type == HLSL_TYPE_UINT);
VKD3D_ASSERT(coords->data_type->e.numeric.dimx == dim_count);
- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, coords, rhs, &lhs->loc);
+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE,
+ &resource_deref, coords, rhs, writemask, &lhs->loc);
hlsl_cleanup_deref(&resource_deref);
}
else if (matrix_writemask)
@@ -2559,10 +2560,17 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v)
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
"Variable '%s' is declared as both \"uniform\" and \"static\".", var->name);
+ if ((modifiers & HLSL_STORAGE_GROUPSHARED) && ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE)
+ {
+ modifiers &= ~HLSL_STORAGE_GROUPSHARED;
+ hlsl_warning(ctx, &var->loc, VKD3D_SHADER_WARNING_HLSL_IGNORED_MODIFIER,
+ "Ignoring the 'groupshared' modifier in a non-compute shader.");
+ }
+
/* Mark it as uniform. We need to do this here since synthetic
* variables also get put in the global scope, but shouldn't be
* considered uniforms, and we have no way of telling otherwise. */
- if (!(modifiers & HLSL_STORAGE_STATIC))
+ if (!(modifiers & (HLSL_STORAGE_STATIC | HLSL_STORAGE_GROUPSHARED)))
var->storage_modifiers |= HLSL_STORAGE_UNIFORM;
if (stream_output)
@@ -4291,6 +4299,28 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx,
return true;
}
+static bool intrinsic_noise(struct hlsl_ctx *ctx,
+ const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
+{
+ struct hlsl_type *type = params->args[0]->data_type, *ret_type;
+ struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0};
+
+ type = params->args[0]->data_type;
+ if (type->class == HLSL_CLASS_MATRIX)
+ {
+ struct vkd3d_string_buffer *string;
+ if ((string = hlsl_type_to_string(ctx, type)))
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
+ "Wrong argument type for noise(): expected vector or scalar, but got '%s'.", string->buffer);
+ hlsl_release_string_buffer(ctx, string);
+ }
+
+ args[0] = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
+ ret_type = hlsl_get_scalar_type(ctx, args[0]->data_type->e.numeric.type);
+
+ return !!add_expr(ctx, params->instrs, HLSL_OP1_NOISE, args, ret_type, loc);
+}
+
static bool intrinsic_normalize(struct hlsl_ctx *ctx,
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
@@ -5033,13 +5063,25 @@ static bool intrinsic_interlocked(struct hlsl_ctx *ctx, enum hlsl_interlocked_op
if (hlsl_deref_get_type(ctx, &dst_deref)->class != HLSL_CLASS_UAV)
{
- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Interlocked targets must be UAV elements.");
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
+ "Interlocked targets must be UAV or groupshared elements.");
return false;
}
}
+ else if (lhs->type == HLSL_IR_INDEX && hlsl_index_chain_has_tgsm_access(hlsl_ir_index(lhs)))
+ {
+ hlsl_fixme(ctx, loc, "Interlocked operations on indexed groupshared elements.");
+ return false;
+ }
+ else if (lhs->type == HLSL_IR_LOAD && (hlsl_ir_load(lhs)->src.var->storage_modifiers & HLSL_STORAGE_GROUPSHARED))
+ {
+ hlsl_init_simple_deref_from_var(&dst_deref, hlsl_ir_load(lhs)->src.var);
+ coords = hlsl_block_add_uint_constant(ctx, params->instrs, 0, loc);
+ }
else
{
- hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Interlocked targets must be UAV elements.");
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
+ "Interlocked targets must be UAV or groupshared elements.");
return false;
}
@@ -5119,10 +5161,10 @@ static bool intrinsic_InterlockedXor(struct hlsl_ctx *ctx,
static void validate_group_barrier_profile(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc)
{
- if (ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE || hlsl_version_lt(ctx, 5, 0))
+ if (ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE)
{
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
- "Group barriers can only be used in compute shaders 5.0 or higher.");
+ "Group barriers can only be used in compute shaders.");
}
}
@@ -5146,10 +5188,10 @@ static bool intrinsic_DeviceMemoryBarrier(struct hlsl_ctx *ctx,
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
{
if ((ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE && ctx->profile->type != VKD3D_SHADER_TYPE_PIXEL)
- || hlsl_version_lt(ctx, 5, 0))
+ || hlsl_version_lt(ctx, 4, 0))
{
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
- "DeviceMemoryBarrier() can only be used in pixel and compute shaders 5.0 or higher.");
+ "DeviceMemoryBarrier() can only be used in compute and pixel shaders 4.0 or higher.");
}
return !!hlsl_block_add_sync(ctx, params->instrs, VKD3DSSF_GLOBAL_UAV, loc);
}
@@ -5255,6 +5297,7 @@ intrinsic_functions[] =
{"min", 2, true, intrinsic_min},
{"modf", 2, true, intrinsic_modf},
{"mul", 2, true, intrinsic_mul},
+ {"noise", 1, true, intrinsic_noise},
{"normalize", 1, true, intrinsic_normalize},
{"pow", 2, true, intrinsic_pow},
{"radians", 1, true, intrinsic_radians},
@@ -5604,6 +5647,7 @@ static unsigned int hlsl_offset_dim_count(enum hlsl_sampler_dim dim)
case HLSL_SAMPLER_DIM_CUBEARRAY:
case HLSL_SAMPLER_DIM_BUFFER:
case HLSL_SAMPLER_DIM_RAW_BUFFER:
+ case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER:
/* Offset parameters not supported for these types. */
return 0;
default:
@@ -6269,6 +6313,7 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block
struct hlsl_ir_node *offset, *rhs;
struct hlsl_deref resource_deref;
unsigned int value_dim;
+ uint32_t writemask;
if (params->args_count != 2)
{
@@ -6290,11 +6335,12 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block
hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc);
rhs = add_implicit_conversion(ctx, block, params->args[1],
hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim), loc);
+ writemask = vkd3d_write_mask_from_component_count(value_dim);
if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object))
return false;
- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, loc);
+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, writemask, loc);
hlsl_cleanup_deref(&resource_deref);
return true;
@@ -6319,7 +6365,7 @@ static bool add_so_append_method_call(struct hlsl_ctx *ctx, struct hlsl_block *b
if (!(rhs = add_implicit_conversion(ctx, block, params->args[0], object->data_type->e.so.type, loc)))
return false;
- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, loc);
+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, 0, loc);
hlsl_cleanup_deref(&so_deref);
return true;
@@ -6340,7 +6386,7 @@ static bool add_so_restartstrip_method_call(struct hlsl_ctx *ctx, struct hlsl_bl
if (!hlsl_init_deref_from_index_chain(ctx, &so_deref, object))
return false;
- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_RESTART, &so_deref, NULL, NULL, loc);
+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_RESTART, &so_deref, NULL, NULL, 0, loc);
hlsl_cleanup_deref(&so_deref);
return true;
@@ -6521,19 +6567,25 @@ static bool add_object_property_access(struct hlsl_ctx *ctx,
return false;
}
-static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type *format,
- const struct vkd3d_shader_location *loc)
+static void validate_texture_format_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
+ struct hlsl_type *format, const struct vkd3d_shader_location *loc)
{
- if (format->class > HLSL_CLASS_VECTOR)
- {
- struct vkd3d_string_buffer *string;
+ struct vkd3d_string_buffer *string;
- string = hlsl_type_to_string(ctx, format);
- if (string)
+ if (!(string = hlsl_type_to_string(ctx, format)))
+ return;
+
+ if (dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
+ {
+ if (!type_contains_only_numerics(format))
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
- "Texture data type %s is not scalar or vector.", string->buffer);
- hlsl_release_string_buffer(ctx, string);
+ "SRV type %s is not numeric.", string->buffer);
}
+ else if (format->class > HLSL_CLASS_VECTOR)
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
+ "Texture data type %s is not scalar or vector.", string->buffer);
+
+ hlsl_release_string_buffer(ctx, string);
}
static bool check_continue(struct hlsl_ctx *ctx, const struct hlsl_scope *scope, const struct vkd3d_shader_location *loc)
@@ -6801,6 +6853,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim,
%token KW_STATIC
%token KW_STRING
%token KW_STRUCT
+%token KW_STRUCTUREDBUFFER
%token KW_SWITCH
%token KW_TBUFFER
%token KW_TECHNIQUE
@@ -7137,23 +7190,19 @@ declaration_statement_list:
preproc_directive:
PRE_LINE STRING
{
- const char **new_array = NULL;
-
- ctx->location.line = $1;
if (strcmp($2, ctx->location.source_name))
- new_array = hlsl_realloc(ctx, ctx->source_files,
- sizeof(*ctx->source_files) * (ctx->source_files_count + 1));
-
- if (new_array)
{
- ctx->source_files = new_array;
- ctx->source_files[ctx->source_files_count++] = $2;
- ctx->location.source_name = $2;
- }
- else
- {
- vkd3d_free($2);
+ if (!vkd3d_shader_source_list_append(ctx->source_files, $2))
+ {
+ ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
+ }
+ else
+ {
+ ctx->location.line = $1;
+ ctx->location.source_name = ctx->source_files->sources[ctx->source_files->count - 1];
+ }
}
+ vkd3d_free($2);
}
struct_declaration_without_vars:
@@ -7888,6 +7937,10 @@ texture_type:
{
$$ = HLSL_SAMPLER_DIM_BUFFER;
}
+ | KW_STRUCTUREDBUFFER
+ {
+ $$ = HLSL_SAMPLER_DIM_STRUCTURED_BUFFER;
+ }
| KW_TEXTURE1D
{
$$ = HLSL_SAMPLER_DIM_1D;
@@ -8111,16 +8164,19 @@ type_no_void:
}
| texture_type
{
+ if ($1 == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
+ hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
+ "Structured buffer type requires an explicit format.");
$$ = hlsl_new_texture_type(ctx, $1, hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4), 0);
}
| texture_type '<' resource_format '>'
{
- validate_texture_format_type(ctx, $3, &@3);
+ validate_texture_format_type(ctx, $1, $3, &@3);
$$ = hlsl_new_texture_type(ctx, $1, $3, 0);
}
| texture_ms_type '<' resource_format '>'
{
- validate_texture_format_type(ctx, $3, &@3);
+ validate_texture_format_type(ctx, $1, $3, &@3);
$$ = hlsl_new_texture_type(ctx, $1, $3, 0);
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index 38d5c55c26b..0b3dee4d2ce 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -94,6 +94,134 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str
return base_offset;
}
+static unsigned int base_type_get_byte_size(enum hlsl_base_type t)
+{
+ switch (t)
+ {
+ case HLSL_TYPE_HALF:
+ case HLSL_TYPE_MIN16UINT:
+ case HLSL_TYPE_FLOAT:
+ case HLSL_TYPE_INT:
+ case HLSL_TYPE_UINT:
+ case HLSL_TYPE_BOOL:
+ return 4;
+
+ case HLSL_TYPE_DOUBLE:
+ return 8;
+ }
+
+ return 0;
+}
+
+static unsigned int hlsl_type_get_packed_alignment(const struct hlsl_type *type)
+{
+ unsigned int max_align, i;
+
+ switch (type->class)
+ {
+ case HLSL_CLASS_SCALAR:
+ case HLSL_CLASS_VECTOR:
+ case HLSL_CLASS_MATRIX:
+ return base_type_get_byte_size(type->e.numeric.type);
+
+ case HLSL_CLASS_ARRAY:
+ return hlsl_type_get_packed_alignment(type->e.array.type);
+
+ case HLSL_CLASS_STRUCT:
+ for (i = 0, max_align = 0; i < type->e.record.field_count; ++i)
+ {
+ struct hlsl_struct_field *field = &type->e.record.fields[i];
+
+ max_align = max(max_align, hlsl_type_get_packed_alignment(field->type));
+ }
+
+ return max_align;
+
+ default:
+ vkd3d_unreachable();
+ }
+}
+
+static unsigned int hlsl_type_get_packed_size(const struct hlsl_type *type)
+{
+ unsigned int size, i;
+
+ switch (type->class)
+ {
+ case HLSL_CLASS_SCALAR:
+ case HLSL_CLASS_VECTOR:
+ return type->e.numeric.dimx * base_type_get_byte_size(type->e.numeric.type);
+
+ case HLSL_CLASS_MATRIX:
+ return type->e.numeric.dimx * type->e.numeric.dimy * base_type_get_byte_size(type->e.numeric.type);
+
+ case HLSL_CLASS_ARRAY:
+ return type->e.array.elements_count * hlsl_type_get_packed_size(type->e.array.type);
+
+ case HLSL_CLASS_STRUCT:
+ for (i = 0, size = 0; i < type->e.record.field_count; ++i)
+ {
+ struct hlsl_struct_field *field = &type->e.record.fields[i];
+
+ size = align(size, hlsl_type_get_packed_alignment(field->type))
+ + hlsl_type_get_packed_size(field->type);
+ }
+ size = align(size, hlsl_type_get_packed_alignment(type));
+
+ return size;
+
+ default:
+ vkd3d_unreachable();
+ }
+}
+
+static struct hlsl_ir_node *hlsl_block_add_packed_index_offset_append(struct hlsl_ctx *ctx,
+ struct hlsl_block *block, struct hlsl_ir_node *prev_offset, struct hlsl_ir_node *idx,
+ struct hlsl_type *type, const struct vkd3d_shader_location *loc)
+{
+ struct hlsl_ir_node *idx_offset = NULL, *c;
+ unsigned int field_idx, offset, size, i;
+
+ switch (type->class)
+ {
+ case HLSL_CLASS_VECTOR:
+ c = hlsl_block_add_uint_constant(ctx, block, base_type_get_byte_size(type->e.numeric.type), loc);
+ idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx);
+ break;
+
+ case HLSL_CLASS_MATRIX:
+ size = base_type_get_byte_size(type->e.numeric.type) * hlsl_type_minor_size(type);
+ c = hlsl_block_add_uint_constant(ctx, block, size, loc);
+ idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx);
+ break;
+
+ case HLSL_CLASS_ARRAY:
+ size = hlsl_type_get_packed_size(type->e.array.type);
+ c = hlsl_block_add_uint_constant(ctx, block, size, loc);
+ idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx);
+ break;
+
+ case HLSL_CLASS_STRUCT:
+ field_idx = hlsl_ir_constant(idx)->value.u[0].u;
+ for (i = 0, offset = 0; i < field_idx; ++i)
+ {
+ struct hlsl_struct_field *field = &type->e.record.fields[i];
+
+ offset = align(offset, hlsl_type_get_packed_alignment(field->type))
+ + hlsl_type_get_packed_size(field->type);
+ }
+
+ offset = align(offset, hlsl_type_get_packed_alignment(type->e.record.fields[field_idx].type));
+ idx_offset = hlsl_block_add_uint_constant(ctx, block, offset, loc);
+ break;
+
+ default:
+ vkd3d_unreachable();
+ }
+
+ return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, idx_offset, prev_offset);
+}
+
/* TODO: remove when no longer needed, only used for replace_deref_path_with_offset() */
static struct hlsl_ir_node *new_offset_instr_from_deref(struct hlsl_ctx *ctx, struct hlsl_block *block,
const struct hlsl_deref *deref, unsigned int *offset_component, const struct vkd3d_shader_location *loc)
@@ -186,30 +314,34 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct hlsl_block *block,
{
struct hlsl_ir_node *store;
struct hlsl_ir_load *load;
- struct hlsl_ir_var *temp;
- char *new_name;
uniform->is_uniform = 1;
list_add_tail(&ctx->extern_vars, &uniform->extern_entry);
- if (!(new_name = hlsl_sprintf_alloc(ctx, "<temp-%s>", uniform->name)))
- return;
-
- if (!(temp = hlsl_new_var(ctx, new_name, uniform->data_type,
- &uniform->loc, NULL, uniform->storage_modifiers, NULL)))
+ if (!uniform->temp_copy)
{
- vkd3d_free(new_name);
- return;
- }
- list_add_before(&uniform->scope_entry, &temp->scope_entry);
+ struct hlsl_ir_var *temp;
+ char *new_name;
- uniform->temp_copy = temp;
+ if (!(new_name = hlsl_sprintf_alloc(ctx, "<temp-%s>", uniform->name)))
+ return;
+
+ if (!(temp = hlsl_new_var(ctx, new_name, uniform->data_type,
+ &uniform->loc, NULL, uniform->storage_modifiers, NULL)))
+ {
+ vkd3d_free(new_name);
+ return;
+ }
+ list_add_tail(&ctx->dummy_scope->vars, &temp->scope_entry);
+
+ uniform->temp_copy = temp;
+ }
if (!(load = hlsl_new_var_load(ctx, uniform, &uniform->loc)))
return;
list_add_head(&block->instrs, &load->node.entry);
- if (!(store = hlsl_new_simple_store(ctx, temp, &load->node)))
+ if (!(store = hlsl_new_simple_store(ctx, uniform->temp_copy, &load->node)))
return;
list_add_after(&load->node.entry, &store->entry);
}
@@ -233,6 +365,20 @@ static bool divert_written_uniform_derefs_to_temp(struct hlsl_ctx *ctx, struct h
return true;
}
+static void warn_on_field_semantic(struct hlsl_ctx *ctx,
+ const struct hlsl_struct_field *field, const struct hlsl_semantic *outer)
+{
+ if (!field->semantic.name)
+ return;
+
+ if (!ascii_strcasecmp(field->semantic.name, outer->name) && field->semantic.index == outer->index)
+ return;
+
+ hlsl_warning(ctx, &field->loc, VKD3D_SHADER_WARNING_HLSL_OVERRIDDEN_SEMANTIC,
+ "Field semantic %s%u is overridden by outer semantic %s%u.\n",
+ field->semantic.name, field->semantic.index, outer->name, outer->index);
+}
+
static void validate_field_semantic(struct hlsl_ctx *ctx, struct hlsl_struct_field *field)
{
if (!field->semantic.name && hlsl_is_numeric_type(hlsl_get_multiarray_element_type(field->type))
@@ -286,11 +432,12 @@ static bool types_are_semantic_equivalent(struct hlsl_ctx *ctx, const struct hls
== base_type_get_semantic_equivalent(type2->e.numeric.type);
}
-static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func,
- struct hlsl_ir_var *var, struct hlsl_type *type, uint32_t modifiers, struct hlsl_semantic *semantic,
- uint32_t index, bool output, bool force_align, bool create, const struct vkd3d_shader_location *loc)
+static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct list *semantic_vars, struct hlsl_ir_var *var,
+ struct hlsl_type *type, uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t stream_index, bool output,
+ bool force_align, bool create, const struct vkd3d_shader_location *loc)
{
struct hlsl_semantic new_semantic;
+ uint32_t index = semantic->index;
struct hlsl_ir_var *ext_var;
const char *prefix;
char *new_name;
@@ -300,10 +447,15 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir
else
prefix = output ? "output" : "input";
- if (!(new_name = hlsl_sprintf_alloc(ctx, "<%s-%s%u>", prefix, semantic->name, index)))
+ if (stream_index)
+ new_name = hlsl_sprintf_alloc(ctx, "<%s-m%u:%s%u>", prefix, stream_index, semantic->name, index);
+ else
+ new_name = hlsl_sprintf_alloc(ctx, "<%s-%s%u>", prefix, semantic->name, index);
+
+ if (!new_name)
return NULL;
- LIST_FOR_EACH_ENTRY(ext_var, &func->extern_vars, struct hlsl_ir_var, extern_entry)
+ LIST_FOR_EACH_ENTRY(ext_var, semantic_vars, struct hlsl_ir_var, extern_entry)
{
if (!ascii_strcasecmp(ext_var->name, new_name))
{
@@ -353,6 +505,7 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir
return NULL;
}
new_semantic.index = index;
+ new_semantic.stream_index = stream_index;
if (!(ext_var = hlsl_new_var(ctx, new_name, type, loc, &new_semantic, modifiers, NULL)))
{
vkd3d_free(new_name);
@@ -366,7 +519,7 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir
ext_var->is_param = var->is_param;
ext_var->force_align = force_align;
list_add_before(&var->scope_entry, &ext_var->scope_entry);
- list_add_tail(&func->extern_vars, &ext_var->extern_entry);
+ list_add_tail(semantic_vars, &ext_var->extern_entry);
return ext_var;
}
@@ -388,9 +541,9 @@ static uint32_t combine_field_storage_modifiers(uint32_t modifiers, uint32_t fie
return field_modifiers;
}
-static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func,
+static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *semantic_vars,
struct hlsl_block *block, uint32_t prim_index, struct hlsl_ir_load *lhs,
- uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align)
+ uint32_t modifiers, struct hlsl_semantic *semantic, bool force_align)
{
struct hlsl_type *type = lhs->node.data_type, *vector_type_src, *vector_type_dst;
struct vkd3d_shader_location *loc = &lhs->node.loc;
@@ -434,9 +587,10 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec
return;
prim_type_src->modifiers = var->data_type->modifiers & HLSL_PRIMITIVE_MODIFIERS_MASK;
- if (!(input = add_semantic_var(ctx, func, var, prim_type_src,
- modifiers, semantic, semantic_index + i, false, force_align, true, loc)))
+ if (!(input = add_semantic_var(ctx, semantic_vars, var, prim_type_src,
+ modifiers, semantic, 0, false, force_align, true, loc)))
return;
+ ++semantic->index;
hlsl_init_simple_deref_from_var(&prim_deref, input);
idx = hlsl_block_add_uint_constant(ctx, block, prim_index, &var->loc);
@@ -447,9 +601,10 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec
}
else
{
- if (!(input = add_semantic_var(ctx, func, var, vector_type_src,
- modifiers, semantic, semantic_index + i, false, force_align, true, loc)))
+ if (!(input = add_semantic_var(ctx, semantic_vars, var, vector_type_src,
+ modifiers, semantic, 0, false, force_align, true, loc)))
return;
+ ++semantic->index;
if (!(load = hlsl_new_var_load(ctx, input, &var->loc)))
return;
@@ -473,9 +628,9 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec
}
}
-static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func,
+static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct list *semantic_vars,
struct hlsl_block *block, uint32_t prim_index, struct hlsl_ir_load *lhs,
- uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align)
+ uint32_t modifiers, struct hlsl_semantic *semantic, bool force_align)
{
struct vkd3d_shader_location *loc = &lhs->node.loc;
struct hlsl_type *type = lhs->node.data_type;
@@ -487,21 +642,31 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_func
{
struct hlsl_ir_load *element_load;
struct hlsl_struct_field *field;
- uint32_t elem_semantic_index;
for (i = 0; i < hlsl_type_element_count(type); ++i)
{
uint32_t element_modifiers;
+ if (type->class == HLSL_CLASS_STRUCT)
+ loc = &type->e.record.fields[i].loc;
+
+ c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc);
+
+ /* This redundant load is expected to be deleted later by DCE. */
+ if (!(element_load = hlsl_new_load_index(ctx, &lhs->src, c, loc)))
+ return;
+ hlsl_block_add_instr(block, &element_load->node);
+
if (type->class == HLSL_CLASS_ARRAY)
{
- elem_semantic_index = semantic_index
- + i * hlsl_type_get_array_element_reg_size(type->e.array.type, HLSL_REGSET_NUMERIC) / 4;
element_modifiers = modifiers;
force_align = true;
if (hlsl_type_is_primitive_array(type))
prim_index = i;
+
+ prepend_input_copy_recurse(ctx, semantic_vars, block, prim_index,
+ element_load, element_modifiers, semantic, force_align);
}
else
{
@@ -511,35 +676,42 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_func
hlsl_fixme(ctx, &field->loc, "Prepend uniform copies for resource components within structs.");
continue;
}
- validate_field_semantic(ctx, field);
- semantic = &field->semantic;
- elem_semantic_index = semantic->index;
- loc = &field->loc;
element_modifiers = combine_field_storage_modifiers(modifiers, field->storage_modifiers);
force_align = (i == 0);
- }
- c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc);
+ if (semantic->name)
+ {
+ warn_on_field_semantic(ctx, field, semantic);
+ prepend_input_copy_recurse(ctx, semantic_vars, block, prim_index,
+ element_load, element_modifiers, semantic, force_align);
+ }
+ else
+ {
+ struct hlsl_semantic semantic_copy;
- /* This redundant load is expected to be deleted later by DCE. */
- if (!(element_load = hlsl_new_load_index(ctx, &lhs->src, c, loc)))
- return;
- hlsl_block_add_instr(block, &element_load->node);
+ validate_field_semantic(ctx, field);
- prepend_input_copy_recurse(ctx, func, block, prim_index, element_load,
- element_modifiers, semantic, elem_semantic_index, force_align);
+ if (!(hlsl_clone_semantic(ctx, &semantic_copy, &field->semantic)))
+ return;
+ prepend_input_copy_recurse(ctx, semantic_vars, block, prim_index,
+ element_load, element_modifiers, &semantic_copy, force_align);
+ hlsl_cleanup_semantic(&semantic_copy);
+ }
+ }
}
}
else
{
- prepend_input_copy(ctx, func, block, prim_index, lhs, modifiers, semantic, semantic_index, force_align);
+ prepend_input_copy(ctx, semantic_vars, block, prim_index, lhs, modifiers, semantic, force_align);
}
}
/* Split inputs into two variables representing the semantic and temp registers,
* and copy the former to the latter, so that writes to input variables work. */
-static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, struct hlsl_ir_var *var)
+static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_block *body,
+ struct list *semantic_vars, struct hlsl_ir_var *var)
{
+ struct hlsl_semantic semantic_copy;
struct hlsl_ir_load *load;
struct hlsl_block block;
@@ -550,15 +722,20 @@ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function
return;
hlsl_block_add_instr(&block, &load->node);
- prepend_input_copy_recurse(ctx, func, &block, 0, load, var->storage_modifiers,
- &var->semantic, var->semantic.index, false);
+ if (!hlsl_clone_semantic(ctx, &semantic_copy, &var->semantic))
+ {
+ hlsl_block_cleanup(&block);
+ return;
+ }
+ prepend_input_copy_recurse(ctx, semantic_vars, &block, 0, load, var->storage_modifiers, &semantic_copy, false);
+ hlsl_cleanup_semantic(&semantic_copy);
- list_move_head(&func->body.instrs, &block.instrs);
+ list_move_head(&body->instrs, &block.instrs);
}
static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block,
- struct hlsl_ir_function_decl *func, struct hlsl_ir_load *rhs, uint32_t modifiers,
- struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align, bool create)
+ struct list *semantic_vars, struct hlsl_ir_load *rhs, uint32_t modifiers,
+ struct hlsl_semantic *semantic, uint32_t stream_index, bool force_align, bool create)
{
struct hlsl_type *type = rhs->node.data_type, *vector_type;
struct vkd3d_shader_location *loc = &rhs->node.loc;
@@ -587,9 +764,10 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block,
struct hlsl_ir_var *output;
struct hlsl_ir_node *load;
- if (!(output = add_semantic_var(ctx, func, var, vector_type,
- modifiers, semantic, semantic_index + i, true, force_align, create, loc)))
+ if (!(output = add_semantic_var(ctx, semantic_vars, var, vector_type, modifiers,
+ semantic, stream_index, true, force_align, create, loc)))
return;
+ ++semantic->index;
if (type->class == HLSL_CLASS_MATRIX)
{
@@ -607,9 +785,9 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block,
}
}
-static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block,
- struct hlsl_ir_function_decl *func, const struct hlsl_type *type, struct hlsl_ir_load *rhs, uint32_t modifiers,
- struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align, bool create)
+static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, struct list *semantic_vars,
+ const struct hlsl_type *type, struct hlsl_ir_load *rhs, uint32_t modifiers, struct hlsl_semantic *semantic,
+ uint32_t stream_index, bool force_align, bool create)
{
struct vkd3d_shader_location *loc = &rhs->node.loc;
struct hlsl_ir_var *var = rhs->src.var;
@@ -620,63 +798,84 @@ static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *
{
for (i = 0; i < hlsl_type_element_count(type); ++i)
{
- uint32_t element_modifiers, elem_semantic_index;
const struct hlsl_type *element_type;
struct hlsl_ir_load *element_load;
struct hlsl_struct_field *field;
+ uint32_t element_modifiers;
+
+ if (type->class == HLSL_CLASS_STRUCT)
+ loc = &type->e.record.fields[i].loc;
+
+ c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc);
+ if (!(element_load = hlsl_new_load_index(ctx, &rhs->src, c, loc)))
+ return;
+ hlsl_block_add_instr(block, &element_load->node);
if (type->class == HLSL_CLASS_ARRAY)
{
- elem_semantic_index = semantic_index
- + i * hlsl_type_get_array_element_reg_size(type->e.array.type, HLSL_REGSET_NUMERIC) / 4;
element_type = type->e.array.type;
element_modifiers = modifiers;
force_align = true;
+
+ append_output_copy_recurse(ctx, block, semantic_vars, element_type, element_load,
+ element_modifiers, semantic, stream_index, force_align, create);
}
else
{
field = &type->e.record.fields[i];
if (hlsl_type_is_resource(field->type))
continue;
- validate_field_semantic(ctx, field);
- semantic = &field->semantic;
- elem_semantic_index = semantic->index;
- loc = &field->loc;
element_type = field->type;
element_modifiers = combine_field_storage_modifiers(modifiers, field->storage_modifiers);
force_align = (i == 0);
- }
- c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc);
+ if (semantic->name)
+ {
+ warn_on_field_semantic(ctx, field, semantic);
- if (!(element_load = hlsl_new_load_index(ctx, &rhs->src, c, loc)))
- return;
- hlsl_block_add_instr(block, &element_load->node);
+ append_output_copy_recurse(ctx, block, semantic_vars, element_type, element_load,
+ element_modifiers, semantic, stream_index, force_align, create);
+ }
+ else
+ {
+ struct hlsl_semantic semantic_copy;
+
+ validate_field_semantic(ctx, field);
- append_output_copy_recurse(ctx, block, func, element_type, element_load, element_modifiers, semantic,
- elem_semantic_index, force_align, create);
+ if (!hlsl_clone_semantic(ctx, &semantic_copy, &field->semantic))
+ continue;
+ append_output_copy_recurse(ctx, block, semantic_vars, element_type, element_load,
+ element_modifiers, &semantic_copy, stream_index, force_align, create);
+ hlsl_cleanup_semantic(&semantic_copy);
+ }
+ }
}
}
else
{
- append_output_copy(ctx, block, func, rhs, modifiers, semantic, semantic_index, force_align, create);
+ append_output_copy(ctx, block, semantic_vars, rhs, modifiers, semantic, stream_index, force_align, create);
}
}
/* Split outputs into two variables representing the temp and semantic
* registers, and copy the former to the latter, so that reads from output
* variables work. */
-static void append_output_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, struct hlsl_ir_var *var)
+static void append_output_var_copy(struct hlsl_ctx *ctx, struct hlsl_block *body,
+ struct list *semantic_vars, struct hlsl_ir_var *var)
{
+ struct hlsl_semantic semantic_copy;
struct hlsl_ir_load *load;
/* This redundant load is expected to be deleted later by DCE. */
if (!(load = hlsl_new_var_load(ctx, var, &var->loc)))
return;
- hlsl_block_add_instr(&func->body, &load->node);
+ hlsl_block_add_instr(body, &load->node);
- append_output_copy_recurse(ctx, &func->body, func, var->data_type, load, var->storage_modifiers,
- &var->semantic, var->semantic.index, false, true);
+ if (!hlsl_clone_semantic(ctx, &semantic_copy, &var->semantic))
+ return;
+ append_output_copy_recurse(ctx, body, semantic_vars, var->data_type,
+ load, var->storage_modifiers, &semantic_copy, 0, false, true);
+ hlsl_cleanup_semantic(&semantic_copy);
}
bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *),
@@ -1237,6 +1436,73 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
return true;
}
+ if (val->type == HLSL_IR_RESOURCE_LOAD)
+ {
+ struct hlsl_ir_resource_load *parent = hlsl_ir_resource_load(index->val.node);
+
+ if (parent->sampling_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
+ {
+ if (hlsl_index_is_noncontiguous(index))
+ {
+ /* For column major matrices, since we have to output a row,
+ * we need to emit dimx loads. */
+ struct hlsl_ir_node *mat = index->val.node;
+ struct hlsl_deref row_deref;
+
+ if (!(var = hlsl_new_synthetic_var(ctx, "row", instr->data_type, &instr->loc)))
+ return false;
+ hlsl_init_simple_deref_from_var(&row_deref, var);
+
+ for (unsigned int i = 0; i < mat->data_type->e.numeric.dimx; ++i)
+ {
+ struct hlsl_type *type = parent->node.data_type;
+ struct hlsl_ir_node *c, *c_offset, *idx_offset;
+ struct hlsl_ir_resource_load *column_load;
+
+ c = hlsl_block_add_uint_constant(ctx, block, i, &instr->loc);
+ c_offset = hlsl_block_add_packed_index_offset_append(ctx,
+ block, parent->byte_offset.node, c, type, &instr->loc);
+ type = hlsl_get_element_type_from_path_index(ctx, type, c);
+
+ idx_offset = hlsl_block_add_packed_index_offset_append(ctx,
+ block, c_offset, index->idx.node, type, &instr->loc);
+ type = hlsl_get_element_type_from_path_index(ctx, type, c_offset);
+
+ column_load = hlsl_ir_resource_load(hlsl_clone_instr(ctx, &parent->node));
+
+ hlsl_src_remove(&column_load->byte_offset);
+ hlsl_src_from_node(&column_load->byte_offset, idx_offset);
+ column_load->node.data_type = type;
+
+ hlsl_block_add_instr(block, &column_load->node);
+
+ hlsl_block_add_store_component(ctx, block, &row_deref, i, &column_load->node);
+ }
+
+ hlsl_block_add_simple_load(ctx, block, var, &instr->loc);
+ }
+ else
+ {
+ struct hlsl_type *type = parent->node.data_type;
+ struct hlsl_ir_resource_load *appended_load;
+ struct hlsl_ir_node *idx_offset;
+
+ idx_offset = hlsl_block_add_packed_index_offset_append(ctx, block,
+ parent->byte_offset.node, index->idx.node, type, &instr->loc);
+ appended_load = hlsl_ir_resource_load(hlsl_clone_instr(ctx, &parent->node));
+ type = hlsl_get_element_type_from_path_index(ctx, type, index->idx.node);
+
+ hlsl_src_remove(&appended_load->byte_offset);
+ hlsl_src_from_node(&appended_load->byte_offset, idx_offset);
+ appended_load->node.data_type = type;
+
+ hlsl_block_add_instr(block, &appended_load->node);
+ }
+
+ return true;
+ }
+ }
+
if (!(var = hlsl_new_synthetic_var(ctx, "index-val", val->data_type, &instr->loc)))
return false;
hlsl_init_simple_deref_from_var(&var_deref, var);
@@ -1315,6 +1581,67 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s
return false;
}
+/* Lowers loads from TGSMs to resource loads. */
+static bool lower_tgsm_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+{
+ struct hlsl_resource_load_params params = {.type = HLSL_RESOURCE_LOAD};
+ const struct vkd3d_shader_location *loc = &instr->loc;
+ struct hlsl_ir_load *load;
+ struct hlsl_deref *deref;
+
+ if (instr->type != HLSL_IR_LOAD || !hlsl_is_numeric_type(instr->data_type))
+ return false;
+ load = hlsl_ir_load(instr);
+ deref = &load->src;
+
+ if (!deref->var->is_tgsm)
+ return false;
+
+ if (deref->path_len)
+ {
+ hlsl_fixme(ctx, &instr->loc, "Load from indexed TGSM.");
+ return false;
+ }
+
+ params.resource = hlsl_block_add_simple_load(ctx, block, deref->var, loc);
+ params.format = instr->data_type;
+ params.coords = hlsl_block_add_uint_constant(ctx, block, 0, &instr->loc);
+ hlsl_block_add_resource_load(ctx, block, &params, loc);
+
+ return true;
+}
+
+/* Lowers stores to TGSMs to resource stores. */
+static bool lower_tgsm_stores(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
+{
+ struct hlsl_ir_store *store;
+ struct hlsl_ir_node *coords;
+ struct hlsl_deref res_deref;
+ struct hlsl_deref *deref;
+
+ if (instr->type != HLSL_IR_STORE)
+ return false;
+ store = hlsl_ir_store(instr);
+ deref = &store->lhs;
+
+ if (!deref->var->is_tgsm)
+ return false;
+
+ if (deref->path_len)
+ {
+ hlsl_fixme(ctx, &instr->loc, "Store to indexed TGSM.");
+ return false;
+ }
+
+ hlsl_init_simple_deref_from_var(&res_deref, deref->var);
+ coords = hlsl_block_add_uint_constant(ctx, block, 0, &instr->loc);
+
+ hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &res_deref,
+ coords, store->rhs.node, store->writemask, &instr->loc);
+
+ return true;
+}
+
/* Allocate a unique, ordered index to each instruction, which will be used for
* copy propagation and computing liveness ranges.
* Index 0 means unused, so start at 1. */
@@ -3146,10 +3473,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
{
struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr);
- if (!load->resource.var->is_uniform)
+ if (!load->resource.var->is_uniform && !load->resource.var->is_tgsm)
{
hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF,
- "Loaded resource must have a single uniform source.");
+ "Loaded resource must have a single uniform or groupshared source.");
}
else if (validate_component_index_range_from_deref(ctx, &load->resource) == DEREF_VALIDATION_NOT_CONSTANT)
{
@@ -3180,10 +3507,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
{
struct hlsl_ir_resource_store *store = hlsl_ir_resource_store(instr);
- if (!store->resource.var->is_uniform)
+ if (!store->resource.var->is_uniform && !store->resource.var->is_tgsm)
{
hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF,
- "Accessed resource must have a single uniform source.");
+ "Accessed resource must have a single uniform or groupshared source.");
}
else if (validate_component_index_range_from_deref(ctx, &store->resource) == DEREF_VALIDATION_NOT_CONSTANT)
{
@@ -3210,10 +3537,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
{
struct hlsl_ir_interlocked *interlocked = hlsl_ir_interlocked(instr);
- if (!interlocked->dst.var->is_uniform)
+ if (!interlocked->dst.var->is_uniform && !interlocked->dst.var->is_tgsm)
{
hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF,
- "Accessed resource must have a single uniform source.");
+ "Accessed resource must have a single uniform or groupshared source.");
}
else if (validate_component_index_range_from_deref(ctx, &interlocked->dst) == DEREF_VALIDATION_NOT_CONSTANT)
{
@@ -3359,18 +3686,20 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
struct stream_append_ctx
{
- struct hlsl_ir_function_decl *func;
- bool created;
+ struct list *semantic_vars;
+ bool created[VKD3D_MAX_STREAM_COUNT];
};
static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
{
struct stream_append_ctx *append_ctx = context;
struct hlsl_ir_resource_store *store;
+ struct hlsl_semantic semantic_copy;
const struct hlsl_ir_node *rhs;
const struct hlsl_type *type;
struct hlsl_ir_var *var;
struct hlsl_block block;
+ uint32_t stream_index;
if (instr->type != HLSL_IR_RESOURCE_STORE)
return false;
@@ -3390,24 +3719,49 @@ static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst
}
VKD3D_ASSERT(var->regs[HLSL_REGSET_STREAM_OUTPUTS].allocated);
+ stream_index = var->regs[HLSL_REGSET_STREAM_OUTPUTS].index;
- if (var->regs[HLSL_REGSET_STREAM_OUTPUTS].index)
- {
- hlsl_fixme(ctx, &instr->loc, "Append to an output stream with a nonzero stream index.");
- return false;
- }
+ VKD3D_ASSERT(stream_index < ARRAY_SIZE(append_ctx->created));
hlsl_block_init(&block);
- append_output_copy_recurse(ctx, &block, append_ctx->func, type->e.so.type, hlsl_ir_load(rhs), var->storage_modifiers,
- &var->semantic, var->semantic.index, false, !append_ctx->created);
- append_ctx->created = true;
+ if (!hlsl_clone_semantic(ctx, &semantic_copy, &var->semantic))
+ return false;
+ append_output_copy_recurse(ctx, &block, append_ctx->semantic_vars, type->e.so.type, hlsl_ir_load(rhs),
+ var->storage_modifiers, &semantic_copy, var->regs[HLSL_REGSET_STREAM_OUTPUTS].index,
+ false, !append_ctx->created[stream_index]);
+ hlsl_cleanup_semantic(&semantic_copy);
+
+ append_ctx->created[stream_index] = true;
list_move_before(&instr->entry, &block.instrs);
hlsl_src_remove(&store->value);
return true;
+}
+
+static void split_resource_load(struct hlsl_ctx *ctx, struct hlsl_ir_store *store,
+ struct hlsl_ir_resource_load *load, const unsigned int idx, struct hlsl_type *type)
+{
+ struct hlsl_ir_resource_load *vector_load;
+ struct hlsl_ir_node *c, *idx_offset;
+ struct hlsl_block block;
+
+ hlsl_block_init(&block);
+ c = hlsl_block_add_uint_constant(ctx, &block, idx, &store->node.loc);
+ idx_offset = hlsl_block_add_packed_index_offset_append(ctx, &block,
+ load->byte_offset.node, c, load->node.data_type, &store->node.loc);
+
+ vector_load = hlsl_ir_resource_load(hlsl_clone_instr(ctx, &load->node));
+ hlsl_src_remove(&vector_load->byte_offset);
+ hlsl_src_from_node(&vector_load->byte_offset, idx_offset);
+ vector_load->node.data_type = type;
+ hlsl_block_add_instr(&block, &vector_load->node);
+
+ hlsl_block_add_store_index(ctx, &block, &store->lhs, c, &vector_load->node, 0, &store->node.loc);
+
+ list_move_before(&store->node.entry, &block.instrs);
}
static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
@@ -3428,16 +3782,32 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
return false;
element_type = hlsl_get_vector_type(ctx, type->e.numeric.type, hlsl_type_minor_size(type));
- if (rhs->type != HLSL_IR_LOAD)
+ if (rhs->type != HLSL_IR_LOAD && rhs->type != HLSL_IR_RESOURCE_LOAD)
{
hlsl_fixme(ctx, &instr->loc, "Copying from unsupported node type.");
return false;
}
- for (i = 0; i < hlsl_type_major_size(type); ++i)
+ if (rhs->type == HLSL_IR_RESOURCE_LOAD)
{
- if (!split_copy(ctx, store, hlsl_ir_load(rhs), i, element_type))
- return false;
+ /* As we forbid non-scalar or vector types in non-structured resource
+ * loads, this is specific to structured buffer loads. */
+ struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(rhs);
+
+ VKD3D_ASSERT(hlsl_deref_get_type(ctx, &load->resource)->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER);
+
+ for (i = 0; i < hlsl_type_major_size(type); ++i)
+ {
+ split_resource_load(ctx, store, load, i, element_type);
+ }
+ }
+ else
+ {
+ for (i = 0; i < hlsl_type_major_size(type); ++i)
+ {
+ if (!split_copy(ctx, store, hlsl_ir_load(rhs), i, element_type))
+ return false;
+ }
}
list_remove(&store->node.entry);
@@ -3919,7 +4289,7 @@ static bool lower_separate_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
if (load->texel_offset.node)
{
hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
- "Texel offsets are not supported on profiles lower than 4.0.\n");
+ "Texel offsets are not supported on profiles lower than 4.0.");
return false;
}
@@ -5223,7 +5593,7 @@ static void dump_function(struct rb_entry *entry, void *context)
LIST_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry)
{
if (decl->has_body)
- hlsl_dump_function(ctx, decl);
+ hlsl_dump_function(ctx, decl, "function", NULL);
}
}
@@ -5240,7 +5610,7 @@ static bool mark_indexable_var(struct hlsl_ctx *ctx, struct hlsl_deref *deref,
return true;
}
-static void mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func)
+static void mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_block *body)
{
struct hlsl_scope *scope;
struct hlsl_ir_var *var;
@@ -5251,7 +5621,7 @@ static void mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_ir_function_de
var->indexable = false;
}
- transform_derefs(ctx, mark_indexable_var, &entry_func->body);
+ transform_derefs(ctx, mark_indexable_var, body);
}
static char get_regset_name(enum hlsl_regset regset)
@@ -5411,6 +5781,8 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop
deref_mark_last_read(&load->sampler, last_read);
}
+ if (load->byte_offset.node)
+ load->byte_offset.node->last_read = last_read;
if (load->coords.node)
load->coords.node->last_read = last_read;
if (load->texel_offset.node)
@@ -5498,7 +5870,7 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop
}
}
-static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func)
+static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_block *body)
{
struct hlsl_scope *scope;
struct hlsl_ir_var *var;
@@ -5506,7 +5878,7 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
if (ctx->result)
return;
- index_instructions(&entry_func->body, 1);
+ index_instructions(body, 1);
LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry)
{
@@ -5514,7 +5886,7 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
var->first_write = var->last_read = 0;
}
- compute_liveness_recurse(&entry_func->body, 0, 0);
+ compute_liveness_recurse(body, 0, 0);
}
static void mark_vars_usage(struct hlsl_ctx *ctx)
@@ -5648,6 +6020,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a
unsigned int writemask = hlsl_combine_writemasks(available_writemask,
vkd3d_write_mask_from_component_count(reg_size));
+ ret.type = VKD3DSPR_TEMP;
ret.id = reg_idx;
ret.writemask = hlsl_combine_writemasks(writemask,
vkd3d_write_mask_from_component_count(component_count));
@@ -5658,6 +6031,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a
}
}
+ ret.type = VKD3DSPR_TEMP;
ret.id = allocator->reg_count;
ret.writemask = vkd3d_write_mask_from_component_count(component_count);
record_allocation(ctx, allocator, allocator->reg_count,
@@ -5684,6 +6058,7 @@ static struct hlsl_reg allocate_register_with_masks(struct hlsl_ctx *ctx,
record_allocation(ctx, allocator, reg_idx, reg_writemask, first_write, last_read, mode, vip);
+ ret.type = VKD3DSPR_TEMP;
ret.id = reg_idx;
ret.allocation_size = 1;
ret.writemask = writemask;
@@ -5729,6 +6104,7 @@ static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allo
record_allocation(ctx, allocator, reg_idx + (reg_size / 4),
(1u << (reg_size % 4)) - 1, first_write, last_read, mode, vip);
+ ret.type = VKD3DSPR_TEMP;
ret.id = reg_idx;
ret.allocation_size = align(reg_size, 4) / 4;
ret.allocated = true;
@@ -5749,20 +6125,30 @@ static struct hlsl_reg allocate_numeric_registers_for_type(struct hlsl_ctx *ctx,
return allocate_range(ctx, allocator, first_write, last_read, reg_size, 0, false);
}
-static const char *debug_register(char class, struct hlsl_reg reg, const struct hlsl_type *type)
+static const char *debug_register(struct hlsl_reg reg, const struct hlsl_type *type)
{
static const char writemask_offset[] = {'w','x','y','z'};
unsigned int reg_size = type->reg_size[HLSL_REGSET_NUMERIC];
+ const char *class = "r";
- if (reg_size > 4)
+ if (reg.type == VKD3DSPR_CONST)
+ class = "c";
+ else if (reg.type == VKD3DSPR_INPUT)
+ class = "v";
+ else if (reg.type == VKD3DSPR_OUTPUT)
+ class = "o";
+ else if (reg.type == VKD3DSPR_SSA)
+ class = "sr";
+
+ if (reg_size > 4 && !hlsl_type_is_patch_array(type))
{
if (reg_size & 3)
- return vkd3d_dbg_sprintf("%c%u-%c%u.%c", class, reg.id, class, reg.id + (reg_size / 4),
+ return vkd3d_dbg_sprintf("%s%u-%s%u.%c", class, reg.id, class, reg.id + (reg_size / 4),
writemask_offset[reg_size & 3]);
- return vkd3d_dbg_sprintf("%c%u-%c%u", class, reg.id, class, reg.id + (reg_size / 4) - 1);
+ return vkd3d_dbg_sprintf("%s%u-%s%u", class, reg.id, class, reg.id + (reg_size / 4) - 1);
}
- return vkd3d_dbg_sprintf("%c%u%s", class, reg.id, debug_hlsl_writemask(reg.writemask));
+ return vkd3d_dbg_sprintf("%s%u%s", class, reg.id, debug_hlsl_writemask(reg.writemask));
}
static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
@@ -5778,6 +6164,9 @@ static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hls
load = hlsl_ir_resource_load(instr);
var = load->resource.var;
+ if (var->is_tgsm)
+ return false;
+
regset = hlsl_deref_get_regset(ctx, &load->resource);
if (!hlsl_regset_index_from_deref(ctx, &load->resource, regset, &index))
return false;
@@ -5846,7 +6235,7 @@ static bool track_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
{
struct hlsl_ir_load *load = hlsl_ir_load(instr);
- if (!load->src.var->is_uniform)
+ if (!load->src.var->is_uniform && !load->src.var->is_tgsm)
return false;
/* These will are handled by validate_static_object_references(). */
@@ -5902,11 +6291,12 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx,
struct hlsl_ir_node *instr, struct register_allocator *allocator)
{
unsigned int reg_writemask = 0, dst_writemask = 0;
+ bool is_per_component = false;
if (instr->reg.allocated || !instr->last_read)
return;
- if (instr->type == HLSL_IR_EXPR)
+ if (instr->type == HLSL_IR_EXPR && ctx->profile->major_version < 4)
{
switch (hlsl_ir_expr(instr)->op)
{
@@ -5920,20 +6310,42 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx,
reg_writemask = ctx->profile->major_version < 3 ? (1 << 3) - 1 : VKD3DSP_WRITEMASK_1;
break;
+ case HLSL_OP1_EXP2:
+ case HLSL_OP1_LOG2:
+ case HLSL_OP1_RCP:
+ case HLSL_OP1_RSQ:
+ /* These ops can only be written one component at a time in sm1,
+ * so it'll take more than one instruction to fill the variable
+ * and thus we can't use an SSA.
+ * FIXME: We should probably handle this by splitting at the vsir
+ * level instead. */
+ is_per_component = true;
+ break;
+
default:
break;
}
}
+ VKD3D_ASSERT(instr->data_type->class <= HLSL_CLASS_VECTOR);
+
if (reg_writemask)
- instr->reg = allocate_register_with_masks(ctx, allocator, instr->index,
- instr->last_read, reg_writemask, dst_writemask, 0, false);
- else
+ instr->reg = allocate_register_with_masks(ctx, allocator,
+ instr->index, instr->last_read, reg_writemask, dst_writemask, 0, false);
+ else if (is_per_component)
instr->reg = allocate_numeric_registers_for_type(ctx, allocator,
instr->index, instr->last_read, instr->data_type);
+ else
+ {
+ instr->reg.writemask = vkd3d_write_mask_from_component_count(instr->data_type->e.numeric.dimx);
+ instr->reg.allocation_size = 1;
+ instr->reg.allocated = true;
+ instr->reg.type = VKD3DSPR_SSA;
+ instr->reg.id = ctx->ssa_count++;
+ }
TRACE("Allocated anonymous expression @%u to %s (liveness %u-%u).\n", instr->index,
- debug_register('r', instr->reg, instr->data_type), instr->index, instr->last_read);
+ debug_register(instr->reg, instr->data_type), instr->index, instr->last_read);
}
static void allocate_variable_temp_register(struct hlsl_ctx *ctx,
@@ -5958,8 +6370,8 @@ static void allocate_variable_temp_register(struct hlsl_ctx *ctx,
var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, allocator,
var->first_write, var->last_read, var->data_type);
- TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, debug_register('r',
- var->regs[HLSL_REGSET_NUMERIC], var->data_type), var->first_write, var->last_read);
+ TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name,
+ debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type), var->first_write, var->last_read);
}
}
}
@@ -6043,6 +6455,7 @@ static bool find_constant(struct hlsl_ctx *ctx, const float *f, unsigned int cou
if ((reg->allocated_mask & writemask) == writemask
&& !memcmp(f, &reg->value.f[j], count * sizeof(float)))
{
+ ret->type = VKD3DSPR_CONST;
ret->id = reg->index;
ret->allocation_size = 1;
ret->writemask = writemask;
@@ -6136,12 +6549,13 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx,
if (find_constant(ctx, f, type->e.numeric.dimx, &constant->reg))
{
TRACE("Reusing already allocated constant %s for @%u.\n",
- debug_register('c', constant->reg, type), instr->index);
+ debug_register(constant->reg, type), instr->index);
break;
}
constant->reg = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type);
- TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register('c', constant->reg, type));
+ constant->reg.type = VKD3DSPR_CONST;
+ TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register(constant->reg, type));
for (unsigned int x = 0, i = 0; x < 4; ++x)
{
@@ -6238,14 +6652,16 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl
type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4);
ctx->d3dsincosconst1 = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type);
- TRACE("Allocated D3DSINCOSCONST1 to %s.\n", debug_register('c', ctx->d3dsincosconst1, type));
+ ctx->d3dsincosconst1.type = VKD3DSPR_CONST;
+ TRACE("Allocated D3DSINCOSCONST1 to %s.\n", debug_register(ctx->d3dsincosconst1, type));
record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 0, -1.55009923e-06f, &instr->loc);
record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 1, -2.17013894e-05f, &instr->loc);
record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 2, 2.60416674e-03f, &instr->loc);
record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 3, 2.60416680e-04f, &instr->loc);
ctx->d3dsincosconst2 = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type);
- TRACE("Allocated D3DSINCOSCONST2 to %s.\n", debug_register('c', ctx->d3dsincosconst2, type));
+ ctx->d3dsincosconst2.type = VKD3DSPR_CONST;
+ TRACE("Allocated D3DSINCOSCONST2 to %s.\n", debug_register(ctx->d3dsincosconst2, type));
record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 0, -2.08333340e-02f, &instr->loc);
record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 1, -1.25000000e-01f, &instr->loc);
record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 2, 1.00000000e+00f, &instr->loc);
@@ -6256,7 +6672,7 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl
}
}
-static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func)
+static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *body)
{
struct register_allocator allocator_used = {0};
struct register_allocator allocator = {0};
@@ -6293,12 +6709,13 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi
record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false);
}
+ var->regs[HLSL_REGSET_NUMERIC].type = VKD3DSPR_CONST;
var->regs[HLSL_REGSET_NUMERIC].id = reg_idx;
var->regs[HLSL_REGSET_NUMERIC].allocation_size = reg_size / 4;
var->regs[HLSL_REGSET_NUMERIC].writemask = VKD3DSP_WRITEMASK_ALL;
var->regs[HLSL_REGSET_NUMERIC].allocated = true;
TRACE("Allocated reserved %s to %s.\n", var->name,
- debug_register('c', var->regs[HLSL_REGSET_NUMERIC], var->data_type));
+ debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type));
}
}
@@ -6314,14 +6731,15 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi
if (!var->regs[HLSL_REGSET_NUMERIC].allocated)
{
var->regs[HLSL_REGSET_NUMERIC] = allocate_range(ctx, &allocator, 1, UINT_MAX, alloc_size, 0, false);
+ var->regs[HLSL_REGSET_NUMERIC].type = VKD3DSPR_CONST;
TRACE("Allocated %s to %s.\n", var->name,
- debug_register('c', var->regs[HLSL_REGSET_NUMERIC], var->data_type));
+ debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type));
}
}
- allocate_const_registers_recurse(ctx, &entry_func->body, &allocator);
+ allocate_const_registers_recurse(ctx, body, &allocator);
- allocate_sincos_const_registers(ctx, &entry_func->body, &allocator);
+ allocate_sincos_const_registers(ctx, body, &allocator);
vkd3d_free(allocator.allocations);
}
@@ -6330,7 +6748,7 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi
* index to all (simultaneously live) variables or intermediate values. Agnostic
* as to how many registers are actually available for the current backend, and
* does not handle constants. */
-static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func)
+static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block *body, struct list *semantic_vars)
{
struct register_allocator allocator = {0};
struct hlsl_scope *scope;
@@ -6341,7 +6759,7 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun
{
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
{
- if (!(var->is_input_semantic || var->is_output_semantic || var->is_uniform))
+ if (!(var->is_input_semantic || var->is_output_semantic || var->is_uniform || var->is_tgsm))
memset(var->regs, 0, sizeof(var->regs));
}
}
@@ -6349,7 +6767,7 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun
/* ps_1_* outputs are special and go in temp register 0. */
if (ctx->profile->major_version == 1 && ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL)
{
- LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry)
+ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry)
{
if (var->is_output_semantic)
{
@@ -6360,15 +6778,16 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun
}
}
- allocate_temp_registers_recurse(ctx, &entry_func->body, &allocator);
+ allocate_temp_registers_recurse(ctx, body, &allocator);
vkd3d_free(allocator.allocations);
if (allocator.indexable_count)
- TRACE("Declaration of function \"%s\" required %u temp registers, and %u indexable temps.\n",
- entry_func->func->name, allocator.reg_count, allocator.indexable_count);
+ TRACE("Declaration of %s function required %u temp registers, and %u indexable temps.\n",
+ ctx->is_patch_constant_func ? "patch constant" : "main",
+ allocator.reg_count, allocator.indexable_count);
else
- TRACE("Declaration of function \"%s\" required %u temp registers.\n",
- entry_func->func->name, allocator.reg_count);
+ TRACE("Declaration of %s function required %u temp registers.\n",
+ ctx->is_patch_constant_func ? "patch constant" : "main", allocator.reg_count);
return allocator.reg_count;
}
@@ -6456,6 +6875,8 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var
if ((!output && !var->last_read) || (output && !var->first_write))
return;
+
+ optimize = false;
}
else
{
@@ -6509,17 +6930,17 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var
var->regs[HLSL_REGSET_NUMERIC] = allocate_register(ctx, allocator, 1, UINT_MAX,
reg_size, component_count, mode, var->force_align, vip_allocation);
+ var->regs[HLSL_REGSET_NUMERIC].type = output ? VKD3DSPR_OUTPUT : VKD3DSPR_INPUT;
- TRACE("Allocated %s to %s (mode %d).\n", var->name, debug_register(output ? 'o' : 'v',
- var->regs[HLSL_REGSET_NUMERIC], var->data_type), mode);
+ TRACE("Allocated %s to %s (mode %d).\n", var->name,
+ debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type), mode);
}
}
-static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
- uint32_t *output_reg_count)
+static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct list *semantic_vars, uint32_t *output_reg_count)
{
+ struct register_allocator input_allocator = {0}, output_allocators[VKD3D_MAX_STREAM_COUNT] = {{0}};
struct register_allocator in_prim_allocator = {0}, patch_constant_out_patch_allocator = {0};
- struct register_allocator input_allocator = {0}, output_allocator = {0};
bool is_vertex_shader = ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX;
bool is_pixel_shader = ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL;
struct hlsl_ir_var *var;
@@ -6527,9 +6948,10 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun
in_prim_allocator.prioritize_smaller_writemasks = true;
patch_constant_out_patch_allocator.prioritize_smaller_writemasks = true;
input_allocator.prioritize_smaller_writemasks = true;
- output_allocator.prioritize_smaller_writemasks = true;
+ for (unsigned int i = 0; i < ARRAY_SIZE(output_allocators); ++i)
+ output_allocators[i].prioritize_smaller_writemasks = true;
- LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry)
+ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry)
{
if (var->is_input_semantic)
{
@@ -6550,15 +6972,22 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun
}
if (var->is_output_semantic)
- allocate_semantic_register(ctx, var, &output_allocator, true, !is_pixel_shader);
+ {
+ VKD3D_ASSERT(var->semantic.stream_index < ARRAY_SIZE(output_allocators));
+ allocate_semantic_register(ctx, var, &output_allocators[var->semantic.stream_index],
+ true, !is_pixel_shader);
+ }
}
- *output_reg_count = output_allocator.reg_count;
+ *output_reg_count = output_allocators[0].reg_count;
+ for (unsigned int i = 1; i < ARRAY_SIZE(output_allocators); ++i)
+ *output_reg_count = max(*output_reg_count, output_allocators[i].reg_count);
vkd3d_free(in_prim_allocator.allocations);
vkd3d_free(patch_constant_out_patch_allocator.allocations);
vkd3d_free(input_allocator.allocations);
- vkd3d_free(output_allocator.allocations);
+ for (unsigned int i = 0; i < ARRAY_SIZE(output_allocators); ++i)
+ vkd3d_free(output_allocators[i].allocations);
}
static const struct hlsl_buffer *get_reserved_buffer(struct hlsl_ctx *ctx,
@@ -6863,7 +7292,7 @@ static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum
return NULL;
}
-static void allocate_objects(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, enum hlsl_regset regset)
+static void allocate_objects(struct hlsl_ctx *ctx, struct list *semantic_vars, enum hlsl_regset regset)
{
char regset_name = get_regset_name(regset);
uint32_t min_index = 0, id = 0;
@@ -6871,7 +7300,7 @@ static void allocate_objects(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
if (regset == HLSL_REGSET_UAVS && ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL)
{
- LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry)
+ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry)
{
if (var->semantic.name && (!ascii_strcasecmp(var->semantic.name, "color")
|| !ascii_strcasecmp(var->semantic.name, "sv_target")))
@@ -6980,6 +7409,27 @@ static void allocate_stream_outputs(struct hlsl_ctx *ctx)
}
}
+static void allocate_tgsms(struct hlsl_ctx *ctx)
+{
+ struct hlsl_ir_var *var;
+ struct hlsl_reg *reg;
+ uint32_t index = 0;
+
+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+ {
+ if (!var->is_tgsm || !var->bind_count[HLSL_REGSET_NUMERIC])
+ continue;
+
+ reg = &var->regs[HLSL_REGSET_NUMERIC];
+ reg->space = 0;
+ reg->index = index;
+ reg->id = index;
+ reg->allocated = true;
+
+ ++index;
+ }
+}
+
bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref,
unsigned int *start, unsigned int *count)
{
@@ -7420,6 +7870,8 @@ static void parse_entry_function_attributes(struct hlsl_ctx *ctx, struct hlsl_ir
entry_func->early_depth_test = true;
else if (!strcmp(attr->name, "maxvertexcount") && profile->type == VKD3D_SHADER_TYPE_GEOMETRY)
parse_maxvertexcount_attribute(ctx, attr);
+ else if (!strcmp(attr->name, "instance") && profile->type == VKD3D_SHADER_TYPE_GEOMETRY)
+ hlsl_fixme(ctx, &entry_func->attrs[i]->loc, "Geometry shader instance count");
else
hlsl_warning(ctx, &entry_func->attrs[i]->loc, VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE,
"Ignoring unknown attribute \"%s\".", entry_func->attrs[i]->name);
@@ -7715,12 +8167,10 @@ static void validate_and_record_stream_outputs(struct hlsl_ctx *ctx)
reported_invalid_index = true;
}
}
-
- /* TODO: check that maxvertexcount * outputdatasize <= 1024. */
}
-static void validate_max_output_size(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
- uint32_t output_reg_count)
+static void validate_max_output_size(struct hlsl_ctx *ctx, struct list *semantic_vars,
+ uint32_t output_reg_count, const struct vkd3d_shader_location *loc)
{
unsigned int max_output_size, comp_count = 0;
unsigned int *reg_comp_count;
@@ -7733,7 +8183,7 @@ static void validate_max_output_size(struct hlsl_ctx *ctx, struct hlsl_ir_functi
if (!(reg_comp_count = hlsl_calloc(ctx, output_reg_count, sizeof(*reg_comp_count))))
return;
- LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry)
+ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry)
{
if (!var->is_output_semantic)
continue;
@@ -7748,7 +8198,7 @@ static void validate_max_output_size(struct hlsl_ctx *ctx, struct hlsl_ir_functi
max_output_size = ctx->max_vertex_count * comp_count;
if (max_output_size > 1024)
- hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT,
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT,
"Max vertex count (%u) * output data component count (%u) = %u, which is greater than 1024.",
ctx->max_vertex_count, comp_count, max_output_size);
@@ -7960,8 +8410,19 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog
if ((!output && !var->last_read) || (output && !var->first_write))
return;
- if (!sm1_register_from_semantic_name(&program->shader_version,
+ if (sm1_register_from_semantic_name(&program->shader_version,
var->semantic.name, var->semantic.index, output, &sysval, &type, &register_index))
+ {
+ if (!vkd3d_shader_ver_ge(&program->shader_version, 3, 0))
+ {
+ if (type == VKD3DSPR_RASTOUT)
+ register_index += SM1_RASTOUT_REGISTER_OFFSET;
+ else if (type == VKD3DSPR_ATTROUT
+ || (type == VKD3DSPR_INPUT && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL))
+ register_index += SM1_COLOR_REGISTER_OFFSET;
+ }
+ }
+ else
{
enum vkd3d_decl_usage usage;
unsigned int usage_idx;
@@ -8018,6 +8479,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog
return;
}
element->semantic_index = var->semantic.index;
+ element->stream_index = var->semantic.stream_index;
element->sysval_semantic = sysval;
element->component_type = component_type;
element->register_index = register_index;
@@ -8050,15 +8512,15 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog
}
}
-static void generate_vsir_signature(struct hlsl_ctx *ctx,
- struct vsir_program *program, struct hlsl_ir_function_decl *func)
+static void generate_vsir_signature(struct hlsl_ctx *ctx, struct vsir_program *program,
+ struct hlsl_ir_function_decl *func, struct list *semantic_vars)
{
bool is_domain = program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN;
struct hlsl_ir_var *var;
ctx->is_patch_constant_func = func == ctx->patch_constant_func;
- LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry)
+ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry)
{
if (var->is_input_semantic)
{
@@ -8092,38 +8554,38 @@ static void generate_vsir_signature(struct hlsl_ctx *ctx,
}
}
-static enum vkd3d_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type)
+static enum vsir_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type)
{
if (hlsl_version_lt(ctx, 4, 0))
- return VKD3D_DATA_FLOAT;
+ return VSIR_DATA_F32;
if (type->class == HLSL_CLASS_ARRAY)
return vsir_data_type_from_hlsl_type(ctx, type->e.array.type);
if (type->class == HLSL_CLASS_STRUCT)
- return VKD3D_DATA_MIXED;
+ return VSIR_DATA_MIXED;
if (type->class <= HLSL_CLASS_LAST_NUMERIC)
{
switch (type->e.numeric.type)
{
case HLSL_TYPE_DOUBLE:
- return VKD3D_DATA_DOUBLE;
+ return VSIR_DATA_F64;
case HLSL_TYPE_FLOAT:
- return VKD3D_DATA_FLOAT;
+ return VSIR_DATA_F32;
case HLSL_TYPE_HALF:
- return VKD3D_DATA_HALF;
+ return VSIR_DATA_F16;
case HLSL_TYPE_INT:
- return VKD3D_DATA_INT;
+ return VSIR_DATA_I32;
case HLSL_TYPE_UINT:
case HLSL_TYPE_BOOL:
case HLSL_TYPE_MIN16UINT:
- return VKD3D_DATA_UINT;
+ return VSIR_DATA_U32;
}
}
- vkd3d_unreachable();
+ return VSIR_DATA_UNUSED;
}
-static enum vkd3d_data_type vsir_data_type_from_hlsl_instruction(struct hlsl_ctx *ctx,
+static enum vsir_data_type vsir_data_type_from_hlsl_instruction(struct hlsl_ctx *ctx,
const struct hlsl_ir_node *instr)
{
return vsir_data_type_from_hlsl_type(ctx, instr->data_type);
@@ -8141,7 +8603,6 @@ static uint32_t generate_vsir_get_src_swizzle(uint32_t src_writemask, uint32_t d
static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_program *program,
struct hlsl_block *block)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
struct vkd3d_shader_dst_param *dst_param;
struct vkd3d_shader_src_param *src_param;
struct vkd3d_shader_instruction *ins;
@@ -8151,32 +8612,30 @@ static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_pr
{
const struct hlsl_constant_register *constant_reg = &ctx->constant_defs.regs[i];
- if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
+ if (!(ins = vsir_program_append(program)))
{
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
return;
}
-
- ins = &instructions->elements[instructions->count];
- if (!vsir_instruction_init_with_params(program, ins, &constant_reg->loc, VKD3DSIH_DEF, 1, 1))
+ if (!vsir_instruction_init_with_params(program, ins, &constant_reg->loc, VSIR_OP_DEF, 1, 1))
{
+ vsir_instruction_init(ins, &constant_reg->loc, VSIR_OP_NOP);
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
return;
}
- ++instructions->count;
dst_param = &ins->dst[0];
- vsir_register_init(&dst_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1);
+ vsir_register_init(&dst_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1);
ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
ins->dst[0].reg.idx[0].offset = constant_reg->index;
ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL;
src_param = &ins->src[0];
- vsir_register_init(&src_param->reg, VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0);
+ vsir_register_init(&src_param->reg, VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0);
src_param->reg.type = VKD3DSPR_IMMCONST;
src_param->reg.precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT;
src_param->reg.non_uniform = false;
- src_param->reg.data_type = VKD3D_DATA_FLOAT;
+ src_param->reg.data_type = VSIR_DATA_F32;
src_param->reg.dimension = VSIR_DIMENSION_VEC4;
for (x = 0; x < 4; ++x)
src_param->reg.u.immconst_f32[x] = constant_reg->value.f[x];
@@ -8187,7 +8646,6 @@ static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_pr
static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx,
struct vsir_program *program, struct hlsl_block *block)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
enum vkd3d_shader_resource_type resource_type;
struct vkd3d_shader_register_range *range;
struct vkd3d_shader_dst_param *dst_param;
@@ -8234,25 +8692,18 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx,
break;
}
- if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
- {
- ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
- return;
- }
-
- ins = &instructions->elements[instructions->count];
- if (!vsir_instruction_init_with_params(program, ins, &var->loc, VKD3DSIH_DCL, 0, 0))
+ if (!(ins = vsir_program_append(program)))
{
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
return;
}
- ++instructions->count;
+ vsir_instruction_init(ins, &var->loc, VSIR_OP_DCL);
semantic = &ins->declaration.semantic;
semantic->resource_type = resource_type;
dst_param = &semantic->resource.reg;
- vsir_register_init(&dst_param->reg, VKD3DSPR_SAMPLER, VKD3D_DATA_FLOAT, 1);
+ vsir_register_init(&dst_param->reg, VKD3DSPR_SAMPLER, VSIR_DATA_F32, 1);
dst_param->reg.dimension = VSIR_DIMENSION_NONE;
dst_param->reg.idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].index + i;
dst_param->write_mask = 0;
@@ -8297,32 +8748,31 @@ static enum vkd3d_shader_register_type sm4_get_semantic_register_type(enum vkd3d
return VKD3DSPR_INPUT;
}
-static struct vkd3d_shader_instruction *generate_vsir_add_program_instruction(
- struct hlsl_ctx *ctx, struct vsir_program *program,
- const struct vkd3d_shader_location *loc, enum vkd3d_shader_opcode opcode,
- unsigned int dst_count, unsigned int src_count)
+static struct vkd3d_shader_instruction *generate_vsir_add_program_instruction(struct hlsl_ctx *ctx,
+ struct vsir_program *program, const struct vkd3d_shader_location *loc,
+ enum vkd3d_shader_opcode opcode, unsigned int dst_count, unsigned int src_count)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
struct vkd3d_shader_instruction *ins;
- if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
+ if (!(ins = vsir_program_append(program)))
{
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
return NULL;
}
- ins = &instructions->elements[instructions->count];
+
if (!vsir_instruction_init_with_params(program, ins, loc, opcode, dst_count, src_count))
{
+ vsir_instruction_init(ins, loc, VSIR_OP_NOP);
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
return NULL;
}
- ++instructions->count;
+
return ins;
}
static void vsir_src_from_hlsl_constant_value(struct vkd3d_shader_src_param *src,
struct hlsl_ctx *ctx, const struct hlsl_constant_value *value,
- enum vkd3d_data_type type, unsigned int width, unsigned int map_writemask)
+ enum vsir_data_type type, unsigned int width, unsigned int map_writemask)
{
unsigned int i, j;
@@ -8357,7 +8807,7 @@ static void vsir_src_from_hlsl_node(struct vkd3d_shader_src_param *src,
}
else
{
- vsir_register_init(&src->reg, VKD3DSPR_TEMP, vsir_data_type_from_hlsl_instruction(ctx, instr), 1);
+ vsir_register_init(&src->reg, instr->reg.type, vsir_data_type_from_hlsl_instruction(ctx, instr), 1);
src->reg.idx[0].offset = instr->reg.id;
src->reg.dimension = VSIR_DIMENSION_VEC4;
src->swizzle = generate_vsir_get_src_swizzle(instr->reg.writemask, map_writemask);
@@ -8424,6 +8874,8 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p
const struct hlsl_type *data_type = hlsl_deref_get_type(ctx, deref);
const struct hlsl_ir_var *var = deref->var;
+ reg->data_type = vsir_data_type_from_hlsl_type(ctx, data_type);
+
if (var->is_uniform)
{
enum hlsl_regset regset = hlsl_deref_get_regset(ctx, deref);
@@ -8432,18 +8884,10 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p
{
reg->type = VKD3DSPR_RESOURCE;
reg->dimension = VSIR_DIMENSION_VEC4;
- if (vkd3d_shader_ver_ge(version, 5, 1))
- {
- reg->idx[0].offset = var->regs[HLSL_REGSET_TEXTURES].id;
- reg->idx[1].offset = var->regs[HLSL_REGSET_TEXTURES].index; /* FIXME: array index */
- reg->idx_count = 2;
- }
- else
- {
- reg->idx[0].offset = var->regs[HLSL_REGSET_TEXTURES].index;
- reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref);
- reg->idx_count = 1;
- }
+ reg->idx[0].offset = var->regs[HLSL_REGSET_TEXTURES].id;
+ reg->idx[1].offset = var->regs[HLSL_REGSET_TEXTURES].index;
+ reg->idx[1].offset += hlsl_offset_from_deref_safe(ctx, deref);
+ reg->idx_count = 2;
VKD3D_ASSERT(regset == HLSL_REGSET_TEXTURES);
*writemask = VKD3DSP_WRITEMASK_ALL;
}
@@ -8451,18 +8895,10 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p
{
reg->type = VKD3DSPR_UAV;
reg->dimension = VSIR_DIMENSION_VEC4;
- if (vkd3d_shader_ver_ge(version, 5, 1))
- {
- reg->idx[0].offset = var->regs[HLSL_REGSET_UAVS].id;
- reg->idx[1].offset = var->regs[HLSL_REGSET_UAVS].index; /* FIXME: array index */
- reg->idx_count = 2;
- }
- else
- {
- reg->idx[0].offset = var->regs[HLSL_REGSET_UAVS].index;
- reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref);
- reg->idx_count = 1;
- }
+ reg->idx[0].offset = var->regs[HLSL_REGSET_UAVS].id;
+ reg->idx[1].offset = var->regs[HLSL_REGSET_UAVS].index;
+ reg->idx[1].offset += hlsl_offset_from_deref_safe(ctx, deref);
+ reg->idx_count = 2;
VKD3D_ASSERT(regset == HLSL_REGSET_UAVS);
*writemask = VKD3DSP_WRITEMASK_ALL;
}
@@ -8470,21 +8906,21 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p
{
reg->type = VKD3DSPR_SAMPLER;
reg->dimension = VSIR_DIMENSION_NONE;
- if (vkd3d_shader_ver_ge(version, 5, 1))
- {
- reg->idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].id;
- reg->idx[1].offset = var->regs[HLSL_REGSET_SAMPLERS].index; /* FIXME: array index */
- reg->idx_count = 2;
- }
- else
- {
- reg->idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].index;
- reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref);
- reg->idx_count = 1;
- }
+ reg->idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].id;
+ reg->idx[1].offset = var->regs[HLSL_REGSET_SAMPLERS].index;
+ reg->idx[1].offset += hlsl_offset_from_deref_safe(ctx, deref);
+ reg->idx_count = 2;
VKD3D_ASSERT(regset == HLSL_REGSET_SAMPLERS);
*writemask = VKD3DSP_WRITEMASK_ALL;
}
+ else if (regset == HLSL_REGSET_STREAM_OUTPUTS)
+ {
+ reg->type = VKD3DSPR_STREAM;
+ reg->dimension = VSIR_DIMENSION_NONE;
+ reg->idx[0].offset = var->regs[HLSL_REGSET_STREAM_OUTPUTS].index;
+ reg->idx_count = 1;
+ *writemask = VKD3DSP_WRITEMASK_ALL;
+ }
else
{
unsigned int offset = deref->const_offset + var->buffer_offset;
@@ -8492,19 +8928,10 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p
VKD3D_ASSERT(data_type->class <= HLSL_CLASS_VECTOR);
reg->type = VKD3DSPR_CONSTBUFFER;
reg->dimension = VSIR_DIMENSION_VEC4;
- if (vkd3d_shader_ver_ge(version, 5, 1))
- {
- reg->idx[0].offset = var->buffer->reg.id;
- reg->idx[1].offset = var->buffer->reg.index; /* FIXME: array index */
- reg->idx[2].offset = offset / 4;
- reg->idx_count = 3;
- }
- else
- {
- reg->idx[0].offset = var->buffer->reg.index;
- reg->idx[1].offset = offset / 4;
- reg->idx_count = 2;
- }
+ reg->idx[0].offset = var->buffer->reg.id;
+ reg->idx[1].offset = var->buffer->reg.index; /* FIXME: array index */
+ reg->idx[2].offset = offset / 4;
+ reg->idx_count = 3;
if (deref->rel_offset.node)
{
@@ -8594,6 +9021,15 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p
*writemask = hlsl_reg.writemask;
}
}
+ else if (var->is_tgsm)
+ {
+ VKD3D_ASSERT(var->regs[HLSL_REGSET_NUMERIC].allocated);
+ reg->type = VKD3DSPR_GROUPSHAREDMEM;
+ reg->dimension = VSIR_DIMENSION_VEC4;
+ reg->idx[0].offset = var->regs[HLSL_REGSET_NUMERIC].id;
+ reg->idx_count = 1;
+ *writemask = (1u << data_type->e.numeric.dimx) - 1;
+ }
else
{
return sm4_generate_vsir_numeric_reg_from_deref(ctx, program, reg, writemask, deref);
@@ -8630,7 +9066,7 @@ static void vsir_dst_from_hlsl_node(struct vkd3d_shader_dst_param *dst,
struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr)
{
VKD3D_ASSERT(instr->reg.allocated);
- vsir_dst_param_init(dst, VKD3DSPR_TEMP, vsir_data_type_from_hlsl_instruction(ctx, instr), 1);
+ vsir_dst_param_init(dst, instr->reg.type, vsir_data_type_from_hlsl_instruction(ctx, instr), 1);
dst->reg.idx[0].offset = instr->reg.id;
dst->reg.dimension = VSIR_DIMENSION_VEC4;
dst->write_mask = instr->reg.writemask;
@@ -8646,11 +9082,11 @@ static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx,
VKD3D_ASSERT(instr->reg.allocated);
VKD3D_ASSERT(constant->reg.allocated);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1)))
return;
src_param = &ins->src[0];
- vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1);
+ vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1);
src_param->reg.dimension = VSIR_DIMENSION_VEC4;
src_param->reg.idx[0].offset = constant->reg.id;
src_param->swizzle = generate_vsir_get_src_swizzle(constant->reg.writemask, instr->reg.writemask);
@@ -8665,14 +9101,14 @@ static void sm4_generate_vsir_rasterizer_sample_count(struct hlsl_ctx *ctx,
struct hlsl_ir_node *instr = &expr->node;
struct vkd3d_shader_instruction *ins;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SAMPLE_INFO, 1, 1)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_SAMPLE_INFO, 1, 1)))
return;
ins->flags = VKD3DSI_SAMPLE_INFO_UINT;
vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr);
src_param = &ins->src[0];
- vsir_src_param_init(src_param, VKD3DSPR_RASTERIZER, VKD3D_DATA_UNUSED, 0);
+ vsir_src_param_init(src_param, VKD3DSPR_RASTERIZER, VSIR_DATA_UNUSED, 0);
src_param->reg.dimension = VSIR_DIMENSION_VEC4;
src_param->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
}
@@ -8740,13 +9176,13 @@ static void sm1_generate_vsir_instr_expr_per_component_instr_op(struct hlsl_ctx
return;
dst_param = &ins->dst[0];
- vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ vsir_register_init(&dst_param->reg, instr->reg.type, VSIR_DATA_F32, 1);
dst_param->reg.idx[0].offset = instr->reg.id;
dst_param->reg.dimension = VSIR_DIMENSION_VEC4;
dst_param->write_mask = 1u << i;
src_param = &ins->src[0];
- vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ vsir_register_init(&src_param->reg, operand->reg.type, VSIR_DATA_F32, 1);
src_param->reg.idx[0].offset = operand->reg.id;
src_param->reg.dimension = VSIR_DIMENSION_VEC4;
c = vsir_swizzle_get_component(src_swizzle, i);
@@ -8767,7 +9203,7 @@ static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsi
VKD3D_ASSERT(instr->reg.allocated);
src_count = (ctx->profile->major_version < 3) ? 3 : 1;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SINCOS, 1, src_count)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_SINCOS, 1, src_count)))
return;
vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr);
@@ -8776,13 +9212,13 @@ static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsi
if (ctx->profile->major_version < 3)
{
src_param = &ins->src[1];
- vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1);
+ vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1);
src_param->reg.dimension = VSIR_DIMENSION_VEC4;
src_param->reg.idx[0].offset = ctx->d3dsincosconst1.id;
src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
src_param = &ins->src[2];
- vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1);
+ vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1);
src_param->reg.dimension = VSIR_DIMENSION_VEC4;
src_param->reg.idx[0].offset = ctx->d3dsincosconst2.id;
src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
@@ -8816,13 +9252,13 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx,
/* Integrals are internally represented as floats, so no change is necessary.*/
case HLSL_TYPE_HALF:
case HLSL_TYPE_FLOAT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true);
return true;
case HLSL_TYPE_DOUBLE:
if (ctx->double_as_float_alias)
{
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true);
return true;
}
hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE,
@@ -8847,7 +9283,7 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx,
case HLSL_TYPE_MIN16UINT:
case HLSL_TYPE_UINT:
case HLSL_TYPE_BOOL:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true);
return true;
case HLSL_TYPE_DOUBLE:
@@ -8860,7 +9296,7 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx,
switch (src_type->e.numeric.type)
{
case HLSL_TYPE_FLOAT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true);
return true;
break;
@@ -8899,7 +9335,7 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr
switch (expr->op)
{
case HLSL_OP1_ABS:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ABS, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ABS, 0, 0, true);
break;
case HLSL_OP1_CAST:
@@ -8915,53 +9351,53 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr
case HLSL_OP1_DSX:
if (!hlsl_type_is_floating_point(type))
goto err;
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSX, 0, 0, true);
break;
case HLSL_OP1_DSY:
if (!hlsl_type_is_floating_point(type))
goto err;
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSY, 0, 0, true);
break;
case HLSL_OP1_EXP2:
if (!hlsl_type_is_floating_point(type))
goto err;
- sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_EXP);
+ sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VSIR_OP_EXP);
break;
case HLSL_OP1_LOG2:
if (!hlsl_type_is_floating_point(type))
goto err;
- sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_LOG);
+ sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VSIR_OP_LOG);
break;
case HLSL_OP1_NEG:
if (type->e.numeric.type == HLSL_TYPE_BOOL)
goto err;
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, VKD3DSPSM_NEG, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, VKD3DSPSM_NEG, 0, true);
break;
case HLSL_OP1_RCP:
if (!hlsl_type_is_floating_point(type))
goto err;
- sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_RCP);
+ sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VSIR_OP_RCP);
break;
case HLSL_OP1_REINTERPRET:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true);
break;
case HLSL_OP1_RSQ:
if (!hlsl_type_is_floating_point(type))
goto err;
- sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_RSQ);
+ sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VSIR_OP_RSQ);
break;
case HLSL_OP1_SAT:
if (!hlsl_type_is_floating_point(type))
goto err;
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, VKD3DSPDM_SATURATE, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, VKD3DSPDM_SATURATE, true);
break;
case HLSL_OP1_SIN_REDUCED:
@@ -8974,7 +9410,7 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr
case HLSL_OP2_ADD:
if (type->e.numeric.type == HLSL_TYPE_BOOL)
goto err;
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ADD, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ADD, 0, 0, true);
break;
case HLSL_OP2_DOT:
@@ -8983,11 +9419,11 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr
switch (expr->operands[0].node->data_type->e.numeric.dimx)
{
case 3:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP3, 0, 0, false);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP3, 0, 0, false);
break;
case 4:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP4, 0, 0, false);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP4, 0, 0, false);
break;
default:
@@ -8997,55 +9433,55 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr
break;
case HLSL_OP2_MAX:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAX, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MAX, 0, 0, true);
break;
case HLSL_OP2_MIN:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MIN, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MIN, 0, 0, true);
break;
case HLSL_OP2_MUL:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MUL, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MUL, 0, 0, true);
break;
case HLSL_OP1_FRACT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_FRC, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_FRC, 0, 0, true);
break;
case HLSL_OP2_LOGIC_AND:
if (type->e.numeric.type != HLSL_TYPE_BOOL)
goto err;
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MIN, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MIN, 0, 0, true);
break;
case HLSL_OP2_LOGIC_OR:
if (type->e.numeric.type != HLSL_TYPE_BOOL)
goto err;
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAX, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MAX, 0, 0, true);
break;
case HLSL_OP2_SLT:
if (!hlsl_type_is_floating_point(type))
goto err;
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_SLT, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_SLT, 0, 0, true);
break;
case HLSL_OP3_CMP:
if (!hlsl_type_is_floating_point(type))
goto err;
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_CMP, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_CMP, 0, 0, true);
break;
case HLSL_OP3_DP2ADD:
if (!hlsl_type_is_floating_point(type))
goto err;
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP2ADD, 0, 0, false);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP2ADD, 0, 0, false);
break;
case HLSL_OP3_MAD:
if (!hlsl_type_is_floating_point(type))
goto err;
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAD, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MAD, 0, 0, true);
break;
default:
@@ -9107,12 +9543,12 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx,
if (type == VKD3DSPR_DEPTHOUT)
{
- vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 0);
+ vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 0);
dst_param->reg.dimension = VSIR_DIMENSION_SCALAR;
}
else
{
- vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 1);
+ vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 1);
dst_param->reg.idx[0].offset = register_index;
dst_param->reg.dimension = VSIR_DIMENSION_VEC4;
}
@@ -9125,7 +9561,7 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx,
static void sm1_generate_vsir_instr_mova(struct hlsl_ctx *ctx,
struct vsir_program *program, struct hlsl_ir_node *instr)
{
- enum vkd3d_shader_opcode opcode = hlsl_version_ge(ctx, 2, 0) ? VKD3DSIH_MOVA : VKD3DSIH_MOV;
+ enum vkd3d_shader_opcode opcode = hlsl_version_ge(ctx, 2, 0) ? VSIR_OP_MOVA : VSIR_OP_MOV;
struct vkd3d_shader_dst_param *dst_param;
struct vkd3d_shader_instruction *ins;
@@ -9135,7 +9571,7 @@ static void sm1_generate_vsir_instr_mova(struct hlsl_ctx *ctx,
return;
dst_param = &ins->dst[0];
- vsir_register_init(&dst_param->reg, VKD3DSPR_ADDR, VKD3D_DATA_FLOAT, 0);
+ vsir_register_init(&dst_param->reg, VKD3DSPR_ADDR, VSIR_DATA_F32, 0);
dst_param->write_mask = VKD3DSP_WRITEMASK_0;
VKD3D_ASSERT(instr->data_type->class <= HLSL_CLASS_VECTOR);
@@ -9155,7 +9591,7 @@ static struct vkd3d_shader_src_param *sm1_generate_vsir_new_address_src(struct h
}
memset(idx_src, 0, sizeof(*idx_src));
- vsir_register_init(&idx_src->reg, VKD3DSPR_ADDR, VKD3D_DATA_FLOAT, 0);
+ vsir_register_init(&idx_src->reg, VKD3DSPR_ADDR, VSIR_DATA_F32, 0);
idx_src->reg.dimension = VSIR_DIMENSION_VEC4;
idx_src->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
return idx_src;
@@ -9234,7 +9670,7 @@ static void sm1_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx,
writemask = reg.writemask;
}
- vsir_register_init(&src_param->reg, type, VKD3D_DATA_FLOAT, 1);
+ vsir_register_init(&src_param->reg, type, VSIR_DATA_F32, 1);
src_param->reg.dimension = VSIR_DIMENSION_VEC4;
src_param->reg.idx[0].offset = register_index;
src_param->reg.idx[0].rel_addr = src_rel_addr;
@@ -9252,7 +9688,7 @@ static void sm1_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_progr
if (load->src.rel_offset.node)
sm1_generate_vsir_instr_mova(ctx, program, load->src.rel_offset.node);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1)))
return;
vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr);
@@ -9279,21 +9715,25 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx,
switch (load->load_type)
{
case HLSL_RESOURCE_SAMPLE:
- opcode = VKD3DSIH_TEX;
+ opcode = VSIR_OP_TEXLD;
break;
case HLSL_RESOURCE_SAMPLE_PROJ:
- opcode = VKD3DSIH_TEX;
+ opcode = VSIR_OP_TEXLD;
flags |= VKD3DSI_TEXLD_PROJECT;
break;
+ case HLSL_RESOURCE_SAMPLE_LOD:
+ opcode = VSIR_OP_TEXLDL;
+ break;
+
case HLSL_RESOURCE_SAMPLE_LOD_BIAS:
- opcode = VKD3DSIH_TEX;
+ opcode = VSIR_OP_TEXLD;
flags |= VKD3DSI_TEXLD_BIAS;
break;
case HLSL_RESOURCE_SAMPLE_GRAD:
- opcode = VKD3DSIH_TEXLDD;
+ opcode = VSIR_OP_TEXLDD;
src_count += 2;
break;
@@ -9334,7 +9774,7 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx,
VKD3D_ASSERT(instr->reg.allocated);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1)))
return;
vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr);
@@ -9345,7 +9785,7 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx,
src_param = &ins->src[0];
VKD3D_ASSERT(val->type != HLSL_IR_CONSTANT);
- vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, vsir_data_type_from_hlsl_instruction(ctx, val), 1);
+ vsir_register_init(&src_param->reg, val->reg.type, vsir_data_type_from_hlsl_instruction(ctx, val), 1);
src_param->reg.idx[0].offset = val->reg.id;
src_param->reg.dimension = VSIR_DIMENSION_VEC4;
src_param->swizzle = swizzle;
@@ -9359,7 +9799,7 @@ static void sm1_generate_vsir_instr_store(struct hlsl_ctx *ctx, struct vsir_prog
struct vkd3d_shader_instruction *ins;
struct vkd3d_shader_src_param *src_param;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1)))
return;
sm1_generate_vsir_init_dst_param_from_deref(ctx, &ins->dst[0], &store->lhs, &ins->location, store->writemask);
@@ -9377,7 +9817,7 @@ static void sm1_generate_vsir_instr_jump(struct hlsl_ctx *ctx,
if (jump->type == HLSL_IR_JUMP_DISCARD_NEG)
{
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_TEXKILL, 0, 1)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_TEXKILL, 0, 1)))
return;
vsir_src_from_hlsl_node(&ins->src[0], ctx, condition, VKD3DSP_WRITEMASK_ALL);
@@ -9404,7 +9844,7 @@ static void sm1_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program
}
VKD3D_ASSERT(condition->data_type->e.numeric.dimx == 1 && condition->data_type->e.numeric.dimy == 1);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_IFC, 0, 2)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_IFC, 0, 2)))
return;
ins->flags = VKD3D_SHADER_REL_OP_NE;
@@ -9418,12 +9858,12 @@ static void sm1_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program
sm1_generate_vsir_block(ctx, &iff->then_block, program);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ELSE, 0, 0)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ELSE, 0, 0)))
return;
sm1_generate_vsir_block(ctx, &iff->else_block, program);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ENDIF, 0, 0)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ENDIF, 0, 0)))
return;
}
@@ -9486,33 +9926,30 @@ static void sm1_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *blo
}
}
-static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
- uint64_t config_flags, struct vsir_program *program)
+static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info,
+ struct hlsl_ir_function_decl *func, struct list *semantic_vars,
+ struct hlsl_block *body, uint64_t config_flags, struct vsir_program *program)
{
- struct vkd3d_shader_version version = {0};
struct hlsl_block block;
- version.major = ctx->profile->major_version;
- version.minor = ctx->profile->minor_version;
- version.type = ctx->profile->type;
- if (!vsir_program_init(program, NULL, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4))
- {
- ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
- return;
- }
-
- program->temp_count = allocate_temp_registers(ctx, entry_func);
+ program->ssa_count = 0;
+ program->temp_count = allocate_temp_registers(ctx, body, semantic_vars);
if (ctx->result)
return;
- generate_vsir_signature(ctx, program, entry_func);
-
hlsl_block_init(&block);
sm1_generate_vsir_constant_defs(ctx, program, &block);
sm1_generate_vsir_sampler_dcls(ctx, program, &block);
- list_move_head(&entry_func->body.instrs, &block.instrs);
+ list_move_head(&body->instrs, &block.instrs);
+
+ sm1_generate_vsir_block(ctx, body, program);
- sm1_generate_vsir_block(ctx, &entry_func->body, program);
+ program->ssa_count = ctx->ssa_count;
+
+ if (ctx->result)
+ return;
+ if (program->normalisation_level >= VSIR_NORMALISED_SM4)
+ ctx->result = vsir_program_lower_d3dbc(program, config_flags, compile_info, ctx->message_context);
}
D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type)
@@ -9922,6 +10359,57 @@ static void sm1_generate_ctab(struct hlsl_ctx *ctx, struct vkd3d_shader_code *ct
ctab->size = buffer.size;
}
+static enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval,
+ unsigned int index)
+{
+ switch (sysval)
+ {
+ case VKD3D_SHADER_SV_COVERAGE:
+ case VKD3D_SHADER_SV_DEPTH:
+ case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL:
+ case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL:
+ case VKD3D_SHADER_SV_NONE:
+ case VKD3D_SHADER_SV_STENCIL_REF:
+ case VKD3D_SHADER_SV_TARGET:
+ return VKD3D_SIV_NONE;
+ case VKD3D_SHADER_SV_POSITION:
+ return VKD3D_SIV_POSITION;
+ case VKD3D_SHADER_SV_CLIP_DISTANCE:
+ return VKD3D_SIV_CLIP_DISTANCE;
+ case VKD3D_SHADER_SV_CULL_DISTANCE:
+ return VKD3D_SIV_CULL_DISTANCE;
+ case VKD3D_SHADER_SV_INSTANCE_ID:
+ return VKD3D_SIV_INSTANCE_ID;
+ case VKD3D_SHADER_SV_IS_FRONT_FACE:
+ return VKD3D_SIV_IS_FRONT_FACE;
+ case VKD3D_SHADER_SV_PRIMITIVE_ID:
+ return VKD3D_SIV_PRIMITIVE_ID;
+ case VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX:
+ return VKD3D_SIV_RENDER_TARGET_ARRAY_INDEX;
+ case VKD3D_SHADER_SV_SAMPLE_INDEX:
+ return VKD3D_SIV_SAMPLE_INDEX;
+ case VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE:
+ return VKD3D_SIV_QUAD_U0_TESS_FACTOR + index;
+ case VKD3D_SHADER_SV_TESS_FACTOR_QUADINT:
+ return VKD3D_SIV_QUAD_U_INNER_TESS_FACTOR + index;
+ case VKD3D_SHADER_SV_TESS_FACTOR_TRIEDGE:
+ return VKD3D_SIV_TRIANGLE_U_TESS_FACTOR + index;
+ case VKD3D_SHADER_SV_TESS_FACTOR_TRIINT:
+ return VKD3D_SIV_TRIANGLE_INNER_TESS_FACTOR;
+ case VKD3D_SHADER_SV_TESS_FACTOR_LINEDET:
+ return VKD3D_SIV_LINE_DETAIL_TESS_FACTOR;
+ case VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN:
+ return VKD3D_SIV_LINE_DENSITY_TESS_FACTOR;
+ case VKD3D_SHADER_SV_VERTEX_ID:
+ return VKD3D_SIV_VERTEX_ID;
+ case VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX:
+ return VKD3D_SIV_VIEWPORT_ARRAY_INDEX;
+ default:
+ FIXME("Unhandled sysval %#x, index %u.\n", sysval, index);
+ return VKD3D_SIV_NONE;
+ }
+}
+
static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vsir_program *program,
const struct hlsl_ir_var *var, struct hlsl_block *block, const struct vkd3d_shader_location *loc)
{
@@ -9948,16 +10436,16 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs
{
case VKD3D_SHADER_SV_NONE:
opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL)
- ? VKD3DSIH_DCL_INPUT_PS : VKD3DSIH_DCL_INPUT;
+ ? VSIR_OP_DCL_INPUT_PS : VSIR_OP_DCL_INPUT;
break;
case VKD3D_SHADER_SV_PRIMITIVE_ID:
if (version->type == VKD3D_SHADER_TYPE_PIXEL)
- opcode = VKD3DSIH_DCL_INPUT_PS_SGV;
+ opcode = VSIR_OP_DCL_INPUT_PS_SGV;
else if (version->type == VKD3D_SHADER_TYPE_GEOMETRY)
- opcode = VKD3DSIH_DCL_INPUT;
+ opcode = VSIR_OP_DCL_INPUT;
else
- opcode = VKD3DSIH_DCL_INPUT_SGV;
+ opcode = VSIR_OP_DCL_INPUT_SGV;
break;
case VKD3D_SHADER_SV_INSTANCE_ID:
@@ -9965,16 +10453,16 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs
case VKD3D_SHADER_SV_SAMPLE_INDEX:
case VKD3D_SHADER_SV_VERTEX_ID:
opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL)
- ? VKD3DSIH_DCL_INPUT_PS_SGV : VKD3DSIH_DCL_INPUT_SGV;
+ ? VSIR_OP_DCL_INPUT_PS_SGV : VSIR_OP_DCL_INPUT_SGV;
break;
default:
if (version->type == VKD3D_SHADER_TYPE_PIXEL)
- opcode = VKD3DSIH_DCL_INPUT_PS_SIV;
+ opcode = VSIR_OP_DCL_INPUT_PS_SIV;
else if (is_primitive && version->type != VKD3D_SHADER_TYPE_GEOMETRY)
- opcode = VKD3DSIH_DCL_INPUT;
+ opcode = VSIR_OP_DCL_INPUT;
else
- opcode = VKD3DSIH_DCL_INPUT_SIV;
+ opcode = VSIR_OP_DCL_INPUT_SIV;
break;
}
}
@@ -9982,9 +10470,12 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs
{
if (semantic == VKD3D_SHADER_SV_NONE || version->type == VKD3D_SHADER_TYPE_PIXEL
|| (version->type == VKD3D_SHADER_TYPE_HULL && !ctx->is_patch_constant_func))
- opcode = VKD3DSIH_DCL_OUTPUT;
+ opcode = VSIR_OP_DCL_OUTPUT;
+ else if ((semantic == VKD3D_SHADER_SV_PRIMITIVE_ID || semantic == VKD3D_SHADER_SV_IS_FRONT_FACE)
+ && version->type == VKD3D_SHADER_TYPE_GEOMETRY)
+ opcode = VSIR_OP_DCL_OUTPUT_SGV;
else
- opcode = VKD3DSIH_DCL_OUTPUT_SIV;
+ opcode = VSIR_OP_DCL_OUTPUT_SIV;
}
if (sm4_register_from_semantic_name(version, var->semantic.name, output, &type, &has_idx))
@@ -10004,13 +10495,13 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs
if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, opcode, 0, 0)))
return;
- if (opcode == VKD3DSIH_DCL_OUTPUT)
+ if (opcode == VSIR_OP_DCL_OUTPUT)
{
VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE || semantic == VKD3D_SHADER_SV_TARGET
|| version->type == VKD3D_SHADER_TYPE_HULL || type != VKD3DSPR_OUTPUT);
dst_param = &ins->declaration.dst;
}
- else if (opcode == VKD3DSIH_DCL_INPUT || opcode == VKD3DSIH_DCL_INPUT_PS)
+ else if (opcode == VSIR_OP_DCL_INPUT || opcode == VSIR_OP_DCL_INPUT_PS)
{
VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE || is_primitive || version->type == VKD3D_SHADER_TYPE_GEOMETRY);
dst_param = &ins->declaration.dst;
@@ -10026,18 +10517,18 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs
if (is_primitive)
{
VKD3D_ASSERT(has_idx);
- vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 2);
+ vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 2);
dst_param->reg.idx[0].offset = var->data_type->e.array.elements_count;
dst_param->reg.idx[1].offset = idx;
}
else if (has_idx)
{
- vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 1);
+ vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 1);
dst_param->reg.idx[0].offset = idx;
}
else
{
- vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 0);
+ vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 0);
}
if (shader_sm4_is_scalar_register(&dst_param->reg))
@@ -10056,7 +10547,7 @@ static void sm4_generate_vsir_instr_dcl_temps(struct hlsl_ctx *ctx, struct vsir_
{
struct vkd3d_shader_instruction *ins;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, VKD3DSIH_DCL_TEMPS, 0, 0)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, VSIR_OP_DCL_TEMPS, 0, 0)))
return;
ins->declaration.count = temp_count;
@@ -10068,13 +10559,13 @@ static void sm4_generate_vsir_instr_dcl_indexable_temp(struct hlsl_ctx *ctx,
{
struct vkd3d_shader_instruction *ins;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, VKD3DSIH_DCL_INDEXABLE_TEMP, 0, 0)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, VSIR_OP_DCL_INDEXABLE_TEMP, 0, 0)))
return;
ins->declaration.indexable_temp.register_idx = idx;
ins->declaration.indexable_temp.register_size = size;
ins->declaration.indexable_temp.alignment = 0;
- ins->declaration.indexable_temp.data_type = VKD3D_DATA_FLOAT;
+ ins->declaration.indexable_temp.data_type = VSIR_DATA_F32;
ins->declaration.indexable_temp.component_count = comp_count;
ins->declaration.indexable_temp.has_function_scope = false;
}
@@ -10095,16 +10586,17 @@ static void sm4_generate_vsir_cast_from_bool(struct hlsl_ctx *ctx, struct vsir_p
VKD3D_ASSERT(instr->reg.allocated);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_AND, 1, 2)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_AND, 1, 2)))
return;
dst_param = &ins->dst[0];
vsir_dst_from_hlsl_node(dst_param, ctx, instr);
+ ins->dst[0].reg.data_type = VSIR_DATA_U32;
vsir_src_from_hlsl_node(&ins->src[0], ctx, operand, dst_param->write_mask);
value.u[0].u = bits;
- vsir_src_from_hlsl_constant_value(&ins->src[1], ctx, &value, VKD3D_DATA_UINT, 1, 0);
+ vsir_src_from_hlsl_constant_value(&ins->src[1], ctx, &value, VSIR_DATA_U32, 1, 0);
}
static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx,
@@ -10131,16 +10623,16 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx,
{
case HLSL_TYPE_HALF:
case HLSL_TYPE_FLOAT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true);
return true;
case HLSL_TYPE_INT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ITOF, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ITOF, 0, 0, true);
return true;
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */
case HLSL_TYPE_UINT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UTOF, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_UTOF, 0, 0, true);
return true;
case HLSL_TYPE_BOOL:
@@ -10158,13 +10650,13 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx,
{
case HLSL_TYPE_HALF:
case HLSL_TYPE_FLOAT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_FTOI, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_FTOI, 0, 0, true);
return true;
case HLSL_TYPE_INT:
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */
case HLSL_TYPE_UINT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true);
return true;
case HLSL_TYPE_BOOL:
@@ -10183,13 +10675,13 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx,
{
case HLSL_TYPE_HALF:
case HLSL_TYPE_FLOAT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_FTOU, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_FTOU, 0, 0, true);
return true;
case HLSL_TYPE_INT:
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */
case HLSL_TYPE_UINT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true);
return true;
case HLSL_TYPE_BOOL:
@@ -10253,7 +10745,7 @@ static void sm4_generate_vsir_rcp_using_div(struct hlsl_ctx *ctx,
VKD3D_ASSERT(type_is_float(expr->node.data_type));
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_DIV, 1, 2)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_DIV, 1, 2)))
return;
dst_param = &ins->dst[0];
@@ -10264,7 +10756,7 @@ static void sm4_generate_vsir_rcp_using_div(struct hlsl_ctx *ctx,
value.u[2].f = 1.0f;
value.u[3].f = 1.0f;
vsir_src_from_hlsl_constant_value(&ins->src[0], ctx, &value,
- VKD3D_DATA_FLOAT, instr->data_type->e.numeric.dimx, dst_param->write_mask);
+ VSIR_DATA_F32, instr->data_type->e.numeric.dimx, dst_param->write_mask);
vsir_src_from_hlsl_node(&ins->src[1], ctx, operand, dst_param->write_mask);
}
@@ -10287,12 +10779,12 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
case HLSL_OP1_ABS:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, VKD3DSPSM_ABS, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, VKD3DSPSM_ABS, 0, true);
return true;
case HLSL_OP1_BIT_NOT:
VKD3D_ASSERT(hlsl_type_is_integer(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_NOT, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_NOT, 0, 0, true);
return true;
case HLSL_OP1_CAST:
@@ -10300,92 +10792,92 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
case HLSL_OP1_CEIL:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ROUND_PI, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ROUND_PI, 0, 0, true);
return true;
case HLSL_OP1_COS:
VKD3D_ASSERT(type_is_float(dst_type));
- sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_SINCOS, expr, 1);
+ sm4_generate_vsir_expr_with_two_destinations(ctx, program, VSIR_OP_SINCOS, expr, 1);
return true;
case HLSL_OP1_DSX:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSX, 0, 0, true);
return true;
case HLSL_OP1_DSX_COARSE:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX_COARSE, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSX_COARSE, 0, 0, true);
return true;
case HLSL_OP1_DSX_FINE:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX_FINE, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSX_FINE, 0, 0, true);
return true;
case HLSL_OP1_DSY:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSY, 0, 0, true);
return true;
case HLSL_OP1_DSY_COARSE:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY_COARSE, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSY_COARSE, 0, 0, true);
return true;
case HLSL_OP1_DSY_FINE:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY_FINE, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSY_FINE, 0, 0, true);
return true;
case HLSL_OP1_EXP2:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_EXP, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_EXP, 0, 0, true);
return true;
case HLSL_OP1_F16TOF32:
VKD3D_ASSERT(type_is_float(dst_type));
VKD3D_ASSERT(hlsl_version_ge(ctx, 5, 0));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_F16TOF32, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_F16TOF32, 0, 0, true);
return true;
case HLSL_OP1_F32TOF16:
VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_UINT);
VKD3D_ASSERT(hlsl_version_ge(ctx, 5, 0));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_F32TOF16, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_F32TOF16, 0, 0, true);
return true;
case HLSL_OP1_FLOOR:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ROUND_NI, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ROUND_NI, 0, 0, true);
return true;
case HLSL_OP1_FRACT:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_FRC, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_FRC, 0, 0, true);
return true;
case HLSL_OP1_LOG2:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_LOG, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_LOG, 0, 0, true);
return true;
case HLSL_OP1_LOGIC_NOT:
VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL);
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_NOT, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_NOT, 0, 0, true);
return true;
case HLSL_OP1_NEG:
switch (dst_type->e.numeric.type)
{
case HLSL_TYPE_FLOAT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, VKD3DSPSM_NEG, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, VKD3DSPSM_NEG, 0, true);
return true;
case HLSL_TYPE_INT:
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */
case HLSL_TYPE_UINT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_INEG, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_INEG, 0, 0, true);
return true;
default:
@@ -10399,7 +10891,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
case HLSL_TYPE_FLOAT:
/* SM5 comes with a RCP opcode */
if (hlsl_version_ge(ctx, 5, 0))
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_RCP, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_RCP, 0, 0, true);
else
sm4_generate_vsir_rcp_using_div(ctx, program, expr);
return true;
@@ -10410,50 +10902,50 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
}
case HLSL_OP1_REINTERPRET:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true);
return true;
case HLSL_OP1_ROUND:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ROUND_NE, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ROUND_NE, 0, 0, true);
return true;
case HLSL_OP1_RSQ:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_RSQ, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_RSQ, 0, 0, true);
return true;
case HLSL_OP1_SAT:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, VKD3DSPDM_SATURATE, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, VKD3DSPDM_SATURATE, true);
return true;
case HLSL_OP1_SIN:
VKD3D_ASSERT(type_is_float(dst_type));
- sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_SINCOS, expr, 0);
+ sm4_generate_vsir_expr_with_two_destinations(ctx, program, VSIR_OP_SINCOS, expr, 0);
return true;
case HLSL_OP1_SQRT:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_SQRT, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_SQRT, 0, 0, true);
return true;
case HLSL_OP1_TRUNC:
VKD3D_ASSERT(type_is_float(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ROUND_Z, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ROUND_Z, 0, 0, true);
return true;
case HLSL_OP2_ADD:
switch (dst_type->e.numeric.type)
{
case HLSL_TYPE_FLOAT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ADD, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ADD, 0, 0, true);
return true;
case HLSL_TYPE_INT:
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */
case HLSL_TYPE_UINT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IADD, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IADD, 0, 0, true);
return true;
default:
@@ -10463,29 +10955,29 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
case HLSL_OP2_BIT_AND:
VKD3D_ASSERT(hlsl_type_is_integer(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_AND, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_AND, 0, 0, true);
return true;
case HLSL_OP2_BIT_OR:
VKD3D_ASSERT(hlsl_type_is_integer(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_OR, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_OR, 0, 0, true);
return true;
case HLSL_OP2_BIT_XOR:
VKD3D_ASSERT(hlsl_type_is_integer(dst_type));
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_XOR, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_XOR, 0, 0, true);
return true;
case HLSL_OP2_DIV:
switch (dst_type->e.numeric.type)
{
case HLSL_TYPE_FLOAT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DIV, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DIV, 0, 0, true);
return true;
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */
case HLSL_TYPE_UINT:
- sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_UDIV, expr, 0);
+ sm4_generate_vsir_expr_with_two_destinations(ctx, program, VSIR_OP_UDIV, expr, 0);
return true;
default:
@@ -10500,15 +10992,15 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
switch (expr->operands[0].node->data_type->e.numeric.dimx)
{
case 4:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP4, 0, 0, false);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP4, 0, 0, false);
return true;
case 3:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP3, 0, 0, false);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP3, 0, 0, false);
return true;
case 2:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP2, 0, 0, false);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP2, 0, 0, false);
return true;
case 1:
@@ -10527,14 +11019,14 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
switch (src_type->e.numeric.type)
{
case HLSL_TYPE_FLOAT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_EQO, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_EQO, 0, 0, true);
return true;
case HLSL_TYPE_BOOL:
case HLSL_TYPE_INT:
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */
case HLSL_TYPE_UINT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IEQ, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IEQ, 0, 0, true);
return true;
default:
@@ -10549,17 +11041,17 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
switch (src_type->e.numeric.type)
{
case HLSL_TYPE_FLOAT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_GEO, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_GEO, 0, 0, true);
return true;
case HLSL_TYPE_INT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IGE, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IGE, 0, 0, true);
return true;
case HLSL_TYPE_BOOL:
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */
case HLSL_TYPE_UINT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UGE, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_UGE, 0, 0, true);
return true;
default:
@@ -10574,17 +11066,17 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
switch (src_type->e.numeric.type)
{
case HLSL_TYPE_FLOAT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_LTO, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_LTO, 0, 0, true);
return true;
case HLSL_TYPE_INT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ILT, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ILT, 0, 0, true);
return true;
case HLSL_TYPE_BOOL:
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */
case HLSL_TYPE_UINT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ULT, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ULT, 0, 0, true);
return true;
default:
@@ -10595,31 +11087,31 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
case HLSL_OP2_LOGIC_AND:
VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL);
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_AND, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_AND, 0, 0, true);
return true;
case HLSL_OP2_LOGIC_OR:
VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL);
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_OR, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_OR, 0, 0, true);
return true;
case HLSL_OP2_LSHIFT:
VKD3D_ASSERT(hlsl_type_is_integer(dst_type));
VKD3D_ASSERT(dst_type->e.numeric.type != HLSL_TYPE_BOOL);
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ISHL, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ISHL, 0, 0, true);
return true;
case HLSL_OP3_MAD:
switch (dst_type->e.numeric.type)
{
case HLSL_TYPE_FLOAT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAD, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MAD, 0, 0, true);
return true;
case HLSL_TYPE_INT:
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */
case HLSL_TYPE_UINT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMAD, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IMAD, 0, 0, true);
return true;
default:
@@ -10631,16 +11123,16 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
switch (dst_type->e.numeric.type)
{
case HLSL_TYPE_FLOAT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAX, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MAX, 0, 0, true);
return true;
case HLSL_TYPE_INT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMAX, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IMAX, 0, 0, true);
return true;
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */
case HLSL_TYPE_UINT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UMAX, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_UMAX, 0, 0, true);
return true;
default:
@@ -10652,16 +11144,16 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
switch (dst_type->e.numeric.type)
{
case HLSL_TYPE_FLOAT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MIN, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MIN, 0, 0, true);
return true;
case HLSL_TYPE_INT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMIN, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IMIN, 0, 0, true);
return true;
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */
case HLSL_TYPE_UINT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UMIN, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_UMIN, 0, 0, true);
return true;
default:
@@ -10674,7 +11166,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
{
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */
case HLSL_TYPE_UINT:
- sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_UDIV, expr, 1);
+ sm4_generate_vsir_expr_with_two_destinations(ctx, program, VSIR_OP_UDIV, expr, 1);
return true;
default:
@@ -10686,7 +11178,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
switch (dst_type->e.numeric.type)
{
case HLSL_TYPE_FLOAT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MUL, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MUL, 0, 0, true);
return true;
case HLSL_TYPE_INT:
@@ -10694,7 +11186,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
case HLSL_TYPE_UINT:
/* Using IMUL instead of UMUL because we're taking the low
* bits, and the native compiler generates IMUL. */
- sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_IMUL, expr, 1);
+ sm4_generate_vsir_expr_with_two_destinations(ctx, program, VSIR_OP_IMUL, expr, 1);
return true;
default:
@@ -10708,14 +11200,14 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
switch (src_type->e.numeric.type)
{
case HLSL_TYPE_FLOAT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_NEU, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_NEU, 0, 0, true);
return true;
case HLSL_TYPE_BOOL:
case HLSL_TYPE_INT:
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */
case HLSL_TYPE_UINT:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_INE, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_INE, 0, 0, true);
return true;
default:
@@ -10728,11 +11220,11 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
VKD3D_ASSERT(hlsl_type_is_integer(dst_type));
VKD3D_ASSERT(dst_type->e.numeric.type != HLSL_TYPE_BOOL);
generate_vsir_instr_expr_single_instr_op(ctx, program, expr,
- dst_type->e.numeric.type == HLSL_TYPE_INT ? VKD3DSIH_ISHR : VKD3DSIH_USHR, 0, 0, true);
+ dst_type->e.numeric.type == HLSL_TYPE_INT ? VSIR_OP_ISHR : VSIR_OP_USHR, 0, 0, true);
return true;
case HLSL_OP3_TERNARY:
- generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOVC, 0, 0, true);
+ generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOVC, 0, 0, true);
return true;
default:
@@ -10749,7 +11241,9 @@ static bool sm4_generate_vsir_instr_store(struct hlsl_ctx *ctx,
struct vkd3d_shader_src_param *src_param;
struct vkd3d_shader_instruction *ins;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1)))
+ VKD3D_ASSERT(!store->lhs.var->is_tgsm);
+
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1)))
return false;
dst_param = &ins->dst[0];
@@ -10783,13 +11277,14 @@ static bool sm4_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_progr
struct vkd3d_shader_instruction *ins;
struct hlsl_constant_value value;
+ VKD3D_ASSERT(!load->src.var->is_tgsm);
VKD3D_ASSERT(hlsl_is_numeric_type(type));
if (type->e.numeric.type == HLSL_TYPE_BOOL && var_is_user_input(version, load->src.var))
{
/* Uniform bools can be specified as anything, but internal bools
* always have 0 for false and ~0 for true. Normalise that here. */
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOVC, 1, 3)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOVC, 1, 3)))
return false;
dst_param = &ins->dst[0];
@@ -10801,14 +11296,14 @@ static bool sm4_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_progr
memset(&value, 0xff, sizeof(value));
vsir_src_from_hlsl_constant_value(&ins->src[1], ctx, &value,
- VKD3D_DATA_UINT, type->e.numeric.dimx, dst_param->write_mask);
+ VSIR_DATA_U32, type->e.numeric.dimx, dst_param->write_mask);
memset(&value, 0x00, sizeof(value));
vsir_src_from_hlsl_constant_value(&ins->src[2], ctx, &value,
- VKD3D_DATA_UINT, type->e.numeric.dimx, dst_param->write_mask);
+ VSIR_DATA_U32, type->e.numeric.dimx, dst_param->write_mask);
}
else
{
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1)))
return false;
dst_param = &ins->dst[0];
@@ -10827,30 +11322,37 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx,
struct hlsl_type *resource_type = hlsl_deref_get_type(ctx, &store->resource);
struct hlsl_ir_node *coords = store->coords.node, *value = store->value.node;
struct hlsl_ir_node *instr = &store->node;
+ bool tgsm = store->resource.var->is_tgsm;
struct vkd3d_shader_instruction *ins;
- unsigned int writemask;
if (store->store_type != HLSL_RESOURCE_STORE)
{
- enum vkd3d_shader_opcode opcode = store->store_type == HLSL_RESOURCE_STREAM_APPEND
- ? VKD3DSIH_EMIT : VKD3DSIH_CUT;
+ enum vkd3d_shader_opcode opcode;
VKD3D_ASSERT(!store->value.node && !store->coords.node);
VKD3D_ASSERT(store->resource.var->regs[HLSL_REGSET_STREAM_OUTPUTS].allocated);
- if (store->resource.var->regs[HLSL_REGSET_STREAM_OUTPUTS].index)
+ if (hlsl_version_lt(ctx, 5, 0))
{
- hlsl_fixme(ctx, &instr->loc, "Stream output operation with a nonzero stream index.");
- return false;
+ opcode = store->store_type == HLSL_RESOURCE_STREAM_APPEND ? VSIR_OP_EMIT : VSIR_OP_CUT;
+ ins = generate_vsir_add_program_instruction(ctx, program, &store->node.loc, opcode, 0, 0);
+ return !!ins;
}
- ins = generate_vsir_add_program_instruction(ctx, program, &store->node.loc, opcode, 0, 0);
- return !!ins;
+ opcode = store->store_type == HLSL_RESOURCE_STREAM_APPEND ? VSIR_OP_EMIT_STREAM : VSIR_OP_CUT_STREAM;
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &store->node.loc, opcode, 0, 1)))
+ return false;
+
+ if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, &ins->src[0],
+ &store->resource, VKD3DSP_WRITEMASK_ALL, &instr->loc))
+ return false;
+
+ return true;
}
- if (!store->resource.var->is_uniform)
+ if (!store->resource.var->is_uniform && !tgsm)
{
- hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform resource variable.");
+ hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform non-groupshared resource variable.");
return false;
}
@@ -10860,19 +11362,24 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx,
return false;
}
- if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER)
+ if (tgsm && !hlsl_is_numeric_type(resource_type))
+ {
+ hlsl_fixme(ctx, &store->node.loc, "Store to structured TGSM.");
+ return false;
+ }
+
+ if (tgsm || resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER)
{
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_STORE_RAW, 1, 2)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_STORE_RAW, 1, 2)))
return false;
- writemask = vkd3d_write_mask_from_component_count(value->data_type->e.numeric.dimx);
- if (!sm4_generate_vsir_init_dst_param_from_deref(ctx, program,
- &ins->dst[0], &store->resource, &instr->loc, writemask))
+ if (!sm4_generate_vsir_init_dst_param_from_deref(ctx, program, &ins->dst[0],
+ &store->resource, &instr->loc, store->writemask))
return false;
}
else
{
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_STORE_UAV_TYPED, 1, 2)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_STORE_UAV_TYPED, 1, 2)))
return false;
if (!sm4_generate_vsir_init_dst_param_from_deref(ctx, program,
@@ -10928,7 +11435,6 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx,
const struct hlsl_type *resource_type = hlsl_deref_get_type(ctx, &load->resource);
bool uav = (hlsl_deref_get_regset(ctx, &load->resource) == HLSL_REGSET_UAVS);
const struct vkd3d_shader_version *version = &program->shader_version;
- bool raw = resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER;
const struct hlsl_ir_node *sample_index = load->sample_index.node;
const struct hlsl_ir_node *texel_offset = load->texel_offset.node;
const struct hlsl_ir_node *coords = load->coords.node;
@@ -10936,22 +11442,39 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx,
const struct hlsl_deref *resource = &load->resource;
const struct hlsl_ir_node *instr = &load->node;
enum hlsl_sampler_dim dim = load->sampling_dim;
+ bool tgsm = load->resource.var->is_tgsm;
struct vkd3d_shader_instruction *ins;
enum vkd3d_shader_opcode opcode;
- bool multisampled;
+ bool multisampled, raw;
VKD3D_ASSERT(load->load_type == HLSL_RESOURCE_LOAD);
+ if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
+ {
+ hlsl_fixme(ctx, &load->node.loc, "Structured buffer loads.");
+ return false;
+ }
+
multisampled = resource_type->class == HLSL_CLASS_TEXTURE
&& (resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS
|| resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY);
+ if (!tgsm)
+ {
+ raw = resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER;
+ }
+ else if (!(raw = hlsl_is_numeric_type(resource_type)))
+ {
+ hlsl_fixme(ctx, &load->node.loc, "Load from structured TGSM.");
+ return false;
+ }
+
if (uav)
- opcode = VKD3DSIH_LD_UAV_TYPED;
+ opcode = VSIR_OP_LD_UAV_TYPED;
else if (raw)
- opcode = VKD3DSIH_LD_RAW;
+ opcode = VSIR_OP_LD_RAW;
else
- opcode = multisampled ? VKD3DSIH_LD2DMS : VKD3DSIH_LD;
+ opcode = multisampled ? VSIR_OP_LD2DMS : VSIR_OP_LD;
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, 2 + multisampled)))
return false;
@@ -10966,7 +11489,7 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx,
vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr);
- if (!uav)
+ if (!uav && !tgsm)
{
/* Mipmap level is in the last component in the IR, but needs to be in
* the W component in the instruction. */
@@ -10988,7 +11511,7 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx,
{
if (sample_index->type == HLSL_IR_CONSTANT)
vsir_src_from_hlsl_constant_value(&ins->src[2], ctx,
- &hlsl_ir_constant(sample_index)->value, VKD3D_DATA_INT, 1, 0);
+ &hlsl_ir_constant(sample_index)->value, VSIR_DATA_I32, 1, 0);
else if (version->major == 4 && version->minor == 0)
hlsl_error(ctx, &sample_index->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Expected literal sample index.");
else
@@ -11012,32 +11535,32 @@ static bool sm4_generate_vsir_instr_sample(struct hlsl_ctx *ctx,
switch (load->load_type)
{
case HLSL_RESOURCE_SAMPLE:
- opcode = VKD3DSIH_SAMPLE;
+ opcode = VSIR_OP_SAMPLE;
src_count = 3;
break;
case HLSL_RESOURCE_SAMPLE_CMP:
- opcode = VKD3DSIH_SAMPLE_C;
+ opcode = VSIR_OP_SAMPLE_C;
src_count = 4;
break;
case HLSL_RESOURCE_SAMPLE_CMP_LZ:
- opcode = VKD3DSIH_SAMPLE_C_LZ;
+ opcode = VSIR_OP_SAMPLE_C_LZ;
src_count = 4;
break;
case HLSL_RESOURCE_SAMPLE_LOD:
- opcode = VKD3DSIH_SAMPLE_LOD;
+ opcode = VSIR_OP_SAMPLE_LOD;
src_count = 4;
break;
case HLSL_RESOURCE_SAMPLE_LOD_BIAS:
- opcode = VKD3DSIH_SAMPLE_B;
+ opcode = VSIR_OP_SAMPLE_B;
src_count = 4;
break;
case HLSL_RESOURCE_SAMPLE_GRAD:
- opcode = VKD3DSIH_SAMPLE_GRAD;
+ opcode = VSIR_OP_SAMPLE_GRAD;
src_count = 5;
break;
@@ -11068,15 +11591,15 @@ static bool sm4_generate_vsir_instr_sample(struct hlsl_ctx *ctx,
sampler, VKD3DSP_WRITEMASK_ALL, &instr->loc))
return false;
- if (opcode == VKD3DSIH_SAMPLE_LOD || opcode == VKD3DSIH_SAMPLE_B)
+ if (opcode == VSIR_OP_SAMPLE_LOD || opcode == VSIR_OP_SAMPLE_B)
{
vsir_src_from_hlsl_node(&ins->src[3], ctx, load->lod.node, VKD3DSP_WRITEMASK_ALL);
}
- else if (opcode == VKD3DSIH_SAMPLE_C || opcode == VKD3DSIH_SAMPLE_C_LZ)
+ else if (opcode == VSIR_OP_SAMPLE_C || opcode == VSIR_OP_SAMPLE_C_LZ)
{
vsir_src_from_hlsl_node(&ins->src[3], ctx, load->cmp.node, VKD3DSP_WRITEMASK_ALL);
}
- else if (opcode == VKD3DSIH_SAMPLE_GRAD)
+ else if (opcode == VSIR_OP_SAMPLE_GRAD)
{
vsir_src_from_hlsl_node(&ins->src[3], ctx, load->ddx.node, VKD3DSP_WRITEMASK_ALL);
vsir_src_from_hlsl_node(&ins->src[4], ctx, load->ddy.node, VKD3DSP_WRITEMASK_ALL);
@@ -11091,7 +11614,7 @@ static bool sm4_generate_vsir_instr_gather(struct hlsl_ctx *ctx, struct vsir_pro
const struct hlsl_ir_node *texel_offset = load->texel_offset.node;
const struct hlsl_ir_node *coords = load->coords.node;
const struct hlsl_deref *resource = &load->resource;
- enum vkd3d_shader_opcode opcode = VKD3DSIH_GATHER4;
+ enum vkd3d_shader_opcode opcode = VSIR_OP_GATHER4;
const struct hlsl_deref *sampler = &load->sampler;
const struct hlsl_ir_node *instr = &load->node;
unsigned int src_count = 3, current_arg = 0;
@@ -11105,13 +11628,13 @@ static bool sm4_generate_vsir_instr_gather(struct hlsl_ctx *ctx, struct vsir_pro
"Offset must resolve to integer literal in the range -8 to 7 for profiles < 5.");
return false;
}
- opcode = VKD3DSIH_GATHER4_PO;
+ opcode = VSIR_OP_GATHER4_PO;
++src_count;
}
if (compare)
{
- opcode = opcode == VKD3DSIH_GATHER4 ? VKD3DSIH_GATHER4_C : VKD3DSIH_GATHER4_PO_C;
+ opcode = opcode == VSIR_OP_GATHER4 ? VSIR_OP_GATHER4_C : VSIR_OP_GATHER4_PO_C;
++src_count;
}
@@ -11121,7 +11644,7 @@ static bool sm4_generate_vsir_instr_gather(struct hlsl_ctx *ctx, struct vsir_pro
vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr);
vsir_src_from_hlsl_node(&ins->src[current_arg++], ctx, coords, VKD3DSP_WRITEMASK_ALL);
- if (opcode == VKD3DSIH_GATHER4_PO || opcode == VKD3DSIH_GATHER4_PO_C)
+ if (opcode == VSIR_OP_GATHER4_PO || opcode == VSIR_OP_GATHER4_PO_C)
vsir_src_from_hlsl_node(&ins->src[current_arg++], ctx, texel_offset, VKD3DSP_WRITEMASK_ALL);
else
sm4_generate_vsir_encode_texel_offset_as_aoffimmi(ins, texel_offset);
@@ -11153,7 +11676,7 @@ static bool sm4_generate_vsir_instr_sample_info(struct hlsl_ctx *ctx,
VKD3D_ASSERT(type->e.numeric.type == HLSL_TYPE_UINT || type->e.numeric.type == HLSL_TYPE_FLOAT);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SAMPLE_INFO, 1, 1)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_SAMPLE_INFO, 1, 1)))
return false;
if (type->e.numeric.type == HLSL_TYPE_UINT)
@@ -11185,7 +11708,7 @@ static bool sm4_generate_vsir_instr_resinfo(struct hlsl_ctx *ctx,
VKD3D_ASSERT(type->e.numeric.type == HLSL_TYPE_UINT || type->e.numeric.type == HLSL_TYPE_FLOAT);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_RESINFO, 1, 2)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_RESINFO, 1, 2)))
return false;
if (type->e.numeric.type == HLSL_TYPE_UINT)
@@ -11237,7 +11760,7 @@ static bool sm4_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx,
return false;
}
- if (!load->resource.var->is_uniform)
+ if (!load->resource.var->is_uniform && !load->resource.var->is_tgsm)
{
hlsl_fixme(ctx, &load->node.loc, "Load from non-uniform resource variable.");
return false;
@@ -11290,25 +11813,25 @@ static bool sm4_generate_vsir_instr_interlocked(struct hlsl_ctx *ctx,
static const enum vkd3d_shader_opcode opcodes[] =
{
- [HLSL_INTERLOCKED_ADD] = VKD3DSIH_ATOMIC_IADD,
- [HLSL_INTERLOCKED_AND] = VKD3DSIH_ATOMIC_AND,
- [HLSL_INTERLOCKED_CMP_EXCH] = VKD3DSIH_ATOMIC_CMP_STORE,
- [HLSL_INTERLOCKED_MAX] = VKD3DSIH_ATOMIC_UMAX,
- [HLSL_INTERLOCKED_MIN] = VKD3DSIH_ATOMIC_UMIN,
- [HLSL_INTERLOCKED_OR] = VKD3DSIH_ATOMIC_OR,
- [HLSL_INTERLOCKED_XOR] = VKD3DSIH_ATOMIC_XOR,
+ [HLSL_INTERLOCKED_ADD] = VSIR_OP_ATOMIC_IADD,
+ [HLSL_INTERLOCKED_AND] = VSIR_OP_ATOMIC_AND,
+ [HLSL_INTERLOCKED_CMP_EXCH] = VSIR_OP_ATOMIC_CMP_STORE,
+ [HLSL_INTERLOCKED_MAX] = VSIR_OP_ATOMIC_UMAX,
+ [HLSL_INTERLOCKED_MIN] = VSIR_OP_ATOMIC_UMIN,
+ [HLSL_INTERLOCKED_OR] = VSIR_OP_ATOMIC_OR,
+ [HLSL_INTERLOCKED_XOR] = VSIR_OP_ATOMIC_XOR,
};
static const enum vkd3d_shader_opcode imm_opcodes[] =
{
- [HLSL_INTERLOCKED_ADD] = VKD3DSIH_IMM_ATOMIC_IADD,
- [HLSL_INTERLOCKED_AND] = VKD3DSIH_IMM_ATOMIC_AND,
- [HLSL_INTERLOCKED_CMP_EXCH] = VKD3DSIH_IMM_ATOMIC_CMP_EXCH,
- [HLSL_INTERLOCKED_EXCH] = VKD3DSIH_IMM_ATOMIC_EXCH,
- [HLSL_INTERLOCKED_MAX] = VKD3DSIH_IMM_ATOMIC_UMAX,
- [HLSL_INTERLOCKED_MIN] = VKD3DSIH_IMM_ATOMIC_UMIN,
- [HLSL_INTERLOCKED_OR] = VKD3DSIH_IMM_ATOMIC_OR,
- [HLSL_INTERLOCKED_XOR] = VKD3DSIH_IMM_ATOMIC_XOR,
+ [HLSL_INTERLOCKED_ADD] = VSIR_OP_IMM_ATOMIC_IADD,
+ [HLSL_INTERLOCKED_AND] = VSIR_OP_IMM_ATOMIC_AND,
+ [HLSL_INTERLOCKED_CMP_EXCH] = VSIR_OP_IMM_ATOMIC_CMP_EXCH,
+ [HLSL_INTERLOCKED_EXCH] = VSIR_OP_IMM_ATOMIC_EXCH,
+ [HLSL_INTERLOCKED_MAX] = VSIR_OP_IMM_ATOMIC_UMAX,
+ [HLSL_INTERLOCKED_MIN] = VSIR_OP_IMM_ATOMIC_UMIN,
+ [HLSL_INTERLOCKED_OR] = VSIR_OP_IMM_ATOMIC_OR,
+ [HLSL_INTERLOCKED_XOR] = VSIR_OP_IMM_ATOMIC_XOR,
};
struct hlsl_ir_node *cmp_value = interlocked->cmp_value.node, *value = interlocked->value.node;
@@ -11323,14 +11846,14 @@ static bool sm4_generate_vsir_instr_interlocked(struct hlsl_ctx *ctx,
if (value->data_type->e.numeric.type == HLSL_TYPE_INT)
{
- if (opcode == VKD3DSIH_ATOMIC_UMAX)
- opcode = VKD3DSIH_ATOMIC_IMAX;
- else if (opcode == VKD3DSIH_ATOMIC_UMIN)
- opcode = VKD3DSIH_ATOMIC_IMIN;
- else if (opcode == VKD3DSIH_IMM_ATOMIC_UMAX)
- opcode = VKD3DSIH_IMM_ATOMIC_IMAX;
- else if (opcode == VKD3DSIH_IMM_ATOMIC_UMIN)
- opcode = VKD3DSIH_IMM_ATOMIC_IMIN;
+ if (opcode == VSIR_OP_ATOMIC_UMAX)
+ opcode = VSIR_OP_ATOMIC_IMAX;
+ else if (opcode == VSIR_OP_ATOMIC_UMIN)
+ opcode = VSIR_OP_ATOMIC_IMIN;
+ else if (opcode == VSIR_OP_IMM_ATOMIC_UMAX)
+ opcode = VSIR_OP_IMM_ATOMIC_IMAX;
+ else if (opcode == VSIR_OP_IMM_ATOMIC_UMIN)
+ opcode = VSIR_OP_IMM_ATOMIC_IMIN;
}
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode,
@@ -11368,13 +11891,13 @@ static bool sm4_generate_vsir_instr_jump(struct hlsl_ctx *ctx,
switch (jump->type)
{
case HLSL_IR_JUMP_BREAK:
- return generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_BREAK, 0, 0);
+ return generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_BREAK, 0, 0);
case HLSL_IR_JUMP_CONTINUE:
- return generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_CONTINUE, 0, 0);
+ return generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_CONTINUE, 0, 0);
case HLSL_IR_JUMP_DISCARD_NZ:
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_DISCARD, 0, 1)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_DISCARD, 0, 1)))
return false;
ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ;
@@ -11396,7 +11919,7 @@ static bool sm4_generate_vsir_instr_sync(struct hlsl_ctx *ctx,
const struct hlsl_ir_node *instr = &sync->node;
struct vkd3d_shader_instruction *ins;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SYNC, 0, 0)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_SYNC, 0, 0)))
return false;
ins->flags = sync->sync_flags;
@@ -11412,7 +11935,7 @@ static void sm4_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program
VKD3D_ASSERT(iff->condition.node->data_type->e.numeric.dimx == 1);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_IF, 0, 1)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_IF, 0, 1)))
return;
ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ;
@@ -11422,12 +11945,12 @@ static void sm4_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program
if (!list_empty(&iff->else_block.instrs))
{
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ELSE, 0, 0)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ELSE, 0, 0)))
return;
sm4_generate_vsir_block(ctx, &iff->else_block, program);
}
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ENDIF, 0, 0)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ENDIF, 0, 0)))
return;
}
@@ -11437,12 +11960,12 @@ static void sm4_generate_vsir_instr_loop(struct hlsl_ctx *ctx,
struct hlsl_ir_node *instr = &loop->node;
struct vkd3d_shader_instruction *ins;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_LOOP, 0, 0)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_LOOP, 0, 0)))
return;
sm4_generate_vsir_block(ctx, &loop->body, program);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ENDLOOP, 0, 0)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ENDLOOP, 0, 0)))
return;
}
@@ -11454,7 +11977,7 @@ static void sm4_generate_vsir_instr_switch(struct hlsl_ctx *ctx,
struct vkd3d_shader_instruction *ins;
struct hlsl_ir_switch_case *cas;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SWITCH, 0, 1)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_SWITCH, 0, 1)))
return;
vsir_src_from_hlsl_node(&ins->src[0], ctx, selector, VKD3DSP_WRITEMASK_ALL);
@@ -11462,22 +11985,22 @@ static void sm4_generate_vsir_instr_switch(struct hlsl_ctx *ctx,
{
if (cas->is_default)
{
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_DEFAULT, 0, 0)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_DEFAULT, 0, 0)))
return;
}
else
{
struct hlsl_constant_value value = {.u[0].u = cas->value};
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_CASE, 0, 1)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_CASE, 0, 1)))
return;
- vsir_src_from_hlsl_constant_value(&ins->src[0], ctx, &value, VKD3D_DATA_UINT, 1, VKD3DSP_WRITEMASK_ALL);
+ vsir_src_from_hlsl_constant_value(&ins->src[0], ctx, &value, VSIR_DATA_U32, 1, VKD3DSP_WRITEMASK_ALL);
}
sm4_generate_vsir_block(ctx, &cas->body, program);
}
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ENDSWITCH, 0, 0)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ENDSWITCH, 0, 0)))
return;
}
@@ -11563,8 +12086,9 @@ static void sm4_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *blo
}
}
-static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx,
- struct hlsl_ir_function_decl *func, uint64_t config_flags, struct vsir_program *program)
+static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct list *semantic_vars,
+ struct hlsl_ir_function_decl *func, struct hlsl_block *body, uint64_t config_flags,
+ struct vsir_program *program)
{
struct hlsl_block block = {0};
struct hlsl_scope *scope;
@@ -11573,16 +12097,16 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx,
ctx->is_patch_constant_func = func == ctx->patch_constant_func;
- compute_liveness(ctx, func);
- mark_indexable_vars(ctx, func);
- temp_count = allocate_temp_registers(ctx, func);
+ compute_liveness(ctx, body);
+ mark_indexable_vars(ctx, body);
+ temp_count = allocate_temp_registers(ctx, body, semantic_vars);
if (ctx->result)
return;
program->temp_count = max(program->temp_count, temp_count);
hlsl_block_init(&block);
- LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry)
+ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry)
{
if ((var->is_input_semantic && var->last_read)
|| (var->is_output_semantic && var->first_write))
@@ -11596,7 +12120,7 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx,
{
LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry)
{
- if (var->is_uniform || var->is_input_semantic || var->is_output_semantic)
+ if (var->is_uniform || var->is_tgsm || var->is_input_semantic || var->is_output_semantic)
continue;
if (!var->regs[HLSL_REGSET_NUMERIC].allocated)
continue;
@@ -11611,13 +12135,13 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx,
}
}
- list_move_head(&func->body.instrs, &block.instrs);
+ list_move_head(&body->instrs, &block.instrs);
hlsl_block_cleanup(&block);
- sm4_generate_vsir_block(ctx, &func->body, program);
+ sm4_generate_vsir_block(ctx, body, program);
- generate_vsir_add_program_instruction(ctx, program, &func->loc, VKD3DSIH_RET, 0, 0);
+ generate_vsir_add_program_instruction(ctx, program, &func->loc, VSIR_OP_RET, 0, 0);
}
static int sm4_compare_extern_resources(const void *a, const void *b)
@@ -11839,8 +12363,8 @@ static void generate_vsir_scan_required_features(struct hlsl_ctx *ctx, struct vs
* STENCIL_REF, and TYPED_UAV_LOAD_ADDITIONAL_FORMATS. */
}
-static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx,
- struct vsir_program *program, const struct hlsl_ir_function_decl *entry_func)
+static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx, struct vsir_program *program,
+ const struct list *semantic_vars, const struct hlsl_ir_function_decl *entry_func)
{
const struct vkd3d_shader_version *version = &program->shader_version;
struct extern_resource *extern_resources;
@@ -11866,7 +12390,7 @@ static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx,
sm4_free_extern_resources(extern_resources, extern_resources_count);
- LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry)
+ LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry)
{
const struct hlsl_type *type = var->data_type;
@@ -11897,7 +12421,7 @@ static void sm4_generate_vsir_add_dcl_constant_buffer(struct hlsl_ctx *ctx,
struct vkd3d_shader_src_param *src_param;
struct vkd3d_shader_instruction *ins;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &cbuffer->loc, VKD3DSIH_DCL_CONSTANT_BUFFER, 0, 0)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &cbuffer->loc, VSIR_OP_DCL_CONSTANT_BUFFER, 0, 0)))
{
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
return;
@@ -11906,7 +12430,7 @@ static void sm4_generate_vsir_add_dcl_constant_buffer(struct hlsl_ctx *ctx,
ins->declaration.cb.size = cbuffer->size;
src_param = &ins->declaration.cb.src;
- vsir_src_param_init(src_param, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 0);
+ vsir_src_param_init(src_param, VKD3DSPR_CONSTBUFFER, VSIR_DATA_F32, 0);
src_param->reg.dimension = VSIR_DIMENSION_VEC4;
src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
@@ -11938,7 +12462,7 @@ static void sm4_generate_vsir_add_dcl_sampler(struct hlsl_ctx *ctx,
if (resource->var && !resource->var->objects_usage[HLSL_REGSET_SAMPLERS][i].used)
continue;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &resource->loc, VKD3DSIH_DCL_SAMPLER, 0, 0)))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &resource->loc, VSIR_OP_DCL_SAMPLER, 0, 0)))
{
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
return;
@@ -11948,7 +12472,7 @@ static void sm4_generate_vsir_add_dcl_sampler(struct hlsl_ctx *ctx,
ins->flags |= VKD3DSI_SAMPLER_COMPARISON_MODE;
src_param = &ins->declaration.sampler.src;
- vsir_src_param_init(src_param, VKD3DSPR_SAMPLER, VKD3D_DATA_UNUSED, 0);
+ vsir_src_param_init(src_param, VKD3DSPR_SAMPLER, VSIR_DATA_UNUSED, 0);
ins->declaration.sampler.range.first = array_first;
ins->declaration.sampler.range.last = array_last;
@@ -11992,30 +12516,33 @@ static enum vkd3d_shader_resource_type sm4_generate_vsir_get_resource_type(const
}
}
-static enum vkd3d_data_type sm4_generate_vsir_get_format_type(const struct hlsl_type *type)
+static enum vsir_data_type sm4_generate_vsir_get_format_type(const struct hlsl_type *type)
{
const struct hlsl_type *format = type->e.resource.format;
+ if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
+ return VSIR_DATA_MIXED;
+
switch (format->e.numeric.type)
{
case HLSL_TYPE_DOUBLE:
- return VKD3D_DATA_DOUBLE;
+ return VSIR_DATA_F64;
case HLSL_TYPE_FLOAT:
case HLSL_TYPE_HALF:
if (format->modifiers & HLSL_MODIFIER_UNORM)
- return VKD3D_DATA_UNORM;
+ return VSIR_DATA_UNORM;
if (format->modifiers & HLSL_MODIFIER_SNORM)
- return VKD3D_DATA_SNORM;
- return VKD3D_DATA_FLOAT;
+ return VSIR_DATA_SNORM;
+ return VSIR_DATA_F32;
case HLSL_TYPE_INT:
- return VKD3D_DATA_INT;
+ return VSIR_DATA_I32;
case HLSL_TYPE_BOOL:
case HLSL_TYPE_MIN16UINT:
case HLSL_TYPE_UINT:
- return VKD3D_DATA_UINT;
+ return VSIR_DATA_U32;
}
vkd3d_unreachable();
@@ -12026,14 +12553,11 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx,
bool uav)
{
enum hlsl_regset regset = uav ? HLSL_REGSET_UAVS : HLSL_REGSET_TEXTURES;
- struct vkd3d_shader_structured_resource *structured_resource;
- struct vkd3d_shader_dst_param *dst_param;
- struct vkd3d_shader_semantic *semantic;
struct vkd3d_shader_instruction *ins;
struct hlsl_type *component_type;
enum vkd3d_shader_opcode opcode;
bool multisampled;
- unsigned int i, j;
+ unsigned int i;
VKD3D_ASSERT(resource->regset == regset);
VKD3D_ASSERT(hlsl_version_lt(ctx, 5, 1) || resource->bind_count == 1);
@@ -12044,6 +12568,7 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx,
{
unsigned int array_first = resource->index + i;
unsigned int array_last = resource->index + i; /* FIXME: array end. */
+ struct vkd3d_shader_resource *vsir_resource;
if (resource->var && !resource->var->objects_usage[regset][i].used)
continue;
@@ -12053,13 +12578,13 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx,
switch (component_type->sampler_dim)
{
case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER:
- opcode = VKD3DSIH_DCL_UAV_STRUCTURED;
+ opcode = VSIR_OP_DCL_UAV_STRUCTURED;
break;
case HLSL_SAMPLER_DIM_RAW_BUFFER:
- opcode = VKD3DSIH_DCL_UAV_RAW;
+ opcode = VSIR_OP_DCL_UAV_RAW;
break;
default:
- opcode = VKD3DSIH_DCL_UAV_TYPED;
+ opcode = VSIR_OP_DCL_UAV_TYPED;
break;
}
}
@@ -12068,10 +12593,10 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx,
switch (component_type->sampler_dim)
{
case HLSL_SAMPLER_DIM_RAW_BUFFER:
- opcode = VKD3DSIH_DCL_RESOURCE_RAW;
+ opcode = VSIR_OP_DCL_RESOURCE_RAW;
break;
default:
- opcode = VKD3DSIH_DCL;
+ opcode = VSIR_OP_DCL;
break;
}
}
@@ -12081,13 +12606,16 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx,
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
return;
}
- semantic = &ins->declaration.semantic;
- structured_resource = &ins->declaration.structured_resource;
- dst_param = &semantic->resource.reg;
- vsir_dst_param_init(dst_param, uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VKD3D_DATA_UNUSED, 0);
- if (uav && component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
- structured_resource->byte_stride = 4 * component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC];
+ if (component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER)
+ vsir_resource = &ins->declaration.raw_resource.resource;
+ else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
+ vsir_resource = &ins->declaration.structured_resource.resource;
+ else
+ vsir_resource = &ins->declaration.semantic.resource;
+
+ vsir_dst_param_init(&vsir_resource->reg, uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VSIR_DATA_UNUSED, 0);
+
if (uav && component_type->e.resource.rasteriser_ordered)
ins->flags = VKD3DSUF_RASTERISER_ORDERED_VIEW;
@@ -12101,64 +12629,103 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx,
ctx->profile->major_version, ctx->profile->minor_version);
}
- for (j = 0; j < 4; ++j)
- semantic->resource_data_type[j] = sm4_generate_vsir_get_format_type(component_type);
+ vsir_resource->range.first = array_first;
+ vsir_resource->range.last = array_last;
+ vsir_resource->range.space = resource->space;
- semantic->resource.range.first = array_first;
- semantic->resource.range.last = array_last;
- semantic->resource.range.space = resource->space;
-
- dst_param->reg.idx[0].offset = resource->id;
- dst_param->reg.idx[1].offset = array_first;
- dst_param->reg.idx[2].offset = array_last;
- dst_param->reg.idx_count = 3;
+ vsir_resource->reg.reg.idx[0].offset = resource->id;
+ vsir_resource->reg.reg.idx[1].offset = array_first;
+ vsir_resource->reg.reg.idx[2].offset = array_last;
+ vsir_resource->reg.reg.idx_count = 3;
ins->resource_type = sm4_generate_vsir_get_resource_type(resource->component_type);
- if (resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER)
+
+ if (component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER)
+ {
ins->raw = true;
- if (resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
+ }
+ else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
{
ins->structured = true;
ins->resource_stride = 4 * component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC];
+ ins->declaration.structured_resource.byte_stride = ins->resource_stride;
}
+ else
+ {
+ for (unsigned int j = 0; j < 4; ++j)
+ ins->declaration.semantic.resource_data_type[j] = sm4_generate_vsir_get_format_type(component_type);
- if (multisampled)
- semantic->sample_count = component_type->sample_count;
+ if (multisampled)
+ ins->declaration.semantic.sample_count = component_type->sample_count;
+ }
}
}
-/* OBJECTIVE: Translate all the information from ctx and entry_func to the
- * vsir_program, so it can be used as input to tpf_compile() without relying
- * on ctx and entry_func. */
-static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func,
- uint64_t config_flags, struct vsir_program *program)
+static void sm4_generate_vsir_add_dcl_tgsm(struct hlsl_ctx *ctx,
+ struct vsir_program *program, const struct hlsl_ir_var *var)
{
- struct vkd3d_shader_version version = {0};
- struct extern_resource *extern_resources;
- unsigned int extern_resources_count;
- const struct hlsl_buffer *cbuffer;
+ struct vkd3d_shader_dst_param *dst_param;
+ struct vkd3d_shader_instruction *ins;
- version.major = ctx->profile->major_version;
- version.minor = ctx->profile->minor_version;
- version.type = ctx->profile->type;
+ if (!hlsl_is_numeric_type(var->data_type))
+ {
+ hlsl_fixme(ctx, &var->loc, "Structured TGSM declaration.");
+ return;
+ }
- if (!vsir_program_init(program, NULL, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4))
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &var->loc, VSIR_OP_DCL_TGSM_RAW, 0, 0)))
{
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
return;
}
- generate_vsir_signature(ctx, program, func);
- if (version.type == VKD3D_SHADER_TYPE_HULL)
- generate_vsir_signature(ctx, program, ctx->patch_constant_func);
+ dst_param = &ins->declaration.tgsm_raw.reg;
+
+ vsir_dst_param_init(dst_param, VKD3DSPR_GROUPSHAREDMEM, VSIR_DATA_F32, 1);
+ dst_param->reg.dimension = VSIR_DIMENSION_NONE;
+ dst_param->reg.idx[0].offset = var->regs[HLSL_REGSET_NUMERIC].id;
+
+ ins->declaration.tgsm_raw.byte_count = var->data_type->reg_size[HLSL_REGSET_NUMERIC] * 4;
+ ins->declaration.tgsm_raw.zero_init = false;
+}
- if (version.type == VKD3D_SHADER_TYPE_COMPUTE)
+static void sm4_generate_vsir_add_dcl_stream(struct hlsl_ctx *ctx,
+ struct vsir_program *program, const struct hlsl_ir_var *var)
+{
+ struct vkd3d_shader_instruction *ins;
+
+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, &var->loc, VSIR_OP_DCL_STREAM, 0, 1)))
+ {
+ ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
+ return;
+ }
+
+ vsir_src_param_init(&ins->src[0], VKD3DSPR_STREAM, VSIR_DATA_UNUSED, 1);
+ ins->src[0].reg.dimension = VSIR_DIMENSION_NONE;
+ ins->src[0].reg.idx[0].offset = var->regs[HLSL_REGSET_STREAM_OUTPUTS].index;
+}
+
+/* OBJECTIVE: Translate all the information from ctx and entry_func to the
+ * vsir_program, so it can be used as input to tpf_compile() without relying
+ * on ctx and entry_func. */
+static void sm4_generate_vsir(struct hlsl_ctx *ctx,
+ const struct vkd3d_shader_compile_info *compile_info, struct hlsl_ir_function_decl *func,
+ struct list *semantic_vars, struct hlsl_block *body, struct list *patch_semantic_vars,
+ struct hlsl_block *patch_body, uint64_t config_flags, struct vsir_program *program)
+{
+ const struct vkd3d_shader_version *version = &program->shader_version;
+ struct extern_resource *extern_resources;
+ unsigned int extern_resources_count;
+ const struct hlsl_buffer *cbuffer;
+ const struct hlsl_ir_var *var;
+
+ if (version->type == VKD3D_SHADER_TYPE_COMPUTE)
{
program->thread_group_size.x = ctx->thread_count[0];
program->thread_group_size.y = ctx->thread_count[1];
program->thread_group_size.z = ctx->thread_count[2];
}
- else if (version.type == VKD3D_SHADER_TYPE_HULL)
+ else if (version->type == VKD3D_SHADER_TYPE_HULL)
{
program->input_control_point_count = ctx->input_control_point_count == UINT_MAX
? 1 : ctx->input_control_point_count;
@@ -12167,13 +12734,13 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
program->tess_partitioning = ctx->partitioning;
program->tess_output_primitive = ctx->output_primitive;
}
- else if (version.type == VKD3D_SHADER_TYPE_DOMAIN)
+ else if (version->type == VKD3D_SHADER_TYPE_DOMAIN)
{
program->input_control_point_count = ctx->input_control_point_count == UINT_MAX
? 0 : ctx->input_control_point_count;
program->tess_domain = ctx->domain;
}
- else if (version.type == VKD3D_SHADER_TYPE_GEOMETRY)
+ else if (version->type == VKD3D_SHADER_TYPE_GEOMETRY)
{
program->input_control_point_count = ctx->input_control_point_count;
program->input_primitive = ctx->input_primitive_type;
@@ -12201,19 +12768,39 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
}
sm4_free_extern_resources(extern_resources, extern_resources_count);
- if (version.type == VKD3D_SHADER_TYPE_HULL)
+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+ {
+ if (var->is_tgsm && var->regs[HLSL_REGSET_NUMERIC].allocated)
+ sm4_generate_vsir_add_dcl_tgsm(ctx, program, var);
+ }
+
+ if (version->type == VKD3D_SHADER_TYPE_GEOMETRY && version->major >= 5)
+ {
+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+ {
+ if (var->bind_count[HLSL_REGSET_STREAM_OUTPUTS])
+ sm4_generate_vsir_add_dcl_stream(ctx, program, var);
+ }
+ }
+
+ program->ssa_count = 0;
+
+ if (version->type == VKD3D_SHADER_TYPE_HULL)
generate_vsir_add_program_instruction(ctx, program,
- &ctx->patch_constant_func->loc, VKD3DSIH_HS_CONTROL_POINT_PHASE, 0, 0);
- sm4_generate_vsir_add_function(ctx, func, config_flags, program);
- if (version.type == VKD3D_SHADER_TYPE_HULL)
+ &ctx->patch_constant_func->loc, VSIR_OP_HS_CONTROL_POINT_PHASE, 0, 0);
+ sm4_generate_vsir_add_function(ctx, semantic_vars, func, body, config_flags, program);
+ if (version->type == VKD3D_SHADER_TYPE_HULL)
{
generate_vsir_add_program_instruction(ctx, program,
- &ctx->patch_constant_func->loc, VKD3DSIH_HS_FORK_PHASE, 0, 0);
- sm4_generate_vsir_add_function(ctx, ctx->patch_constant_func, config_flags, program);
+ &ctx->patch_constant_func->loc, VSIR_OP_HS_FORK_PHASE, 0, 0);
+ sm4_generate_vsir_add_function(ctx, patch_semantic_vars,
+ ctx->patch_constant_func, patch_body, config_flags, program);
}
generate_vsir_scan_required_features(ctx, program);
- generate_vsir_scan_global_flags(ctx, program, func);
+ generate_vsir_scan_global_flags(ctx, program, semantic_vars, func);
+
+ program->ssa_count = ctx->ssa_count;
}
/* For some reason, for matrices, values from default value initializers end
@@ -12297,6 +12884,9 @@ static enum D3D_RESOURCE_RETURN_TYPE sm4_data_type(const struct hlsl_type *type)
{
const struct hlsl_type *format = type->e.resource.format;
+ if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER)
+ return D3D_RETURN_TYPE_MIXED;
+
switch (format->e.numeric.type)
{
case HLSL_TYPE_DOUBLE:
@@ -13352,15 +13942,14 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct
return true;
}
-static void process_entry_function(struct hlsl_ctx *ctx,
+static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_vars, struct hlsl_block *body,
const struct hlsl_block *global_uniform_block, struct hlsl_ir_function_decl *entry_func)
{
+ struct stream_append_ctx stream_append_ctx = { .semantic_vars = semantic_vars };
const struct hlsl_ir_var *input_patch = NULL, *output_patch = NULL;
const struct hlsl_profile_info *profile = ctx->profile;
struct hlsl_block static_initializers, global_uniforms;
- struct hlsl_block *const body = &entry_func->body;
struct recursive_call_ctx recursive_call_ctx;
- struct stream_append_ctx stream_append_ctx;
uint32_t output_reg_count;
struct hlsl_ir_var *var;
unsigned int i;
@@ -13368,6 +13957,8 @@ static void process_entry_function(struct hlsl_ctx *ctx,
ctx->is_patch_constant_func = entry_func == ctx->patch_constant_func;
+ hlsl_clone_block(ctx, body, &entry_func->body);
+
if (!hlsl_clone_block(ctx, &static_initializers, &ctx->static_initializers))
return;
list_move_head(&body->instrs, &static_initializers.instrs);
@@ -13401,6 +13992,22 @@ static void process_entry_function(struct hlsl_ctx *ctx,
lower_ir(ctx, lower_matrix_swizzles, body);
lower_ir(ctx, lower_index_loads, body);
+ lower_ir(ctx, lower_tgsm_loads, body);
+ lower_ir(ctx, lower_tgsm_stores, body);
+
+ if (entry_func->return_var)
+ {
+ if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY)
+ hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
+ "Geometry shaders cannot return values.");
+ else if (entry_func->return_var->data_type->class != HLSL_CLASS_STRUCT
+ && !entry_func->return_var->semantic.name)
+ hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
+ "Entry point \"%s\" is missing a return value semantic.", entry_func->func->name);
+
+ append_output_var_copy(ctx, body, semantic_vars, entry_func->return_var);
+ }
+
for (i = 0; i < entry_func->parameters.count; ++i)
{
var = entry_func->parameters.vars[i];
@@ -13454,7 +14061,7 @@ static void process_entry_function(struct hlsl_ctx *ctx,
}
validate_and_record_prim_type(ctx, var);
- prepend_input_var_copy(ctx, entry_func, var);
+ prepend_input_var_copy(ctx, body, semantic_vars, var);
}
else if (var->data_type->reg_size[HLSL_REGSET_STREAM_OUTPUTS])
{
@@ -13490,7 +14097,7 @@ static void process_entry_function(struct hlsl_ctx *ctx,
continue;
}
- prepend_input_var_copy(ctx, entry_func, var);
+ prepend_input_var_copy(ctx, body, semantic_vars, var);
}
if (var->storage_modifiers & HLSL_STORAGE_OUT)
{
@@ -13501,29 +14108,39 @@ static void process_entry_function(struct hlsl_ctx *ctx,
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
"Output parameters are not allowed in geometry shaders.");
else
- append_output_var_copy(ctx, entry_func, var);
+ append_output_var_copy(ctx, body, semantic_vars, var);
}
}
}
+
if (entry_func->return_var)
{
- if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY)
- hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE,
- "Geometry shaders cannot return values.");
- else if (entry_func->return_var->data_type->class != HLSL_CLASS_STRUCT
- && !entry_func->return_var->semantic.name)
- hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC,
- "Entry point \"%s\" is missing a return value semantic.", entry_func->func->name);
-
- append_output_var_copy(ctx, entry_func, entry_func->return_var);
-
if (profile->type == VKD3D_SHADER_TYPE_HULL && !ctx->is_patch_constant_func)
ctx->output_control_point_type = entry_func->return_var->data_type;
}
else
{
if (profile->type == VKD3D_SHADER_TYPE_HULL && !ctx->is_patch_constant_func)
- hlsl_fixme(ctx, &entry_func->loc, "Passthrough hull shader control point function.");
+ {
+ if (!ctx->input_control_point_type)
+ {
+ hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INPUT_PATCH,
+ "Pass-through control point function \"%s\" is missing an InputPatch parameter.",
+ entry_func->func->name);
+ }
+ else if (ctx->output_control_point_count
+ && ctx->output_control_point_count != ctx->input_control_point_count)
+ {
+ hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT,
+ "Output control point count %u does not match the input control point count %u.",
+ ctx->output_control_point_count, ctx->input_control_point_count);
+ }
+ else
+ {
+ ctx->output_control_point_type = ctx->input_control_point_type;
+ ctx->output_control_point_count = ctx->input_control_point_count;
+ }
+ }
}
if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY && ctx->input_primitive_type == VKD3D_PT_UNDEFINED)
@@ -13540,8 +14157,8 @@ static void process_entry_function(struct hlsl_ctx *ctx,
hlsl_transform_ir(ctx, lower_resource_load_bias, body, NULL);
}
- compute_liveness(ctx, entry_func);
- transform_derefs(ctx, divert_written_uniform_derefs_to_temp, &entry_func->body);
+ compute_liveness(ctx, body);
+ transform_derefs(ctx, divert_written_uniform_derefs_to_temp, body);
loop_unrolling_execute(ctx, body);
hlsl_run_const_passes(ctx, body);
@@ -13561,7 +14178,7 @@ static void process_entry_function(struct hlsl_ctx *ctx,
do
{
progress = vectorize_exprs(ctx, body);
- compute_liveness(ctx, entry_func);
+ compute_liveness(ctx, body);
progress |= hlsl_transform_ir(ctx, dce, body, NULL);
progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL);
progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL);
@@ -13574,7 +14191,7 @@ static void process_entry_function(struct hlsl_ctx *ctx,
hlsl_transform_ir(ctx, lower_combined_samples, body, NULL);
do
- compute_liveness(ctx, entry_func);
+ compute_liveness(ctx, body);
while (hlsl_transform_ir(ctx, dce, body, NULL));
hlsl_transform_ir(ctx, track_components_usage, body, NULL);
@@ -13587,9 +14204,6 @@ static void process_entry_function(struct hlsl_ctx *ctx,
{
allocate_stream_outputs(ctx);
validate_and_record_stream_outputs(ctx);
-
- memset(&stream_append_ctx, 0, sizeof(stream_append_ctx));
- stream_append_ctx.func = entry_func;
hlsl_transform_ir(ctx, lower_stream_appends, body, &stream_append_ctx);
}
@@ -13630,7 +14244,7 @@ static void process_entry_function(struct hlsl_ctx *ctx,
hlsl_run_folding_passes(ctx, body);
do
- compute_liveness(ctx, entry_func);
+ compute_liveness(ctx, body);
while (hlsl_transform_ir(ctx, dce, body, NULL));
/* TODO: move forward, remove when no longer needed */
@@ -13639,27 +14253,30 @@ static void process_entry_function(struct hlsl_ctx *ctx,
transform_derefs(ctx, clean_constant_deref_offset_srcs, body);
do
- compute_liveness(ctx, entry_func);
+ compute_liveness(ctx, body);
while (hlsl_transform_ir(ctx, dce, body, NULL));
- compute_liveness(ctx, entry_func);
+ compute_liveness(ctx, body);
mark_vars_usage(ctx);
calculate_resource_register_counts(ctx);
allocate_register_reservations(ctx, &ctx->extern_vars);
- allocate_register_reservations(ctx, &entry_func->extern_vars);
- allocate_semantic_registers(ctx, entry_func, &output_reg_count);
+ allocate_register_reservations(ctx, semantic_vars);
+ allocate_semantic_registers(ctx, semantic_vars, &output_reg_count);
if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY)
- validate_max_output_size(ctx, entry_func, output_reg_count);
+ validate_max_output_size(ctx, semantic_vars, output_reg_count, &entry_func->loc);
}
-int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func,
- enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out)
+int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info,
+ struct hlsl_ir_function_decl *entry_func, struct vsir_program *program,
+ struct vkd3d_shader_code *reflection_data)
{
+ struct hlsl_block global_uniform_block, body, patch_body;
+ uint32_t config_flags = vkd3d_shader_init_config_flags();
const struct hlsl_profile_info *profile = ctx->profile;
- struct hlsl_block global_uniform_block;
+ struct list semantic_vars, patch_semantic_vars;
struct hlsl_ir_var *var;
parse_entry_function_attributes(ctx, entry_func);
@@ -13678,21 +14295,31 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_ATTRIBUTE,
"Entry point \"%s\" is missing a [maxvertexcount] attribute.", entry_func->func->name);
+ list_init(&ctx->extern_vars);
+ list_init(&semantic_vars);
+ list_init(&patch_semantic_vars);
hlsl_block_init(&global_uniform_block);
LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry)
{
if (var->storage_modifiers & HLSL_STORAGE_UNIFORM)
+ {
prepend_uniform_copy(ctx, &global_uniform_block, var);
+ }
+ else if (var->storage_modifiers & HLSL_STORAGE_GROUPSHARED)
+ {
+ var->is_tgsm = 1;
+ list_add_tail(&ctx->extern_vars, &var->extern_entry);
+ }
}
- process_entry_function(ctx, &global_uniform_block, entry_func);
+ process_entry_function(ctx, &semantic_vars, &body, &global_uniform_block, entry_func);
if (ctx->result)
return ctx->result;
if (profile->type == VKD3D_SHADER_TYPE_HULL)
{
- process_entry_function(ctx, &global_uniform_block, ctx->patch_constant_func);
+ process_entry_function(ctx, &patch_semantic_vars, &patch_body, &global_uniform_block, ctx->patch_constant_func);
if (ctx->result)
return ctx->result;
}
@@ -13701,79 +14328,49 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
if (profile->major_version < 4)
{
- mark_indexable_vars(ctx, entry_func);
- allocate_const_registers(ctx, entry_func);
+ mark_indexable_vars(ctx, &body);
+ allocate_const_registers(ctx, &body);
sort_uniforms_by_bind_count(ctx, HLSL_REGSET_SAMPLERS);
- allocate_objects(ctx, entry_func, HLSL_REGSET_SAMPLERS);
+ allocate_objects(ctx, &semantic_vars, HLSL_REGSET_SAMPLERS);
}
else
{
allocate_buffers(ctx);
- allocate_objects(ctx, entry_func, HLSL_REGSET_TEXTURES);
- allocate_objects(ctx, entry_func, HLSL_REGSET_UAVS);
- allocate_objects(ctx, entry_func, HLSL_REGSET_SAMPLERS);
+ allocate_objects(ctx, &semantic_vars, HLSL_REGSET_TEXTURES);
+ allocate_objects(ctx, &semantic_vars, HLSL_REGSET_UAVS);
+ allocate_objects(ctx, &semantic_vars, HLSL_REGSET_SAMPLERS);
+ allocate_tgsms(ctx);
}
if (TRACE_ON())
+ {
rb_for_each_entry(&ctx->functions, dump_function, ctx);
+ hlsl_dump_function(ctx, entry_func, "processed entry point", &body);
+ if (profile->type == VKD3D_SHADER_TYPE_HULL)
+ hlsl_dump_function(ctx, ctx->patch_constant_func, "processed patch-constant function", &patch_body);
+ }
if (ctx->result)
return ctx->result;
- switch (target_type)
- {
- case VKD3D_SHADER_TARGET_D3D_BYTECODE:
- {
- uint32_t config_flags = vkd3d_shader_init_config_flags();
- struct vkd3d_shader_code ctab = {0};
- struct vsir_program program;
- int result;
-
- sm1_generate_ctab(ctx, &ctab);
- if (ctx->result)
- return ctx->result;
-
- sm1_generate_vsir(ctx, entry_func, config_flags, &program);
- if (ctx->result)
- {
- vsir_program_cleanup(&program);
- vkd3d_shader_free_shader_code(&ctab);
- return ctx->result;
- }
+ generate_vsir_signature(ctx, program, entry_func, &semantic_vars);
+ if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL)
+ generate_vsir_signature(ctx, program, ctx->patch_constant_func, &patch_semantic_vars);
- result = d3dbc_compile(&program, config_flags, NULL, &ctab, out, ctx->message_context);
- vsir_program_cleanup(&program);
- vkd3d_shader_free_shader_code(&ctab);
- return result;
- }
-
- case VKD3D_SHADER_TARGET_DXBC_TPF:
- {
- uint32_t config_flags = vkd3d_shader_init_config_flags();
- struct vkd3d_shader_code rdef = {0};
- struct vsir_program program;
- int result;
-
- sm4_generate_rdef(ctx, &rdef);
- if (ctx->result)
- return ctx->result;
-
- sm4_generate_vsir(ctx, entry_func, config_flags, &program);
- if (ctx->result)
- {
- vsir_program_cleanup(&program);
- vkd3d_shader_free_shader_code(&rdef);
- return ctx->result;
- }
+ if (program->shader_version.major < 4)
+ sm1_generate_ctab(ctx, reflection_data);
+ else
+ sm4_generate_rdef(ctx, reflection_data);
+ if (ctx->result)
+ return ctx->result;
- result = tpf_compile(&program, config_flags, &rdef, out, ctx->message_context);
- vsir_program_cleanup(&program);
- vkd3d_shader_free_shader_code(&rdef);
- return result;
- }
+ if (program->shader_version.major < 4)
+ sm1_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, config_flags, program);
+ else
+ sm4_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body,
+ &patch_semantic_vars, &patch_body, config_flags, program);
+ if (ctx->result)
+ vkd3d_shader_free_shader_code(reflection_data);
- default:
- ERR("Unsupported shader target type %#x.\n", target_type);
- return VKD3D_ERROR_INVALID_ARGUMENT;
- }
+ return ctx->result;
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index 7466f7a2da1..23e059a3490 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -29,6 +29,350 @@ struct vsir_transformation_context
struct vkd3d_shader_message_context *message_context;
};
+const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error)
+{
+ static const char * const names[] =
+ {
+ [VSIR_OP_ABS ] = "abs",
+ [VSIR_OP_ACOS ] = "acos",
+ [VSIR_OP_ADD ] = "add",
+ [VSIR_OP_AND ] = "and",
+ [VSIR_OP_ASIN ] = "asin",
+ [VSIR_OP_ATAN ] = "atan",
+ [VSIR_OP_ATOMIC_AND ] = "atomic_and",
+ [VSIR_OP_ATOMIC_CMP_STORE ] = "atomic_cmp_store",
+ [VSIR_OP_ATOMIC_IADD ] = "atomic_iadd",
+ [VSIR_OP_ATOMIC_IMAX ] = "atomic_imax",
+ [VSIR_OP_ATOMIC_IMIN ] = "atomic_imin",
+ [VSIR_OP_ATOMIC_OR ] = "atomic_or",
+ [VSIR_OP_ATOMIC_UMAX ] = "atomic_umax",
+ [VSIR_OP_ATOMIC_UMIN ] = "atomic_umin",
+ [VSIR_OP_ATOMIC_XOR ] = "atomic_xor",
+ [VSIR_OP_BEM ] = "bem",
+ [VSIR_OP_BFI ] = "bfi",
+ [VSIR_OP_BFREV ] = "bfrev",
+ [VSIR_OP_BRANCH ] = "branch",
+ [VSIR_OP_BREAK ] = "break",
+ [VSIR_OP_BREAKC ] = "break",
+ [VSIR_OP_BREAKP ] = "breakp",
+ [VSIR_OP_BUFINFO ] = "bufinfo",
+ [VSIR_OP_CALL ] = "call",
+ [VSIR_OP_CALLNZ ] = "callnz",
+ [VSIR_OP_CASE ] = "case",
+ [VSIR_OP_CHECK_ACCESS_FULLY_MAPPED ] = "check_access_fully_mapped",
+ [VSIR_OP_CMP ] = "cmp",
+ [VSIR_OP_CND ] = "cnd",
+ [VSIR_OP_COS ] = "cos",
+ [VSIR_OP_CONTINUE ] = "continue",
+ [VSIR_OP_CONTINUEP ] = "continuec",
+ [VSIR_OP_COUNTBITS ] = "countbits",
+ [VSIR_OP_CRS ] = "crs",
+ [VSIR_OP_CUT ] = "cut",
+ [VSIR_OP_CUT_STREAM ] = "cut_stream",
+ [VSIR_OP_DADD ] = "dadd",
+ [VSIR_OP_DCL ] = "dcl",
+ [VSIR_OP_DCL_CONSTANT_BUFFER ] = "dcl_constantBuffer",
+ [VSIR_OP_DCL_FUNCTION_BODY ] = "dcl_function_body",
+ [VSIR_OP_DCL_FUNCTION_TABLE ] = "dcl_function_table",
+ [VSIR_OP_DCL_GLOBAL_FLAGS ] = "dcl_globalFlags",
+ [VSIR_OP_DCL_GS_INSTANCES ] = "dcl_gs_instances",
+ [VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT] = "dcl_hs_fork_phase_instance_count",
+ [VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT] = "dcl_hs_join_phase_instance_count",
+ [VSIR_OP_DCL_HS_MAX_TESSFACTOR ] = "dcl_hs_max_tessfactor",
+ [VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER ] = "dcl_immediateConstantBuffer",
+ [VSIR_OP_DCL_INDEX_RANGE ] = "dcl_index_range",
+ [VSIR_OP_DCL_INDEXABLE_TEMP ] = "dcl_indexableTemp",
+ [VSIR_OP_DCL_INPUT ] = "dcl_input",
+ [VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT ] = "dcl_input_control_point_count",
+ [VSIR_OP_DCL_INPUT_PRIMITIVE ] = "dcl_inputprimitive",
+ [VSIR_OP_DCL_INPUT_PS ] = "dcl_input_ps",
+ [VSIR_OP_DCL_INPUT_PS_SGV ] = "dcl_input_ps_sgv",
+ [VSIR_OP_DCL_INPUT_PS_SIV ] = "dcl_input_ps_siv",
+ [VSIR_OP_DCL_INPUT_SGV ] = "dcl_input_sgv",
+ [VSIR_OP_DCL_INPUT_SIV ] = "dcl_input_siv",
+ [VSIR_OP_DCL_INTERFACE ] = "dcl_interface",
+ [VSIR_OP_DCL_OUTPUT ] = "dcl_output",
+ [VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT ] = "dcl_output_control_point_count",
+ [VSIR_OP_DCL_OUTPUT_SGV ] = "dcl_output_sgv",
+ [VSIR_OP_DCL_OUTPUT_SIV ] = "dcl_output_siv",
+ [VSIR_OP_DCL_OUTPUT_TOPOLOGY ] = "dcl_outputtopology",
+ [VSIR_OP_DCL_RESOURCE_RAW ] = "dcl_resource_raw",
+ [VSIR_OP_DCL_RESOURCE_STRUCTURED ] = "dcl_resource_structured",
+ [VSIR_OP_DCL_SAMPLER ] = "dcl_sampler",
+ [VSIR_OP_DCL_STREAM ] = "dcl_stream",
+ [VSIR_OP_DCL_TEMPS ] = "dcl_temps",
+ [VSIR_OP_DCL_TESSELLATOR_DOMAIN ] = "dcl_tessellator_domain",
+ [VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = "dcl_tessellator_output_primitive",
+ [VSIR_OP_DCL_TESSELLATOR_PARTITIONING ] = "dcl_tessellator_partitioning",
+ [VSIR_OP_DCL_TGSM_RAW ] = "dcl_tgsm_raw",
+ [VSIR_OP_DCL_TGSM_STRUCTURED ] = "dcl_tgsm_structured",
+ [VSIR_OP_DCL_THREAD_GROUP ] = "dcl_thread_group",
+ [VSIR_OP_DCL_UAV_RAW ] = "dcl_uav_raw",
+ [VSIR_OP_DCL_UAV_STRUCTURED ] = "dcl_uav_structured",
+ [VSIR_OP_DCL_UAV_TYPED ] = "dcl_uav_typed",
+ [VSIR_OP_DCL_VERTICES_OUT ] = "dcl_maxout",
+ [VSIR_OP_DDIV ] = "ddiv",
+ [VSIR_OP_DEF ] = "def",
+ [VSIR_OP_DEFAULT ] = "default",
+ [VSIR_OP_DEFB ] = "defb",
+ [VSIR_OP_DEFI ] = "defi",
+ [VSIR_OP_DEQO ] = "deq",
+ [VSIR_OP_DFMA ] = "dfma",
+ [VSIR_OP_DGEO ] = "dge",
+ [VSIR_OP_DISCARD ] = "discard",
+ [VSIR_OP_DIV ] = "div",
+ [VSIR_OP_DLT ] = "dlt",
+ [VSIR_OP_DMAX ] = "dmax",
+ [VSIR_OP_DMIN ] = "dmin",
+ [VSIR_OP_DMOV ] = "dmov",
+ [VSIR_OP_DMOVC ] = "dmovc",
+ [VSIR_OP_DMUL ] = "dmul",
+ [VSIR_OP_DNE ] = "dne",
+ [VSIR_OP_DP2 ] = "dp2",
+ [VSIR_OP_DP2ADD ] = "dp2add",
+ [VSIR_OP_DP3 ] = "dp3",
+ [VSIR_OP_DP4 ] = "dp4",
+ [VSIR_OP_DRCP ] = "drcp",
+ [VSIR_OP_DST ] = "dst",
+ [VSIR_OP_DSX ] = "dsx",
+ [VSIR_OP_DSX_COARSE ] = "deriv_rtx_coarse",
+ [VSIR_OP_DSX_FINE ] = "deriv_rtx_fine",
+ [VSIR_OP_DSY ] = "dsy",
+ [VSIR_OP_DSY_COARSE ] = "deriv_rty_coarse",
+ [VSIR_OP_DSY_FINE ] = "deriv_rty_fine",
+ [VSIR_OP_DTOF ] = "dtof",
+ [VSIR_OP_DTOI ] = "dtoi",
+ [VSIR_OP_DTOU ] = "dtou",
+ [VSIR_OP_ELSE ] = "else",
+ [VSIR_OP_EMIT ] = "emit",
+ [VSIR_OP_EMIT_STREAM ] = "emit_stream",
+ [VSIR_OP_ENDIF ] = "endif",
+ [VSIR_OP_ENDLOOP ] = "endloop",
+ [VSIR_OP_ENDREP ] = "endrep",
+ [VSIR_OP_ENDSWITCH ] = "endswitch",
+ [VSIR_OP_EQO ] = "eq",
+ [VSIR_OP_EQU ] = "eq_unord",
+ [VSIR_OP_EVAL_CENTROID ] = "eval_centroid",
+ [VSIR_OP_EVAL_SAMPLE_INDEX ] = "eval_sample_index",
+ [VSIR_OP_EXP ] = "exp",
+ [VSIR_OP_EXPP ] = "expp",
+ [VSIR_OP_F16TOF32 ] = "f16tof32",
+ [VSIR_OP_F32TOF16 ] = "f32tof16",
+ [VSIR_OP_FCALL ] = "fcall",
+ [VSIR_OP_FIRSTBIT_HI ] = "firstbit_hi",
+ [VSIR_OP_FIRSTBIT_LO ] = "firstbit_lo",
+ [VSIR_OP_FIRSTBIT_SHI ] = "firstbit_shi",
+ [VSIR_OP_FRC ] = "frc",
+ [VSIR_OP_FREM ] = "frem",
+ [VSIR_OP_FTOD ] = "ftod",
+ [VSIR_OP_FTOI ] = "ftoi",
+ [VSIR_OP_FTOU ] = "ftou",
+ [VSIR_OP_GATHER4 ] = "gather4",
+ [VSIR_OP_GATHER4_C ] = "gather4_c",
+ [VSIR_OP_GATHER4_C_S ] = "gather4_c_s",
+ [VSIR_OP_GATHER4_PO ] = "gather4_po",
+ [VSIR_OP_GATHER4_PO_C ] = "gather4_po_c",
+ [VSIR_OP_GATHER4_PO_C_S ] = "gather4_po_c_s",
+ [VSIR_OP_GATHER4_PO_S ] = "gather4_po_s",
+ [VSIR_OP_GATHER4_S ] = "gather4_s",
+ [VSIR_OP_GEO ] = "ge",
+ [VSIR_OP_GEU ] = "ge_unord",
+ [VSIR_OP_HCOS ] = "hcos",
+ [VSIR_OP_HS_CONTROL_POINT_PHASE ] = "hs_control_point_phase",
+ [VSIR_OP_HS_DECLS ] = "hs_decls",
+ [VSIR_OP_HS_FORK_PHASE ] = "hs_fork_phase",
+ [VSIR_OP_HS_JOIN_PHASE ] = "hs_join_phase",
+ [VSIR_OP_HSIN ] = "hsin",
+ [VSIR_OP_HTAN ] = "htan",
+ [VSIR_OP_IADD ] = "iadd",
+ [VSIR_OP_IBFE ] = "ibfe",
+ [VSIR_OP_IDIV ] = "idiv",
+ [VSIR_OP_IEQ ] = "ieq",
+ [VSIR_OP_IF ] = "if",
+ [VSIR_OP_IFC ] = "if",
+ [VSIR_OP_IGE ] = "ige",
+ [VSIR_OP_ILT ] = "ilt",
+ [VSIR_OP_IMAD ] = "imad",
+ [VSIR_OP_IMAX ] = "imax",
+ [VSIR_OP_IMIN ] = "imin",
+ [VSIR_OP_IMM_ATOMIC_ALLOC ] = "imm_atomic_alloc",
+ [VSIR_OP_IMM_ATOMIC_AND ] = "imm_atomic_and",
+ [VSIR_OP_IMM_ATOMIC_CMP_EXCH ] = "imm_atomic_cmp_exch",
+ [VSIR_OP_IMM_ATOMIC_CONSUME ] = "imm_atomic_consume",
+ [VSIR_OP_IMM_ATOMIC_EXCH ] = "imm_atomic_exch",
+ [VSIR_OP_IMM_ATOMIC_IADD ] = "imm_atomic_iadd",
+ [VSIR_OP_IMM_ATOMIC_IMAX ] = "imm_atomic_imax",
+ [VSIR_OP_IMM_ATOMIC_IMIN ] = "imm_atomic_imin",
+ [VSIR_OP_IMM_ATOMIC_OR ] = "imm_atomic_or",
+ [VSIR_OP_IMM_ATOMIC_UMAX ] = "imm_atomic_umax",
+ [VSIR_OP_IMM_ATOMIC_UMIN ] = "imm_atomic_umin",
+ [VSIR_OP_IMM_ATOMIC_XOR ] = "imm_atomic_xor",
+ [VSIR_OP_IMUL ] = "imul",
+ [VSIR_OP_IMUL_LOW ] = "imul_low",
+ [VSIR_OP_INE ] = "ine",
+ [VSIR_OP_INEG ] = "ineg",
+ [VSIR_OP_IREM ] = "irem",
+ [VSIR_OP_ISFINITE ] = "isfinite",
+ [VSIR_OP_ISHL ] = "ishl",
+ [VSIR_OP_ISHR ] = "ishr",
+ [VSIR_OP_ISINF ] = "isinf",
+ [VSIR_OP_ISNAN ] = "isnan",
+ [VSIR_OP_ITOD ] = "itod",
+ [VSIR_OP_ITOF ] = "itof",
+ [VSIR_OP_ITOI ] = "itoi",
+ [VSIR_OP_LABEL ] = "label",
+ [VSIR_OP_LD ] = "ld",
+ [VSIR_OP_LD2DMS ] = "ld2dms",
+ [VSIR_OP_LD2DMS_S ] = "ld2dms_s",
+ [VSIR_OP_LD_RAW ] = "ld_raw",
+ [VSIR_OP_LD_RAW_S ] = "ld_raw_s",
+ [VSIR_OP_LD_S ] = "ld_s",
+ [VSIR_OP_LD_STRUCTURED ] = "ld_structured",
+ [VSIR_OP_LD_STRUCTURED_S ] = "ld_structured_s",
+ [VSIR_OP_LD_UAV_TYPED ] = "ld_uav_typed",
+ [VSIR_OP_LD_UAV_TYPED_S ] = "ld_uav_typed_s",
+ [VSIR_OP_LIT ] = "lit",
+ [VSIR_OP_LOD ] = "lod",
+ [VSIR_OP_LOG ] = "log",
+ [VSIR_OP_LOGP ] = "logp",
+ [VSIR_OP_LOOP ] = "loop",
+ [VSIR_OP_LRP ] = "lrp",
+ [VSIR_OP_LTO ] = "lt",
+ [VSIR_OP_LTU ] = "lt_unord",
+ [VSIR_OP_M3x2 ] = "m3x2",
+ [VSIR_OP_M3x3 ] = "m3x3",
+ [VSIR_OP_M3x4 ] = "m3x4",
+ [VSIR_OP_M4x3 ] = "m4x3",
+ [VSIR_OP_M4x4 ] = "m4x4",
+ [VSIR_OP_MAD ] = "mad",
+ [VSIR_OP_MAX ] = "max",
+ [VSIR_OP_MIN ] = "min",
+ [VSIR_OP_MOV ] = "mov",
+ [VSIR_OP_MOVA ] = "mova",
+ [VSIR_OP_MOVC ] = "movc",
+ [VSIR_OP_MSAD ] = "msad",
+ [VSIR_OP_MUL ] = "mul",
+ [VSIR_OP_NEO ] = "ne_ord",
+ [VSIR_OP_NEU ] = "ne",
+ [VSIR_OP_NOP ] = "nop",
+ [VSIR_OP_NOT ] = "not",
+ [VSIR_OP_NRM ] = "nrm",
+ [VSIR_OP_OR ] = "or",
+ [VSIR_OP_ORD ] = "ord",
+ [VSIR_OP_PHASE ] = "phase",
+ [VSIR_OP_PHI ] = "phi",
+ [VSIR_OP_POW ] = "pow",
+ [VSIR_OP_QUAD_READ_ACROSS_D ] = "quad_read_across_d",
+ [VSIR_OP_QUAD_READ_ACROSS_X ] = "quad_read_across_x",
+ [VSIR_OP_QUAD_READ_ACROSS_Y ] = "quad_read_across_y",
+ [VSIR_OP_QUAD_READ_LANE_AT ] = "quad_read_lane_at",
+ [VSIR_OP_RCP ] = "rcp",
+ [VSIR_OP_REP ] = "rep",
+ [VSIR_OP_RESINFO ] = "resinfo",
+ [VSIR_OP_RET ] = "ret",
+ [VSIR_OP_RETP ] = "retp",
+ [VSIR_OP_ROUND_NE ] = "round_ne",
+ [VSIR_OP_ROUND_NI ] = "round_ni",
+ [VSIR_OP_ROUND_PI ] = "round_pi",
+ [VSIR_OP_ROUND_Z ] = "round_z",
+ [VSIR_OP_RSQ ] = "rsq",
+ [VSIR_OP_SAMPLE ] = "sample",
+ [VSIR_OP_SAMPLE_B ] = "sample_b",
+ [VSIR_OP_SAMPLE_B_CL_S ] = "sample_b_cl_s",
+ [VSIR_OP_SAMPLE_C ] = "sample_c",
+ [VSIR_OP_SAMPLE_C_CL_S ] = "sample_c_cl_s",
+ [VSIR_OP_SAMPLE_C_LZ ] = "sample_c_lz",
+ [VSIR_OP_SAMPLE_C_LZ_S ] = "sample_c_lz_s",
+ [VSIR_OP_SAMPLE_CL_S ] = "sample_cl_s",
+ [VSIR_OP_SAMPLE_GRAD ] = "sample_d",
+ [VSIR_OP_SAMPLE_GRAD_CL_S ] = "sample_d_cl_s",
+ [VSIR_OP_SAMPLE_INFO ] = "sample_info",
+ [VSIR_OP_SAMPLE_LOD ] = "sample_l",
+ [VSIR_OP_SAMPLE_LOD_S ] = "sample_l_s",
+ [VSIR_OP_SAMPLE_POS ] = "sample_pos",
+ [VSIR_OP_SETP ] = "setp",
+ [VSIR_OP_SGE ] = "sge",
+ [VSIR_OP_SGN ] = "sgn",
+ [VSIR_OP_SIN ] = "sin",
+ [VSIR_OP_SINCOS ] = "sincos",
+ [VSIR_OP_SLT ] = "slt",
+ [VSIR_OP_SQRT ] = "sqrt",
+ [VSIR_OP_STORE_RAW ] = "store_raw",
+ [VSIR_OP_STORE_STRUCTURED ] = "store_structured",
+ [VSIR_OP_STORE_UAV_TYPED ] = "store_uav_typed",
+ [VSIR_OP_SUB ] = "sub",
+ [VSIR_OP_SWAPC ] = "swapc",
+ [VSIR_OP_SWITCH ] = "switch",
+ [VSIR_OP_SWITCH_MONOLITHIC ] = "switch",
+ [VSIR_OP_SYNC ] = "sync",
+ [VSIR_OP_TAN ] = "tan",
+ [VSIR_OP_TEX ] = "tex",
+ [VSIR_OP_TEXBEM ] = "texbem",
+ [VSIR_OP_TEXBEML ] = "texbeml",
+ [VSIR_OP_TEXCOORD ] = "texcoord",
+ [VSIR_OP_TEXCRD ] = "texcrd",
+ [VSIR_OP_TEXDEPTH ] = "texdepth",
+ [VSIR_OP_TEXDP3 ] = "texdp3",
+ [VSIR_OP_TEXDP3TEX ] = "texdp3tex",
+ [VSIR_OP_TEXKILL ] = "texkill",
+ [VSIR_OP_TEXLD ] = "texld",
+ [VSIR_OP_TEXLDD ] = "texldd",
+ [VSIR_OP_TEXLDL ] = "texldl",
+ [VSIR_OP_TEXM3x2DEPTH ] = "texm3x2depth",
+ [VSIR_OP_TEXM3x2PAD ] = "texm3x2pad",
+ [VSIR_OP_TEXM3x2TEX ] = "texm3x2tex",
+ [VSIR_OP_TEXM3x3 ] = "texm3x3",
+ [VSIR_OP_TEXM3x3DIFF ] = "texm3x3diff",
+ [VSIR_OP_TEXM3x3PAD ] = "texm3x3pad",
+ [VSIR_OP_TEXM3x3SPEC ] = "texm3x3spec",
+ [VSIR_OP_TEXM3x3TEX ] = "texm3x3tex",
+ [VSIR_OP_TEXM3x3VSPEC ] = "texm3x3vspec",
+ [VSIR_OP_TEXREG2AR ] = "texreg2ar",
+ [VSIR_OP_TEXREG2GB ] = "texreg2gb",
+ [VSIR_OP_TEXREG2RGB ] = "texreg2rgb",
+ [VSIR_OP_UBFE ] = "ubfe",
+ [VSIR_OP_UDIV ] = "udiv",
+ [VSIR_OP_UDIV_SIMPLE ] = "udiv_simple",
+ [VSIR_OP_UGE ] = "uge",
+ [VSIR_OP_ULT ] = "ult",
+ [VSIR_OP_UMAX ] = "umax",
+ [VSIR_OP_UMIN ] = "umin",
+ [VSIR_OP_UMUL ] = "umul",
+ [VSIR_OP_UNO ] = "uno",
+ [VSIR_OP_UREM ] = "urem",
+ [VSIR_OP_USHR ] = "ushr",
+ [VSIR_OP_UTOD ] = "utod",
+ [VSIR_OP_UTOF ] = "utof",
+ [VSIR_OP_UTOU ] = "utou",
+ [VSIR_OP_WAVE_ACTIVE_ALL_EQUAL ] = "wave_active_all_equal",
+ [VSIR_OP_WAVE_ACTIVE_BALLOT ] = "wave_active_ballot",
+ [VSIR_OP_WAVE_ACTIVE_BIT_AND ] = "wave_active_bit_and",
+ [VSIR_OP_WAVE_ACTIVE_BIT_OR ] = "wave_active_bit_or",
+ [VSIR_OP_WAVE_ACTIVE_BIT_XOR ] = "wave_active_bit_xor",
+ [VSIR_OP_WAVE_ALL_BIT_COUNT ] = "wave_all_bit_count",
+ [VSIR_OP_WAVE_ALL_TRUE ] = "wave_all_true",
+ [VSIR_OP_WAVE_ANY_TRUE ] = "wave_any_true",
+ [VSIR_OP_WAVE_IS_FIRST_LANE ] = "wave_is_first_lane",
+ [VSIR_OP_WAVE_OP_ADD ] = "wave_op_add",
+ [VSIR_OP_WAVE_OP_IMAX ] = "wave_op_imax",
+ [VSIR_OP_WAVE_OP_IMIN ] = "wave_op_imin",
+ [VSIR_OP_WAVE_OP_MAX ] = "wave_op_max",
+ [VSIR_OP_WAVE_OP_MIN ] = "wave_op_min",
+ [VSIR_OP_WAVE_OP_MUL ] = "wave_op_mul",
+ [VSIR_OP_WAVE_OP_UMAX ] = "wave_op_umax",
+ [VSIR_OP_WAVE_OP_UMIN ] = "wave_op_umin",
+ [VSIR_OP_WAVE_PREFIX_BIT_COUNT ] = "wave_prefix_bit_count",
+ [VSIR_OP_WAVE_READ_LANE_AT ] = "wave_read_lane_at",
+ [VSIR_OP_WAVE_READ_LANE_FIRST ] = "wave_read_lane_first",
+ [VSIR_OP_XOR ] = "xor",
+ };
+
+ if ((uint32_t)op < ARRAY_SIZE(names))
+ return names[op] ? names[op] : error;
+
+ return error;
+}
+
static int convert_parameter_info(const struct vkd3d_shader_compile_info *compile_info,
unsigned int *ret_count, const struct vkd3d_shader_parameter1 **ret_parameters)
{
@@ -100,7 +444,16 @@ bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_c
program->shader_version = *version;
program->cf_type = cf_type;
program->normalisation_level = normalisation_level;
- return shader_instruction_array_init(&program->instructions, reserve);
+ if (!shader_instruction_array_init(&program->instructions, reserve))
+ {
+ if (program->free_parameters)
+ vkd3d_free((void *)program->parameters);
+ return false;
+ }
+
+ vkd3d_shader_source_list_init(&program->source_files);
+
+ return true;
}
void vsir_program_cleanup(struct vsir_program *program)
@@ -112,6 +465,7 @@ void vsir_program_cleanup(struct vsir_program *program)
for (i = 0; i < program->block_name_count; ++i)
vkd3d_free((void *)program->block_names[i]);
vkd3d_free(program->block_names);
+ vkd3d_shader_source_list_cleanup(&program->source_files);
shader_instruction_array_destroy(&program->instructions);
shader_signature_cleanup(&program->input_signature);
shader_signature_cleanup(&program->output_signature);
@@ -163,8 +517,55 @@ bool vsir_signature_find_sysval(const struct shader_signature *signature,
return false;
}
+const char *debug_vsir_writemask(unsigned int writemask)
+{
+ static const char components[] = {'x', 'y', 'z', 'w'};
+ char string[5];
+ unsigned int i = 0, pos = 0;
+
+ VKD3D_ASSERT(!(writemask & ~VKD3DSP_WRITEMASK_ALL));
+
+ while (writemask)
+ {
+ if (writemask & 1)
+ string[pos++] = components[i];
+ writemask >>= 1;
+ i++;
+ }
+ string[pos] = '\0';
+ return vkd3d_dbg_sprintf(".%s", string);
+}
+
+static unsigned int vsir_combine_write_masks(unsigned int first, unsigned int second)
+{
+ unsigned int ret = 0, j = 0;
+
+ for (unsigned int i = 0; i < VKD3D_VEC4_SIZE; ++i)
+ {
+ if (first & (1u << i))
+ {
+ if (second & (1u << j++))
+ ret |= (1u << i);
+ }
+ }
+
+ return ret;
+}
+
+static uint32_t vsir_combine_swizzles(uint32_t first, uint32_t second)
+{
+ uint32_t ret = 0;
+
+ for (unsigned int i = 0; i < VKD3D_VEC4_SIZE; ++i)
+ {
+ unsigned int s = vsir_swizzle_get_component(second, i);
+ vsir_swizzle_set_component(&ret, i, vsir_swizzle_get_component(first, s));
+ }
+ return ret;
+}
+
void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type,
- enum vkd3d_data_type data_type, unsigned int idx_count)
+ enum vsir_data_type data_type, unsigned int idx_count)
{
reg->type = reg_type;
reg->precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT;
@@ -190,7 +591,7 @@ static inline bool shader_register_is_phase_instance_id(const struct vkd3d_shade
}
void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type,
- enum vkd3d_data_type data_type, unsigned int idx_count)
+ enum vsir_data_type data_type, unsigned int idx_count)
{
vsir_register_init(&param->reg, reg_type, data_type, idx_count);
param->swizzle = 0;
@@ -199,32 +600,32 @@ void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader
static void src_param_init_const_uint(struct vkd3d_shader_src_param *src, uint32_t value)
{
- vsir_src_param_init(src, VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0);
+ vsir_src_param_init(src, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0);
src->reg.u.immconst_u32[0] = value;
}
static void vsir_src_param_init_io(struct vkd3d_shader_src_param *src,
enum vkd3d_shader_register_type reg_type, const struct signature_element *e, unsigned int idx_count)
{
- vsir_src_param_init(src, reg_type, vkd3d_data_type_from_component_type(e->component_type), idx_count);
+ vsir_src_param_init(src, reg_type, vsir_data_type_from_component_type(e->component_type), idx_count);
src->reg.dimension = VSIR_DIMENSION_VEC4;
src->swizzle = vsir_swizzle_from_writemask(e->mask);
}
void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id)
{
- vsir_src_param_init(param, VKD3DSPR_LABEL, VKD3D_DATA_UNUSED, 1);
+ vsir_src_param_init(param, VKD3DSPR_LABEL, VSIR_DATA_UNUSED, 1);
param->reg.dimension = VSIR_DIMENSION_NONE;
param->reg.idx[0].offset = label_id;
}
-static void src_param_init_parameter(struct vkd3d_shader_src_param *src, uint32_t idx, enum vkd3d_data_type type)
+static void src_param_init_parameter(struct vkd3d_shader_src_param *src, uint32_t idx, enum vsir_data_type type)
{
vsir_src_param_init(src, VKD3DSPR_PARAMETER, type, 1);
src->reg.idx[0].offset = idx;
}
-static void src_param_init_parameter_vec4(struct vkd3d_shader_src_param *src, uint32_t idx, enum vkd3d_data_type type)
+static void src_param_init_parameter_vec4(struct vkd3d_shader_src_param *src, uint32_t idx, enum vsir_data_type type)
{
vsir_src_param_init(src, VKD3DSPR_PARAMETER, type, 1);
src->reg.idx[0].offset = idx;
@@ -234,7 +635,7 @@ static void src_param_init_parameter_vec4(struct vkd3d_shader_src_param *src, ui
static void vsir_src_param_init_resource(struct vkd3d_shader_src_param *src, unsigned int id, unsigned int idx)
{
- vsir_src_param_init(src, VKD3DSPR_RESOURCE, VKD3D_DATA_UNUSED, 2);
+ vsir_src_param_init(src, VKD3DSPR_RESOURCE, VSIR_DATA_UNUSED, 2);
src->reg.idx[0].offset = id;
src->reg.idx[1].offset = idx;
src->reg.dimension = VSIR_DIMENSION_VEC4;
@@ -243,47 +644,61 @@ static void vsir_src_param_init_resource(struct vkd3d_shader_src_param *src, uns
static void vsir_src_param_init_sampler(struct vkd3d_shader_src_param *src, unsigned int id, unsigned int idx)
{
- vsir_src_param_init(src, VKD3DSPR_SAMPLER, VKD3D_DATA_UNUSED, 2);
+ vsir_src_param_init(src, VKD3DSPR_SAMPLER, VSIR_DATA_UNUSED, 2);
src->reg.idx[0].offset = id;
src->reg.idx[1].offset = idx;
src->reg.dimension = VSIR_DIMENSION_NONE;
}
-static void src_param_init_ssa_bool(struct vkd3d_shader_src_param *src, unsigned int idx)
+static void src_param_init_ssa(struct vkd3d_shader_src_param *src, unsigned int idx,
+ enum vsir_data_type data_type, enum vsir_dimension dimension)
{
- vsir_src_param_init(src, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1);
+ vsir_src_param_init(src, VKD3DSPR_SSA, data_type, 1);
src->reg.idx[0].offset = idx;
+
+ if (dimension == VSIR_DIMENSION_VEC4)
+ {
+ src->reg.dimension = VSIR_DIMENSION_VEC4;
+ src->swizzle = VKD3D_SHADER_NO_SWIZZLE;
+ }
+}
+
+static void src_param_init_ssa_scalar(struct vkd3d_shader_src_param *src,
+ unsigned int idx, enum vsir_data_type data_type)
+{
+ src_param_init_ssa(src, idx, data_type, VSIR_DIMENSION_SCALAR);
+}
+
+static void src_param_init_ssa_bool(struct vkd3d_shader_src_param *src, unsigned int idx)
+{
+ src_param_init_ssa_scalar(src, idx, VSIR_DATA_BOOL);
}
static void src_param_init_ssa_float(struct vkd3d_shader_src_param *src, unsigned int idx)
{
- vsir_src_param_init(src, VKD3DSPR_SSA, VKD3D_DATA_FLOAT, 1);
- src->reg.idx[0].offset = idx;
+ src_param_init_ssa_scalar(src, idx, VSIR_DATA_F32);
}
static void src_param_init_ssa_float4(struct vkd3d_shader_src_param *src, unsigned int idx)
{
- vsir_src_param_init(src, VKD3DSPR_SSA, VKD3D_DATA_FLOAT, 1);
- src->reg.idx[0].offset = idx;
- src->reg.dimension = VSIR_DIMENSION_VEC4;
- src->swizzle = VKD3D_SHADER_NO_SWIZZLE;
+ src_param_init_ssa(src, idx, VSIR_DATA_F32, VSIR_DIMENSION_VEC4);
}
static void src_param_init_temp_bool(struct vkd3d_shader_src_param *src, unsigned int idx)
{
- vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1);
+ vsir_src_param_init(src, VKD3DSPR_TEMP, VSIR_DATA_BOOL, 1);
src->reg.idx[0].offset = idx;
}
static void src_param_init_temp_float(struct vkd3d_shader_src_param *src, unsigned int idx)
{
- vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ vsir_src_param_init(src, VKD3DSPR_TEMP, VSIR_DATA_F32, 1);
src->reg.idx[0].offset = idx;
}
static void src_param_init_temp_float4(struct vkd3d_shader_src_param *src, unsigned int idx)
{
- vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ vsir_src_param_init(src, VKD3DSPR_TEMP, VSIR_DATA_F32, 1);
src->reg.dimension = VSIR_DIMENSION_VEC4;
src->swizzle = VKD3D_SHADER_NO_SWIZZLE;
src->reg.idx[0].offset = idx;
@@ -291,12 +706,12 @@ static void src_param_init_temp_float4(struct vkd3d_shader_src_param *src, unsig
static void src_param_init_temp_uint(struct vkd3d_shader_src_param *src, unsigned int idx)
{
- vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
+ vsir_src_param_init(src, VKD3DSPR_TEMP, VSIR_DATA_U32, 1);
src->reg.idx[0].offset = idx;
}
void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type,
- enum vkd3d_data_type data_type, unsigned int idx_count)
+ enum vsir_data_type data_type, unsigned int idx_count)
{
vsir_register_init(&param->reg, reg_type, data_type, idx_count);
param->write_mask = VKD3DSP_WRITEMASK_0;
@@ -307,59 +722,73 @@ void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader
static void vsir_dst_param_init_io(struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_register_type reg_type,
const struct signature_element *e, unsigned int idx_count)
{
- vsir_dst_param_init(dst, reg_type, vkd3d_data_type_from_component_type(e->component_type), idx_count);
+ vsir_dst_param_init(dst, reg_type, vsir_data_type_from_component_type(e->component_type), idx_count);
dst->reg.dimension = VSIR_DIMENSION_VEC4;
dst->write_mask = e->mask;
}
void vsir_dst_param_init_null(struct vkd3d_shader_dst_param *dst)
{
- vsir_dst_param_init(dst, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0);
+ vsir_dst_param_init(dst, VKD3DSPR_NULL, VSIR_DATA_UNUSED, 0);
dst->reg.dimension = VSIR_DIMENSION_NONE;
dst->write_mask = 0;
}
-static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
+static void dst_param_init_ssa(struct vkd3d_shader_dst_param *dst, unsigned int idx,
+ enum vsir_data_type data_type, enum vsir_dimension dimension)
{
- vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1);
+ vsir_dst_param_init(dst, VKD3DSPR_SSA, data_type, 1);
dst->reg.idx[0].offset = idx;
+
+ if (dimension == VSIR_DIMENSION_VEC4)
+ {
+ dst->reg.dimension = VSIR_DIMENSION_VEC4;
+ dst->write_mask = VKD3DSP_WRITEMASK_ALL;
+ }
+}
+
+static void dst_param_init_ssa_scalar(struct vkd3d_shader_dst_param *dst,
+ unsigned int idx, enum vsir_data_type data_type)
+{
+ dst_param_init_ssa(dst, idx, data_type, VSIR_DIMENSION_SCALAR);
+}
+
+static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
+{
+ dst_param_init_ssa_scalar(dst, idx, VSIR_DATA_BOOL);
}
static void dst_param_init_ssa_float(struct vkd3d_shader_dst_param *dst, unsigned int idx)
{
- vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_FLOAT, 1);
- dst->reg.idx[0].offset = idx;
+ dst_param_init_ssa_scalar(dst, idx, VSIR_DATA_F32);
}
static void dst_param_init_ssa_float4(struct vkd3d_shader_dst_param *dst, unsigned int idx)
{
- vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_FLOAT, 1);
- dst->reg.idx[0].offset = idx;
- dst->reg.dimension = VSIR_DIMENSION_VEC4;
- dst->write_mask = VKD3DSP_WRITEMASK_ALL;
+ dst_param_init_ssa(dst, idx, VSIR_DATA_F32, VSIR_DIMENSION_VEC4);
}
static void dst_param_init_temp_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
{
- vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1);
+ vsir_dst_param_init(dst, VKD3DSPR_TEMP, VSIR_DATA_BOOL, 1);
dst->reg.idx[0].offset = idx;
}
static void dst_param_init_temp_float4(struct vkd3d_shader_dst_param *dst, unsigned int idx)
{
- vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ vsir_dst_param_init(dst, VKD3DSPR_TEMP, VSIR_DATA_F32, 1);
dst->reg.idx[0].offset = idx;
dst->reg.dimension = VSIR_DIMENSION_VEC4;
}
static void dst_param_init_temp_uint(struct vkd3d_shader_dst_param *dst, unsigned int idx)
{
- vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
+ vsir_dst_param_init(dst, VKD3DSPR_TEMP, VSIR_DATA_U32, 1);
dst->reg.idx[0].offset = idx;
}
static void dst_param_init_output(struct vkd3d_shader_dst_param *dst,
- enum vkd3d_data_type data_type, uint32_t idx, uint32_t write_mask)
+ enum vsir_data_type data_type, uint32_t idx, uint32_t write_mask)
{
vsir_dst_param_init(dst, VKD3DSPR_OUTPUT, data_type, 1);
dst->reg.idx[0].offset = idx;
@@ -373,6 +802,10 @@ void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vk
memset(ins, 0, sizeof(*ins));
ins->location = *location;
ins->opcode = opcode;
+ ins->resource_data_type[0] = VSIR_DATA_F32;
+ ins->resource_data_type[1] = VSIR_DATA_F32;
+ ins->resource_data_type[2] = VSIR_DATA_F32;
+ ins->resource_data_type[3] = VSIR_DATA_F32;
}
bool vsir_instruction_init_with_params(struct vsir_program *program,
@@ -410,7 +843,7 @@ static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins,
vsir_src_param_init_label(src_param, label_id);
- vsir_instruction_init(ins, location, VKD3DSIH_LABEL);
+ vsir_instruction_init(ins, location, VSIR_OP_LABEL);
ins->src = src_param;
ins->src_count = 1;
@@ -420,28 +853,28 @@ static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins,
static bool vsir_instruction_is_dcl(const struct vkd3d_shader_instruction *instruction)
{
enum vkd3d_shader_opcode opcode = instruction->opcode;
- return (VKD3DSIH_DCL <= opcode && opcode <= VKD3DSIH_DCL_VERTICES_OUT)
- || opcode == VKD3DSIH_HS_DECLS;
+ return (VSIR_OP_DCL <= opcode && opcode <= VSIR_OP_DCL_VERTICES_OUT)
+ || opcode == VSIR_OP_HS_DECLS;
}
static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *ins)
{
struct vkd3d_shader_location location = ins->location;
- vsir_instruction_init(ins, &location, VKD3DSIH_NOP);
+ vsir_instruction_init(ins, &location, VSIR_OP_NOP);
}
-static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_data_type data_type,
- enum vkd3d_shader_opcode *opcode, bool *requires_swap)
+static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op,
+ enum vsir_data_type data_type, enum vkd3d_shader_opcode *opcode, bool *requires_swap)
{
switch (rel_op)
{
case VKD3D_SHADER_REL_OP_LT:
case VKD3D_SHADER_REL_OP_GT:
*requires_swap = (rel_op == VKD3D_SHADER_REL_OP_GT);
- if (data_type == VKD3D_DATA_FLOAT)
+ if (data_type == VSIR_DATA_F32)
{
- *opcode = VKD3DSIH_LTO;
+ *opcode = VSIR_OP_LTO;
return true;
}
break;
@@ -449,27 +882,27 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_d
case VKD3D_SHADER_REL_OP_GE:
case VKD3D_SHADER_REL_OP_LE:
*requires_swap = (rel_op == VKD3D_SHADER_REL_OP_LE);
- if (data_type == VKD3D_DATA_FLOAT)
+ if (data_type == VSIR_DATA_F32)
{
- *opcode = VKD3DSIH_GEO;
+ *opcode = VSIR_OP_GEO;
return true;
}
break;
case VKD3D_SHADER_REL_OP_EQ:
*requires_swap = false;
- if (data_type == VKD3D_DATA_FLOAT)
+ if (data_type == VSIR_DATA_F32)
{
- *opcode = VKD3DSIH_EQO;
+ *opcode = VSIR_OP_EQO;
return true;
}
break;
case VKD3D_SHADER_REL_OP_NE:
*requires_swap = false;
- if (data_type == VKD3D_DATA_FLOAT)
+ if (data_type == VSIR_DATA_F32)
{
- *opcode = VKD3DSIH_NEO;
+ *opcode = VSIR_OP_NEO;
return true;
}
break;
@@ -480,48 +913,47 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_d
static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *program,
struct vsir_transformation_context *ctx)
{
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
struct vkd3d_shader_instruction *ins, *ins2;
unsigned int tmp_idx = ~0u;
- unsigned int i, k, r;
+ unsigned int k, r;
- for (i = 0; i < program->instructions.count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- ins = &program->instructions.elements[i];
-
- if (ins->opcode == VKD3DSIH_MOV && ins->dst[0].reg.type == VKD3DSPR_ADDR)
+ if (ins->opcode == VSIR_OP_MOV && ins->dst[0].reg.type == VKD3DSPR_ADDR)
{
if (tmp_idx == ~0u)
tmp_idx = program->temp_count++;
- ins->opcode = VKD3DSIH_FTOU;
- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
+ ins->opcode = VSIR_OP_FTOU;
+ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1);
ins->dst[0].reg.idx[0].offset = tmp_idx;
ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
}
- else if (ins->opcode == VKD3DSIH_MOVA)
+ else if (ins->opcode == VSIR_OP_MOVA)
{
if (tmp_idx == ~0u)
tmp_idx = program->temp_count++;
- if (!shader_instruction_array_insert_at(&program->instructions, i + 1, 1))
+ if (!vsir_program_iterator_insert_after(&it, 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
- ins = &program->instructions.elements[i];
- ins2 = &program->instructions.elements[i + 1];
+ ins = vsir_program_iterator_current(&it);
- ins->opcode = VKD3DSIH_ROUND_NE;
- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ ins->opcode = VSIR_OP_ROUND_NE;
+ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_F32, 1);
ins->dst[0].reg.idx[0].offset = tmp_idx;
ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
- if (!vsir_instruction_init_with_params(program, ins2, &ins->location, VKD3DSIH_FTOU, 1, 1))
+ ins2 = vsir_program_iterator_next(&it);
+ if (!vsir_instruction_init_with_params(program, ins2, &ins->location, VSIR_OP_FTOU, 1, 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_register_init(&ins2->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
+ vsir_register_init(&ins2->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1);
ins2->dst[0].reg.idx[0].offset = tmp_idx;
ins2->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
ins2->dst[0].write_mask = ins->dst[0].write_mask;
- vsir_register_init(&ins2->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ vsir_register_init(&ins2->src[0].reg, VKD3DSPR_TEMP, VSIR_DATA_F32, 1);
ins2->src[0].reg.idx[0].offset = tmp_idx;
ins2->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
ins2->src[0].swizzle = vsir_swizzle_from_writemask(ins2->dst[0].write_mask);
@@ -540,7 +972,7 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra
if (tmp_idx == ~0u)
tmp_idx = program->temp_count++;
- vsir_register_init(&rel->reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
+ vsir_register_init(&rel->reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1);
rel->reg.idx[0].offset = tmp_idx;
rel->reg.dimension = VSIR_DIMENSION_VEC4;
}
@@ -552,18 +984,16 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra
}
static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program,
- struct vkd3d_shader_instruction *ifc, unsigned int *tmp_idx,
+ struct vsir_program_iterator *it, unsigned int *tmp_idx,
struct vkd3d_shader_message_context *message_context)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
- size_t pos = ifc - instructions->elements;
- struct vkd3d_shader_instruction *ins;
+ struct vkd3d_shader_instruction *ifc, *ins;
enum vkd3d_shader_opcode opcode;
bool swap;
- if (!shader_instruction_array_insert_at(instructions, pos + 1, 2))
+ if (!vsir_program_iterator_insert_after(it, 2))
return VKD3D_ERROR_OUT_OF_MEMORY;
- ifc = &instructions->elements[pos];
+ ifc = vsir_program_iterator_current(it);
if (*tmp_idx == ~0u)
*tmp_idx = program->temp_count++;
@@ -577,11 +1007,11 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program,
return VKD3D_ERROR_NOT_IMPLEMENTED;
}
- ins = &instructions->elements[pos + 1];
+ ins = vsir_program_iterator_next(it);
if (!vsir_instruction_init_with_params(program, ins, &ifc->location, opcode, 1, 2))
return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
+ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1);
ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
ins->dst[0].reg.idx[0].offset = *tmp_idx;
ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0;
@@ -590,12 +1020,12 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program,
ins->src[1] = ifc->src[!swap];
/* Create new if instruction using the previous result. */
- ins = &instructions->elements[pos + 2];
- if (!vsir_instruction_init_with_params(program, ins, &ifc->location, VKD3DSIH_IF, 0, 1))
+ ins = vsir_program_iterator_next(it);
+ if (!vsir_instruction_init_with_params(program, ins, &ifc->location, VSIR_OP_IF, 0, 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ;
- vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
+ vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1);
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
ins->src[0].reg.idx[0].offset = *tmp_idx;
ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
@@ -607,35 +1037,33 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program,
}
static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program,
- struct vkd3d_shader_instruction *texkill, unsigned int *tmp_idx)
+ struct vsir_program_iterator *it, unsigned int *tmp_idx)
{
const unsigned int components_read = 3 + (program->shader_version.major >= 2);
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
- size_t pos = texkill - instructions->elements;
- struct vkd3d_shader_instruction *ins;
+ struct vkd3d_shader_instruction *ins, *texkill;
unsigned int j;
- if (!shader_instruction_array_insert_at(instructions, pos + 1, components_read + 1))
+ if (!vsir_program_iterator_insert_after(it, components_read + 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
- texkill = &instructions->elements[pos];
+ texkill = vsir_program_iterator_current(it);
if (*tmp_idx == ~0u)
*tmp_idx = program->temp_count++;
/* tmp = ins->src[0] < 0 */
- ins = &instructions->elements[pos + 1];
- if (!vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_LTO, 1, 2))
+ ins = vsir_program_iterator_next(it);
+ if (!vsir_instruction_init_with_params(program, ins, &texkill->location, VSIR_OP_LTO, 1, 2))
return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
+ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1);
ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
ins->dst[0].reg.idx[0].offset = *tmp_idx;
ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL;
ins->src[0].reg = texkill->src[0].reg;
ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
- vsir_register_init(&ins->src[1].reg, VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0);
+ vsir_register_init(&ins->src[1].reg, VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0);
ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
ins->src[1].reg.u.immconst_f32[0] = 0.0f;
ins->src[1].reg.u.immconst_f32[1] = 0.0f;
@@ -648,20 +1076,20 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program
for (j = 1; j < components_read; ++j)
{
- ins = &instructions->elements[pos + 1 + j];
- if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_OR, 1, 2)))
+ ins = vsir_program_iterator_next(it);
+ if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VSIR_OP_OR, 1, 2)))
return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
+ vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1);
ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
ins->dst[0].reg.idx[0].offset = *tmp_idx;
ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0;
- vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
+ vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1);
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
ins->src[0].reg.idx[0].offset = *tmp_idx;
ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
- vsir_register_init(&ins->src[1].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
+ vsir_register_init(&ins->src[1].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1);
ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
ins->src[1].reg.idx[0].offset = *tmp_idx;
ins->src[1].swizzle = vkd3d_shader_create_swizzle(j, j, j, j);
@@ -669,12 +1097,12 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program
/* discard_nz tmp.x */
- ins = &instructions->elements[pos + 1 + components_read];
- if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_DISCARD, 0, 1)))
+ ins = vsir_program_iterator_next(it);
+ if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VSIR_OP_DISCARD, 0, 1)))
return VKD3D_ERROR_OUT_OF_MEMORY;
ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ;
- vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
+ vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1);
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
ins->src[0].reg.idx[0].offset = *tmp_idx;
ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
@@ -692,30 +1120,29 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program
* not fused for "precise" operations."
* Windows drivers seem to conform with the latter, for SM 4-5 and SM 6. */
static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *program,
- struct vkd3d_shader_instruction *mad, unsigned int *tmp_idx)
+ struct vsir_program_iterator *it, unsigned int *tmp_idx)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
- struct vkd3d_shader_instruction *mul_ins, *add_ins;
- size_t pos = mad - instructions->elements;
+ struct vkd3d_shader_instruction *mad, *mul_ins, *add_ins;
struct vkd3d_shader_dst_param *mul_dst;
+ mad = vsir_program_iterator_current(it);
+
if (!(mad->flags & VKD3DSI_PRECISE_XYZW))
return VKD3D_OK;
- if (!shader_instruction_array_insert_at(instructions, pos + 1, 1))
+ if (!vsir_program_iterator_insert_after(it, 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
- mad = &instructions->elements[pos];
if (*tmp_idx == ~0u)
*tmp_idx = program->temp_count++;
- mul_ins = &instructions->elements[pos];
- add_ins = &instructions->elements[pos + 1];
+ mul_ins = vsir_program_iterator_current(it);
+ add_ins = vsir_program_iterator_next(it);
- mul_ins->opcode = VKD3DSIH_MUL;
+ mul_ins->opcode = VSIR_OP_MUL;
mul_ins->src_count = 2;
- if (!(vsir_instruction_init_with_params(program, add_ins, &mul_ins->location, VKD3DSIH_ADD, 1, 2)))
+ if (!(vsir_instruction_init_with_params(program, add_ins, &mul_ins->location, VSIR_OP_ADD, 1, 2)))
return VKD3D_ERROR_OUT_OF_MEMORY;
add_ins->flags = mul_ins->flags & VKD3DSI_PRECISE_XYZW;
@@ -736,84 +1163,308 @@ static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *pro
return VKD3D_OK;
}
-static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *program,
- struct vkd3d_shader_instruction *sincos)
+static enum vkd3d_result vsir_program_lower_imul(struct vsir_program *program,
+ struct vkd3d_shader_instruction *imul, struct vsir_transformation_context *ctx)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
- size_t pos = sincos - instructions->elements;
- struct vkd3d_shader_instruction *ins;
- unsigned int s;
+ if (imul->dst[0].reg.type != VKD3DSPR_NULL)
+ {
+ vkd3d_shader_error(ctx->message_context, &imul->location,
+ VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
+ "Extended multiplication is not implemented.");
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
+ }
- if (sincos->dst_count != 1)
- return VKD3D_OK;
+ imul->dst[0] = imul->dst[1];
+ imul->dst_count = 1;
+ imul->opcode = VSIR_OP_IMUL_LOW;
+
+ return VKD3D_OK;
+}
+
+static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program,
+ struct vsir_program_iterator *it, struct vsir_transformation_context *ctx)
+{
+ struct vkd3d_shader_instruction *udiv, *ins, *mov;
+ unsigned int count = 2;
+
+ udiv = vsir_program_iterator_current(it);
+
+ if (udiv->dst_count != 2)
+ {
+ vkd3d_shader_error(ctx->message_context, &udiv->location,
+ VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT,
+ "Internal compiler error: invalid destination count %zu for UDIV.",
+ udiv->dst_count);
+ return VKD3D_ERROR;
+ }
+
+ if (udiv->dst[0].reg.type != VKD3DSPR_NULL)
+ ++count;
+ if (udiv->dst[1].reg.type != VKD3DSPR_NULL)
+ ++count;
+
+ if (!vsir_program_iterator_insert_after(it, count))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ udiv = vsir_program_iterator_current(it);
+
+ /* Save the sources in a SSA in case a destination collides with a source. */
+ mov = vsir_program_iterator_next(it);
+ if (!(vsir_instruction_init_with_params(program, mov, &udiv->location, VSIR_OP_MOV, 1, 1)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ mov->src[0] = udiv->src[0];
+ dst_param_init_ssa(&mov->dst[0], program->ssa_count, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension);
- if (!shader_instruction_array_insert_at(instructions, pos + 1, 1))
+ mov = vsir_program_iterator_next(it);
+ if (!(vsir_instruction_init_with_params(program, mov, &udiv->location, VSIR_OP_MOV, 1, 1)))
return VKD3D_ERROR_OUT_OF_MEMORY;
- sincos = &instructions->elements[pos];
- ins = &instructions->elements[pos + 1];
+ mov->src[0] = udiv->src[1];
+ dst_param_init_ssa(&mov->dst[0], program->ssa_count + 1, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
- if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VKD3DSIH_SINCOS, 2, 1)))
+ if (udiv->dst[0].reg.type != VKD3DSPR_NULL)
+ {
+ ins = vsir_program_iterator_next(it);
+
+ if (!(vsir_instruction_init_with_params(program, ins, &udiv->location, VSIR_OP_UDIV_SIMPLE, 1, 2)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ ins->flags = udiv->flags;
+
+ src_param_init_ssa(&ins->src[0], program->ssa_count,
+ udiv->src[0].reg.data_type, udiv->src[0].reg.dimension);
+ src_param_init_ssa(&ins->src[1], program->ssa_count + 1,
+ udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
+ ins->dst[0] = udiv->dst[0];
+ }
+
+ if (udiv->dst[1].reg.type != VKD3DSPR_NULL)
+ {
+ ins = vsir_program_iterator_next(it);
+
+ if (!(vsir_instruction_init_with_params(program, ins, &udiv->location, VSIR_OP_UREM, 1, 2)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ ins->flags = udiv->flags;
+
+ src_param_init_ssa(&ins->src[0], program->ssa_count,
+ udiv->src[0].reg.data_type, udiv->src[0].reg.dimension);
+ src_param_init_ssa(&ins->src[1], program->ssa_count + 1,
+ udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
+ ins->dst[0] = udiv->dst[1];
+ }
+
+ vkd3d_shader_instruction_make_nop(udiv);
+ program->ssa_count += 2;
+
+ return VKD3D_OK;
+}
+
+static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *program,
+ struct vsir_program_iterator *it)
+{
+ struct vkd3d_shader_instruction *ins, *mov, *sincos;
+ unsigned int s, count;
+
+ sincos = vsir_program_iterator_current(it);
+ count = 1 + vkd3d_popcount(sincos->dst[0].write_mask & (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1));
+
+ if (!vsir_program_iterator_insert_after(it, count))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ sincos = vsir_program_iterator_current(it);
+
+ /* Save the source in a SSA in case a destination collides with the source. */
+ mov = vsir_program_iterator_next(it);
+ if (!(vsir_instruction_init_with_params(program, mov, &sincos->location, VSIR_OP_MOV, 1, 1)))
return VKD3D_ERROR_OUT_OF_MEMORY;
- ins->flags = sincos->flags;
+ mov->src[0] = sincos->src[0];
- *ins->src = *sincos->src;
/* Set the source swizzle to replicate the first component. */
s = vsir_swizzle_get_component(sincos->src->swizzle, 0);
- ins->src->swizzle = vkd3d_shader_create_swizzle(s, s, s, s);
+ mov->src[0].swizzle = vkd3d_shader_create_swizzle(s, s, s, s);
+
+ dst_param_init_ssa_scalar(&mov->dst[0], program->ssa_count, sincos->src[0].reg.data_type);
if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_1)
{
+ ins = vsir_program_iterator_next(it);
+
+ if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VSIR_OP_SIN, 1, 1)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ ins->flags = sincos->flags;
+
+ src_param_init_ssa_scalar(&ins->src[0], program->ssa_count, sincos->src[0].reg.data_type);
+
ins->dst[0] = *sincos->dst;
ins->dst[0].write_mask = VKD3DSP_WRITEMASK_1;
}
- else
+
+ if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_0)
{
- vsir_dst_param_init_null(&ins->dst[0]);
+ ins = vsir_program_iterator_next(it);
+
+ if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VSIR_OP_COS, 1, 1)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ ins->flags = sincos->flags;
+
+ src_param_init_ssa_scalar(&ins->src[0], program->ssa_count, sincos->src[0].reg.data_type);
+
+ ins->dst[0] = *sincos->dst;
+ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0;
}
- if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_0)
+ vkd3d_shader_instruction_make_nop(sincos);
+ ++program->ssa_count;
+
+ return VKD3D_OK;
+}
+
+static enum vkd3d_result vsir_program_lower_sm4_sincos(struct vsir_program *program,
+ struct vsir_program_iterator *it, struct vsir_transformation_context *ctx)
+{
+ struct vkd3d_shader_instruction *ins, *mov, *sincos;
+ unsigned int count = 1;
+
+ sincos = vsir_program_iterator_current(it);
+
+ if (sincos->dst_count != 2)
{
- ins->dst[1] = *sincos->dst;
- ins->dst[1].write_mask = VKD3DSP_WRITEMASK_0;
+ vkd3d_shader_error(ctx->message_context, &sincos->location,
+ VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT,
+ "Internal compiler error: invalid destination count %zu for SINCOS.",
+ sincos->dst_count);
+ return VKD3D_ERROR;
}
- else
+
+ if (sincos->dst[0].reg.type != VKD3DSPR_NULL)
+ ++count;
+ if (sincos->dst[1].reg.type != VKD3DSPR_NULL)
+ ++count;
+
+ if (!vsir_program_iterator_insert_after(it, count))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ sincos = vsir_program_iterator_current(it);
+
+ /* Save the source in a SSA in case a destination collides with the source. */
+ mov = vsir_program_iterator_next(it);
+ if (!(vsir_instruction_init_with_params(program, mov, &sincos->location, VSIR_OP_MOV, 1, 1)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ mov->src[0] = sincos->src[0];
+ dst_param_init_ssa(&mov->dst[0], program->ssa_count, sincos->src[0].reg.data_type, sincos->src[0].reg.dimension);
+
+ if (sincos->dst[0].reg.type != VKD3DSPR_NULL)
{
- vsir_dst_param_init_null(&ins->dst[1]);
+ ins = vsir_program_iterator_next(it);
+
+ if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VSIR_OP_SIN, 1, 1)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ ins->flags = sincos->flags;
+
+ src_param_init_ssa(&ins->src[0], program->ssa_count,
+ sincos->src[0].reg.data_type, sincos->src[0].reg.dimension);
+ ins->dst[0] = sincos->dst[0];
+ }
+
+ if (sincos->dst[1].reg.type != VKD3DSPR_NULL)
+ {
+ ins = vsir_program_iterator_next(it);
+
+ if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VSIR_OP_COS, 1, 1)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ ins->flags = sincos->flags;
+
+ src_param_init_ssa(&ins->src[0], program->ssa_count,
+ sincos->src[0].reg.data_type, sincos->src[0].reg.dimension);
+ ins->dst[0] = sincos->dst[1];
}
- /* Make the original instruction no-op */
vkd3d_shader_instruction_make_nop(sincos);
+ ++program->ssa_count;
+
+ return VKD3D_OK;
+}
+
+static enum vkd3d_result vsir_program_lower_texcrd(struct vsir_program *program,
+ struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context)
+{
+ /* texcrd DST, t# -> mov DST, t# */
+
+ if (ins->src[0].modifiers)
+ {
+ vkd3d_shader_error(message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
+ "Aborting due to not yet implemented feature: texcrd source modifier.");
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
+ }
+
+ ins->opcode = VSIR_OP_MOV;
+
+ return VKD3D_OK;
+}
+
+static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *program,
+ struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context)
+{
+ unsigned int idx = ins->src[0].reg.idx[0].offset;
+ struct vkd3d_shader_src_param *srcs;
+
+ /* texld DST, t# -> sample DST, t#, resource#, sampler# */
+
+ if (ins->src[0].modifiers)
+ {
+ vkd3d_shader_error(message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
+ "Aborting due to not yet implemented feature: texld source modifier.");
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
+ }
+
+ if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 3)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ /* Note we run before I/O normalization. */
+ srcs[0] = ins->src[0];
+ vsir_src_param_init_resource(&srcs[1], idx, idx);
+ vsir_src_param_init_sampler(&srcs[2], idx, idx);
+
+ ins->opcode = VSIR_OP_SAMPLE;
+ ins->src = srcs;
+ ins->src_count = 3;
return VKD3D_OK;
}
static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program,
- struct vkd3d_shader_instruction *tex, unsigned int *tmp_idx)
+ struct vsir_program_iterator *it, unsigned int *tmp_idx)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
- struct vkd3d_shader_location *location = &tex->location;
- struct vkd3d_shader_instruction *div_ins, *tex_ins;
- size_t pos = tex - instructions->elements;
+ struct vkd3d_shader_instruction *div_ins, *tex, *tex_ins;
+ struct vsir_program_iterator it2;
unsigned int w_comp;
+ tex = vsir_program_iterator_current(it);
+
w_comp = vsir_swizzle_get_component(tex->src[0].swizzle, 3);
- if (!shader_instruction_array_insert_at(instructions, pos + 1, 2))
+ if (!vsir_program_iterator_insert_after(it, 2))
return VKD3D_ERROR_OUT_OF_MEMORY;
- tex = &instructions->elements[pos];
+ tex = vsir_program_iterator_current(it);
if (*tmp_idx == ~0u)
*tmp_idx = program->temp_count++;
- div_ins = &instructions->elements[pos + 1];
- tex_ins = &instructions->elements[pos + 2];
+ /* Do not increment `it', because we need to scan the generated instructions
+ * again to lower TEXLD. */
+ it2 = *it;
+ div_ins = vsir_program_iterator_next(&it2);
+ tex_ins = vsir_program_iterator_next(&it2);
- if (!vsir_instruction_init_with_params(program, div_ins, location, VKD3DSIH_DIV, 1, 2))
+ if (!vsir_instruction_init_with_params(program, div_ins, &tex->location, VSIR_OP_DIV, 1, 2))
return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_dst_param_init(&div_ins->dst[0], VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
+ vsir_dst_param_init(&div_ins->dst[0], VKD3DSPR_TEMP, VSIR_DATA_F32, 1);
div_ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
div_ins->dst[0].reg.idx[0].offset = *tmp_idx;
div_ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL;
@@ -823,7 +1474,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program,
div_ins->src[1] = tex->src[0];
div_ins->src[1].swizzle = vkd3d_shader_create_swizzle(w_comp, w_comp, w_comp, w_comp);
- if (!vsir_instruction_init_with_params(program, tex_ins, location, VKD3DSIH_TEX, 1, 2))
+ if (!vsir_instruction_init_with_params(program, tex_ins, &tex->location, VSIR_OP_TEXLD, 1, 2))
return VKD3D_ERROR_OUT_OF_MEMORY;
tex_ins->dst[0] = tex->dst[0];
@@ -838,7 +1489,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program,
return VKD3D_OK;
}
-static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program,
+static enum vkd3d_result vsir_program_lower_texld(struct vsir_program *program,
struct vkd3d_shader_instruction *tex, struct vkd3d_shader_message_context *message_context)
{
unsigned int idx = tex->src[1].reg.idx[0].offset;
@@ -856,7 +1507,7 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program,
if (!tex->flags)
{
- tex->opcode = VKD3DSIH_SAMPLE;
+ tex->opcode = VSIR_OP_SAMPLE;
tex->src = srcs;
tex->src_count = 3;
}
@@ -864,7 +1515,7 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program,
{
enum vkd3d_shader_swizzle_component w = vsir_swizzle_get_component(srcs[0].swizzle, 3);
- tex->opcode = VKD3DSIH_SAMPLE_B;
+ tex->opcode = VSIR_OP_SAMPLE_B;
tex->src = srcs;
tex->src_count = 4;
@@ -899,13 +1550,41 @@ static enum vkd3d_result vsir_program_lower_texldd(struct vsir_program *program,
srcs[3] = texldd->src[2];
srcs[4] = texldd->src[3];
- texldd->opcode = VKD3DSIH_SAMPLE_GRAD;
+ texldd->opcode = VSIR_OP_SAMPLE_GRAD;
texldd->src = srcs;
texldd->src_count = 5;
return VKD3D_OK;
}
+static enum vkd3d_result vsir_program_lower_texldl(struct vsir_program *program,
+ struct vkd3d_shader_instruction *texldl)
+{
+ unsigned int idx = texldl->src[1].reg.idx[0].offset;
+ enum vkd3d_shader_swizzle_component w;
+ struct vkd3d_shader_src_param *srcs;
+
+ VKD3D_ASSERT(texldl->src[1].reg.idx_count == 1);
+ VKD3D_ASSERT(!texldl->src[1].reg.idx[0].rel_addr);
+
+ if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 4)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ srcs[0] = texldl->src[0];
+ vsir_src_param_init_resource(&srcs[1], idx, idx);
+ vsir_src_param_init_sampler(&srcs[2], idx, idx);
+
+ texldl->opcode = VSIR_OP_SAMPLE_LOD;
+ texldl->src = srcs;
+ texldl->src_count = 4;
+
+ w = vsir_swizzle_get_component(srcs[0].swizzle, 3);
+ srcs[3] = texldl->src[0];
+ srcs[3].swizzle = vkd3d_shader_create_swizzle(w, w, w, w);
+
+ return VKD3D_OK;
+}
+
static enum vkd3d_result vsir_program_lower_dcl_input(struct vsir_program *program,
struct vkd3d_shader_instruction *ins, struct vsir_transformation_context *ctx)
{
@@ -976,108 +1655,157 @@ static enum vkd3d_result vsir_program_lower_dcl_output(struct vsir_program *prog
return VKD3D_OK;
}
+static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_program *program,
+ struct vsir_transformation_context *ctx)
+{
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
+ struct vkd3d_shader_message_context *message_context = ctx->message_context;
+ struct vkd3d_shader_instruction *ins;
+ unsigned int tmp_idx = ~0u;
+
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
+ {
+ enum vkd3d_result ret;
+
+ switch (ins->opcode)
+ {
+ case VSIR_OP_TEXCRD:
+ ret = vsir_program_lower_texcrd(program, ins, message_context);
+ break;
+
+ case VSIR_OP_TEXLD:
+ if (program->shader_version.major == 1)
+ ret = vsir_program_lower_texld_sm1(program, ins, message_context);
+ else if (ins->flags == VKD3DSI_TEXLD_PROJECT)
+ ret = vsir_program_lower_texldp(program, &it, &tmp_idx);
+ else
+ ret = vsir_program_lower_texld(program, ins, message_context);
+ break;
+
+ default:
+ ret = VKD3D_OK;
+ break;
+ }
+
+ if (ret < 0)
+ return ret;
+ }
+
+ return VKD3D_OK;
+}
+
static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program,
struct vsir_transformation_context *ctx)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
struct vkd3d_shader_message_context *message_context = ctx->message_context;
- unsigned int tmp_idx = ~0u, i;
+ struct vkd3d_shader_instruction *ins;
+ unsigned int tmp_idx = ~0u;
enum vkd3d_result ret;
- for (i = 0; i < instructions->count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- struct vkd3d_shader_instruction *ins = &instructions->elements[i];
-
switch (ins->opcode)
{
- case VKD3DSIH_IFC:
- if ((ret = vsir_program_lower_ifc(program, ins, &tmp_idx, message_context)) < 0)
+ case VSIR_OP_IFC:
+ if ((ret = vsir_program_lower_ifc(program, &it, &tmp_idx, message_context)) < 0)
return ret;
break;
- case VKD3DSIH_TEXKILL:
- if ((ret = vsir_program_lower_texkill(program, ins, &tmp_idx)) < 0)
+ case VSIR_OP_TEXKILL:
+ if ((ret = vsir_program_lower_texkill(program, &it, &tmp_idx)) < 0)
return ret;
break;
- case VKD3DSIH_MAD:
- if ((ret = vsir_program_lower_precise_mad(program, ins, &tmp_idx)) < 0)
+ case VSIR_OP_MAD:
+ if ((ret = vsir_program_lower_precise_mad(program, &it, &tmp_idx)) < 0)
return ret;
break;
- case VKD3DSIH_DCL:
- case VKD3DSIH_DCL_CONSTANT_BUFFER:
- case VKD3DSIH_DCL_GLOBAL_FLAGS:
- case VKD3DSIH_DCL_SAMPLER:
- case VKD3DSIH_DCL_TEMPS:
- case VKD3DSIH_DCL_TESSELLATOR_DOMAIN:
- case VKD3DSIH_DCL_THREAD_GROUP:
- case VKD3DSIH_DCL_UAV_TYPED:
+ case VSIR_OP_DCL:
+ case VSIR_OP_DCL_CONSTANT_BUFFER:
+ case VSIR_OP_DCL_GLOBAL_FLAGS:
+ case VSIR_OP_DCL_SAMPLER:
+ case VSIR_OP_DCL_TEMPS:
+ case VSIR_OP_DCL_TESSELLATOR_DOMAIN:
+ case VSIR_OP_DCL_THREAD_GROUP:
+ case VSIR_OP_DCL_UAV_TYPED:
vkd3d_shader_instruction_make_nop(ins);
break;
- case VKD3DSIH_DCL_INPUT:
+ case VSIR_OP_DCL_INPUT:
vsir_program_lower_dcl_input(program, ins, ctx);
vkd3d_shader_instruction_make_nop(ins);
break;
- case VKD3DSIH_DCL_OUTPUT:
+ case VSIR_OP_DCL_OUTPUT:
vsir_program_lower_dcl_output(program, ins, ctx);
vkd3d_shader_instruction_make_nop(ins);
break;
- case VKD3DSIH_DCL_INPUT_SGV:
- case VKD3DSIH_DCL_INPUT_SIV:
- case VKD3DSIH_DCL_INPUT_PS:
- case VKD3DSIH_DCL_INPUT_PS_SGV:
- case VKD3DSIH_DCL_INPUT_PS_SIV:
- case VKD3DSIH_DCL_OUTPUT_SIV:
+ case VSIR_OP_DCL_INPUT_SGV:
+ case VSIR_OP_DCL_INPUT_SIV:
+ case VSIR_OP_DCL_INPUT_PS:
+ case VSIR_OP_DCL_INPUT_PS_SGV:
+ case VSIR_OP_DCL_INPUT_PS_SIV:
+ case VSIR_OP_DCL_OUTPUT_SGV:
+ case VSIR_OP_DCL_OUTPUT_SIV:
vkd3d_shader_instruction_make_nop(ins);
break;
- case VKD3DSIH_SINCOS:
- if ((ret = vsir_program_lower_sm1_sincos(program, ins)) < 0)
+ case VSIR_OP_IMUL:
+ case VSIR_OP_UMUL:
+ if ((ret = vsir_program_lower_imul(program, ins, ctx)) < 0)
return ret;
break;
- case VKD3DSIH_TEX:
- if (ins->flags == VKD3DSI_TEXLD_PROJECT)
+ case VSIR_OP_UDIV:
+ if ((ret = vsir_program_lower_udiv(program, &it, ctx)) < 0)
+ return ret;
+ break;
+
+ case VSIR_OP_SINCOS:
+ if (ins->dst_count == 1)
{
- if ((ret = vsir_program_lower_texldp(program, ins, &tmp_idx)) < 0)
+ if ((ret = vsir_program_lower_sm1_sincos(program, &it)) < 0)
return ret;
}
else
{
- if ((ret = vsir_program_lower_tex(program, ins, message_context)) < 0)
+ if ((ret = vsir_program_lower_sm4_sincos(program, &it, ctx)) < 0)
return ret;
}
break;
- case VKD3DSIH_TEXLDD:
+ case VSIR_OP_TEXLDD:
if ((ret = vsir_program_lower_texldd(program, ins)) < 0)
return ret;
break;
- case VKD3DSIH_TEXBEM:
- case VKD3DSIH_TEXBEML:
- case VKD3DSIH_TEXCOORD:
- case VKD3DSIH_TEXDEPTH:
- case VKD3DSIH_TEXDP3:
- case VKD3DSIH_TEXDP3TEX:
- case VKD3DSIH_TEXLDL:
- case VKD3DSIH_TEXM3x2PAD:
- case VKD3DSIH_TEXM3x2TEX:
- case VKD3DSIH_TEXM3x3DIFF:
- case VKD3DSIH_TEXM3x3PAD:
- case VKD3DSIH_TEXM3x3SPEC:
- case VKD3DSIH_TEXM3x3TEX:
- case VKD3DSIH_TEXM3x3VSPEC:
- case VKD3DSIH_TEXREG2AR:
- case VKD3DSIH_TEXREG2GB:
- case VKD3DSIH_TEXREG2RGB:
+ case VSIR_OP_TEXLDL:
+ if ((ret = vsir_program_lower_texldl(program, ins)) < 0)
+ return ret;
+ break;
+
+ case VSIR_OP_TEXBEM:
+ case VSIR_OP_TEXBEML:
+ case VSIR_OP_TEXCOORD:
+ case VSIR_OP_TEXDEPTH:
+ case VSIR_OP_TEXDP3:
+ case VSIR_OP_TEXDP3TEX:
+ case VSIR_OP_TEXM3x2PAD:
+ case VSIR_OP_TEXM3x2TEX:
+ case VSIR_OP_TEXM3x3DIFF:
+ case VSIR_OP_TEXM3x3PAD:
+ case VSIR_OP_TEXM3x3SPEC:
+ case VSIR_OP_TEXM3x3TEX:
+ case VSIR_OP_TEXM3x3VSPEC:
+ case VSIR_OP_TEXREG2AR:
+ case VSIR_OP_TEXREG2GB:
+ case VSIR_OP_TEXREG2RGB:
vkd3d_shader_error(ctx->message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
- "Aborting due to unimplemented feature: Combined sampler instruction %#x.",
- ins->opcode);
+ "Aborting due to unimplemented feature: Combined sampler instruction \"%s\" (%#x).",
+ vsir_opcode_get_name(ins->opcode, "<unknown>"), ins->opcode);
return VKD3D_ERROR_NOT_IMPLEMENTED;
default:
@@ -1088,69 +1816,69 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr
return VKD3D_OK;
}
-static void shader_register_eliminate_phase_addressing(struct vkd3d_shader_register *reg,
- unsigned int instance_id)
+/* Ensure that the program closes with a ret. sm1 programs do not, by default.
+ * Many of our IR passes rely on this in order to insert instructions at the
+ * end of execution. */
+static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program,
+ struct vsir_transformation_context *ctx)
{
- unsigned int i;
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
+ static const struct vkd3d_shader_location no_loc;
+ struct vkd3d_shader_instruction *ins;
- for (i = 0; i < reg->idx_count; ++i)
- {
- if (reg->idx[i].rel_addr && shader_register_is_phase_instance_id(&reg->idx[i].rel_addr->reg))
- {
- reg->idx[i].rel_addr = NULL;
- reg->idx[i].offset += instance_id;
- }
- }
-}
-
-static void shader_instruction_eliminate_phase_instance_id(struct vkd3d_shader_instruction *ins,
- unsigned int instance_id)
-{
- struct vkd3d_shader_register *reg;
- unsigned int i;
+ ins = vsir_program_iterator_tail(&it);
+ if (ins && ins->opcode == VSIR_OP_RET)
+ return VKD3D_OK;
- for (i = 0; i < ins->src_count; ++i)
- {
- reg = (struct vkd3d_shader_register *)&ins->src[i].reg;
- if (shader_register_is_phase_instance_id(reg))
- {
- vsir_register_init(reg, VKD3DSPR_IMMCONST, reg->data_type, 0);
- reg->u.immconst_u32[0] = instance_id;
- continue;
- }
- shader_register_eliminate_phase_addressing(reg, instance_id);
- }
+ if (!(ins = vsir_program_append(program)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ vsir_instruction_init(ins, &no_loc, VSIR_OP_RET);
- for (i = 0; i < ins->dst_count; ++i)
- shader_register_eliminate_phase_addressing(&ins->dst[i].reg, instance_id);
+ return VKD3D_OK;
}
-/* Ensure that the program closes with a ret. sm1 programs do not, by default.
- * Many of our IR passes rely on this in order to insert instructions at the
- * end of execution. */
-static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program,
+/* ps_1_* outputs color in r0. Add an instruction to copy that to oC0.
+ * We don't need to modify the signature since it already contains COLOR. */
+static enum vkd3d_result vsir_program_normalise_ps1_output(struct vsir_program *program,
struct vsir_transformation_context *ctx)
{
- static const struct vkd3d_shader_location no_loc;
- if (program->instructions.count
- && program->instructions.elements[program->instructions.count - 1].opcode == VKD3DSIH_RET)
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
+ struct vkd3d_shader_instruction *ins;
+ struct vkd3d_shader_location loc;
+
+ if (!(ins = vsir_program_iterator_tail(&it)))
return VKD3D_OK;
+ loc = ins->location;
- if (!shader_instruction_array_insert_at(&program->instructions, program->instructions.count, 1))
+ if (!(ins = vsir_program_append(program)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ if (!vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1))
+ {
+ vsir_instruction_init(ins, &loc, VSIR_OP_NOP);
return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_instruction_init(&program->instructions.elements[program->instructions.count - 1], &no_loc, VKD3DSIH_RET);
+ }
+
+ src_param_init_temp_float4(&ins->src[0], 0);
+ ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
+ /* Note we run before I/O normalization. */
+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_COLOROUT, VSIR_DATA_F32, 1);
+ ins->dst[0].reg.idx[0].offset = 0;
+ ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
+ ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL;
+ ins->dst[0].modifiers = VKD3DSPDM_SATURATE;
+
return VKD3D_OK;
}
-static bool add_signature_element(struct shader_signature *signature, const char *semantic_name,
- uint32_t semantic_index, uint32_t mask, uint32_t register_index,
+static struct signature_element *add_signature_element(struct shader_signature *signature,
+ const char *semantic_name, uint32_t semantic_index, uint32_t mask, uint32_t register_index,
enum vkd3d_shader_interpolation_mode interpolation_mode)
{
struct signature_element *new_elements, *e;
if (!(new_elements = vkd3d_realloc(signature->elements,
(signature->element_count + 1) * sizeof(*signature->elements))))
- return false;
+ return NULL;
signature->elements = new_elements;
e = &signature->elements[signature->element_count++];
memset(e, 0, sizeof(*e));
@@ -1164,7 +1892,7 @@ static bool add_signature_element(struct shader_signature *signature, const char
e->register_index = register_index;
e->target_location = register_index;
e->interpolation_mode = interpolation_mode;
- return true;
+ return e;
}
static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *program,
@@ -1194,6 +1922,7 @@ static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *pr
static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *program,
struct vsir_transformation_context *ctx)
{
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
static const struct vkd3d_shader_location no_loc;
struct vkd3d_shader_instruction *ins;
unsigned int i;
@@ -1205,24 +1934,23 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra
/* Write the instruction after all LABEL, DCL, and NOP instructions.
* We need to skip NOP instructions because they might result from removed
* DCLs, and there could still be DCLs after NOPs. */
- for (i = 0; i < program->instructions.count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- ins = &program->instructions.elements[i];
-
- if (!vsir_instruction_is_dcl(ins) && ins->opcode != VKD3DSIH_LABEL && ins->opcode != VKD3DSIH_NOP)
+ if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP)
break;
}
- if (!shader_instruction_array_insert_at(&program->instructions, i, 1))
+ vsir_program_iterator_prev(&it);
+ if (!vsir_program_iterator_insert_after(&it, 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
- ins = &program->instructions.elements[i];
+ ins = vsir_program_iterator_next(&it);
- vsir_instruction_init_with_params(program, ins, &no_loc, VKD3DSIH_MOV, 1, 1);
- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VKD3D_DATA_FLOAT, 1);
+ vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1);
+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VSIR_DATA_F32, 1);
ins->dst[0].reg.idx[0].offset = 0;
ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL & ~program->diffuse_written_mask;
- vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0);
+ vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0);
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
for (i = 0; i < 4; ++i)
ins->src[0].reg.u.immconst_f32[i] = 1.0f;
@@ -1316,6 +2044,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program
struct vsir_transformation_context *ctx)
{
const struct vkd3d_shader_location location = {.source_name = ctx->compile_info->source_name};
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
struct vkd3d_shader_message_context *message_context = ctx->message_context;
const struct vkd3d_shader_compile_info *compile_info = ctx->compile_info;
bool allows_subset_masks = target_allows_subset_masks(compile_info);
@@ -1325,6 +2054,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program
struct signature_element *new_elements, *e;
unsigned int uninit_varying_count = 0;
unsigned int subset_varying_count = 0;
+ struct vkd3d_shader_instruction *ins;
unsigned int new_register_count = 0;
unsigned int i;
@@ -1424,31 +2154,29 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program
}
/* Write each uninitialized varying before each ret. */
- for (i = 0; i < program->instructions.count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
struct vkd3d_shader_location loc;
- if (ins->opcode != VKD3DSIH_RET)
+ if (ins->opcode != VSIR_OP_RET)
continue;
loc = ins->location;
- if (!shader_instruction_array_insert_at(&program->instructions, i, uninit_varying_count))
+ vsir_program_iterator_prev(&it);
+ if (!vsir_program_iterator_insert_after(&it, uninit_varying_count))
return VKD3D_ERROR_OUT_OF_MEMORY;
- ins = &program->instructions.elements[i];
+ ins = vsir_program_iterator_next(&it);
for (unsigned int j = signature->element_count - uninit_varying_count; j < signature->element_count; ++j)
{
e = &signature->elements[j];
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1);
- dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, e->register_index, e->mask);
- vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0);
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1);
+ dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, e->register_index, e->mask);
+ vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0);
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
- ++ins;
+ ins = vsir_program_iterator_next(&it);
}
-
- i += uninit_varying_count;
}
/* Vulkan (without KHR_maintenance4) disallows any mismatching masks,
@@ -1459,10 +2187,8 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program
if (!subset_varying_count || allows_subset_masks)
return VKD3D_OK;
- for (i = 0; i < program->instructions.count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
-
for (unsigned int j = 0; j < ins->dst_count; ++j)
remove_unread_output_components(signature, ins, &ins->dst[j]);
}
@@ -1472,17 +2198,19 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program
struct hull_flattener
{
- struct vkd3d_shader_instruction_array instructions;
+ struct vsir_program *program;
unsigned int instance_count;
unsigned int phase_body_idx;
enum vkd3d_shader_opcode phase;
struct vkd3d_shader_location last_ret_location;
+ unsigned int *ssa_map;
+ unsigned int orig_ssa_count;
};
static bool flattener_is_in_fork_or_join_phase(const struct hull_flattener *flattener)
{
- return flattener->phase == VKD3DSIH_HS_FORK_PHASE || flattener->phase == VKD3DSIH_HS_JOIN_PHASE;
+ return flattener->phase == VSIR_OP_HS_FORK_PHASE || flattener->phase == VSIR_OP_HS_JOIN_PHASE;
}
struct shader_phase_location
@@ -1499,14 +2227,13 @@ struct shader_phase_location_array
unsigned int count;
};
-static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normaliser,
- unsigned int index, struct shader_phase_location_array *locations)
+static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normaliser, unsigned int index,
+ struct vkd3d_shader_instruction *ins, struct shader_phase_location_array *locations)
{
- struct vkd3d_shader_instruction *ins = &normaliser->instructions.elements[index];
struct shader_phase_location *loc;
bool b;
- if (ins->opcode == VKD3DSIH_HS_FORK_PHASE || ins->opcode == VKD3DSIH_HS_JOIN_PHASE)
+ if (ins->opcode == VSIR_OP_HS_FORK_PHASE || ins->opcode == VSIR_OP_HS_JOIN_PHASE)
{
b = flattener_is_in_fork_or_join_phase(normaliser);
/* Reset the phase info. */
@@ -1518,21 +2245,21 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal
vkd3d_shader_instruction_make_nop(ins);
return;
}
- else if (ins->opcode == VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT
- || ins->opcode == VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT)
+ else if (ins->opcode == VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT
+ || ins->opcode == VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT)
{
normaliser->instance_count = ins->declaration.count + !ins->declaration.count;
vkd3d_shader_instruction_make_nop(ins);
return;
}
- if (normaliser->phase == VKD3DSIH_INVALID || vsir_instruction_is_dcl(ins))
+ if (normaliser->phase == VSIR_OP_INVALID || vsir_instruction_is_dcl(ins))
return;
if (normaliser->phase_body_idx == ~0u)
normaliser->phase_body_idx = index;
- if (ins->opcode == VKD3DSIH_RET)
+ if (ins->opcode == VSIR_OP_RET)
{
normaliser->last_ret_location = ins->location;
vkd3d_shader_instruction_make_nop(ins);
@@ -1548,26 +2275,89 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal
}
}
+static void flattener_fixup_ssa_register(struct hull_flattener *normaliser,
+ struct vkd3d_shader_register *reg, unsigned int instance_id)
+{
+ unsigned int id;
+
+ if (!register_is_ssa(reg))
+ return;
+
+ /* No need to alter the first copy, they are already not conflicting. */
+ if (instance_id == 0)
+ return;
+
+ id = reg->idx[0].offset;
+ VKD3D_ASSERT(id < normaliser->orig_ssa_count);
+ if (normaliser->ssa_map[id] == UINT_MAX)
+ normaliser->ssa_map[id] = normaliser->program->ssa_count++;
+ reg->idx[0].offset = normaliser->ssa_map[id];
+}
+
+static void flattener_fixup_register_indices(struct hull_flattener *normaliser,
+ struct vkd3d_shader_register *reg, unsigned int instance_id)
+{
+ unsigned int i;
+
+ flattener_fixup_ssa_register(normaliser, reg, instance_id);
+
+ for (i = 0; i < reg->idx_count; ++i)
+ {
+ if (reg->idx[i].rel_addr)
+ {
+ flattener_fixup_ssa_register(normaliser, &reg->idx[i].rel_addr->reg, instance_id);
+ if (shader_register_is_phase_instance_id(&reg->idx[i].rel_addr->reg))
+ {
+ reg->idx[i].rel_addr = NULL;
+ reg->idx[i].offset += instance_id;
+ }
+ }
+ }
+}
+
+static void flattener_fixup_registers(struct hull_flattener *normaliser,
+ struct vkd3d_shader_instruction *ins, unsigned int instance_id)
+{
+ struct vkd3d_shader_register *reg;
+ unsigned int i;
+
+ for (i = 0; i < ins->src_count; ++i)
+ {
+ reg = &ins->src[i].reg;
+ if (shader_register_is_phase_instance_id(reg))
+ {
+ vsir_register_init(reg, VKD3DSPR_IMMCONST, reg->data_type, 0);
+ reg->u.immconst_u32[0] = instance_id;
+ continue;
+ }
+ flattener_fixup_register_indices(normaliser, reg, instance_id);
+ }
+
+ for (i = 0; i < ins->dst_count; ++i)
+ flattener_fixup_register_indices(normaliser, &ins->dst[i].reg, instance_id);
+}
+
static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normaliser,
struct shader_phase_location_array *locations)
{
+ struct vkd3d_shader_instruction_array *instructions = &normaliser->program->instructions;
struct shader_phase_location *loc;
unsigned int i, j, k, end, count;
for (i = 0, count = 0; i < locations->count; ++i)
count += (locations->locations[i].instance_count - 1) * locations->locations[i].instruction_count;
- if (!shader_instruction_array_reserve(&normaliser->instructions, normaliser->instructions.count + count))
+ if (!shader_instruction_array_reserve(instructions, instructions->count + count))
return VKD3D_ERROR_OUT_OF_MEMORY;
- end = normaliser->instructions.count;
- normaliser->instructions.count += count;
+ end = instructions->count;
+ instructions->count += count;
for (i = locations->count; i > 0; --i)
{
loc = &locations->locations[i - 1];
j = loc->index + loc->instruction_count;
- memmove(&normaliser->instructions.elements[j + count], &normaliser->instructions.elements[j],
- (end - j) * sizeof(*normaliser->instructions.elements));
+ memmove(&instructions->elements[j + count], &instructions->elements[j],
+ (end - j) * sizeof(*instructions->elements));
end = j;
count -= (loc->instance_count - 1) * loc->instruction_count;
loc->index += count;
@@ -1581,7 +2371,7 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali
{
for (k = 0; k < loc->instruction_count; ++k)
{
- if (!shader_instruction_array_clone_instruction(&normaliser->instructions,
+ if (!shader_instruction_array_clone_instruction(instructions,
loc->index + loc->instruction_count * j + k, loc->index + k))
return VKD3D_ERROR_OUT_OF_MEMORY;
}
@@ -1589,9 +2379,12 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali
/* Replace each reference to the instance id with a constant instance id. */
for (j = 0; j < loc->instance_count; ++j)
{
+ if (j != 0)
+ memset(normaliser->ssa_map, 0xff, normaliser->orig_ssa_count * sizeof(*normaliser->ssa_map));
+
for (k = 0; k < loc->instruction_count; ++k)
- shader_instruction_eliminate_phase_instance_id(
- &normaliser->instructions.elements[loc->index + loc->instruction_count * j + k], j);
+ flattener_fixup_registers(normaliser,
+ &instructions->elements[loc->index + loc->instruction_count * j + k], j);
}
}
@@ -1601,31 +2394,41 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali
static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_program *program,
struct vsir_transformation_context *ctx)
{
- struct hull_flattener flattener = {program->instructions};
- struct vkd3d_shader_instruction_array *instructions;
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
struct shader_phase_location_array locations;
+ struct hull_flattener flattener = {program};
+ struct vkd3d_shader_instruction *ins;
enum vkd3d_result result = VKD3D_OK;
unsigned int i;
- instructions = &flattener.instructions;
-
- flattener.phase = VKD3DSIH_INVALID;
- for (i = 0, locations.count = 0; i < instructions->count; ++i)
- flattener_eliminate_phase_related_dcls(&flattener, i, &locations);
+ flattener.phase = VSIR_OP_INVALID;
+ locations.count = 0;
+ for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i)
+ {
+ flattener_eliminate_phase_related_dcls(&flattener, i, ins, &locations);
+ }
bitmap_clear(program->io_dcls, VKD3DSPR_FORKINSTID);
bitmap_clear(program->io_dcls, VKD3DSPR_JOININSTID);
- if ((result = flattener_flatten_phases(&flattener, &locations)) < 0)
+ flattener.orig_ssa_count = program->ssa_count;
+ if (!(flattener.ssa_map = vkd3d_calloc(flattener.orig_ssa_count, sizeof(*flattener.ssa_map))))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ result = flattener_flatten_phases(&flattener, &locations);
+
+ vkd3d_free(flattener.ssa_map);
+ flattener.ssa_map = NULL;
+
+ if (result < 0)
return result;
- if (flattener.phase != VKD3DSIH_INVALID)
+ if (flattener.phase != VSIR_OP_INVALID)
{
- if (!shader_instruction_array_reserve(&flattener.instructions, flattener.instructions.count + 1))
+ if (!(ins = vsir_program_append(program)))
return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_instruction_init(&instructions->elements[instructions->count++], &flattener.last_ret_location, VKD3DSIH_RET);
+ vsir_instruction_init(ins, &flattener.last_ret_location, VSIR_OP_RET);
}
- program->instructions = flattener.instructions;
return result;
}
@@ -1638,7 +2441,7 @@ struct control_point_normaliser
static bool control_point_normaliser_is_in_control_point_phase(const struct control_point_normaliser *normaliser)
{
- return normaliser->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE;
+ return normaliser->phase == VSIR_OP_HS_CONTROL_POINT_PHASE;
}
struct vkd3d_shader_src_param *vsir_program_create_outpointid_param(struct vsir_program *program)
@@ -1652,7 +2455,7 @@ struct vkd3d_shader_src_param *vsir_program_create_outpointid_param(struct vsir_
if (!(rel_addr = shader_src_param_allocator_get(&instructions->src_params, 1)))
return NULL;
- vsir_register_init(&rel_addr->reg, VKD3DSPR_OUTPOINTID, VKD3D_DATA_UINT, 0);
+ vsir_register_init(&rel_addr->reg, VKD3DSPR_OUTPOINTID, VSIR_DATA_U32, 0);
rel_addr->swizzle = 0;
rel_addr->modifiers = 0;
@@ -1696,7 +2499,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p
normaliser->instructions.count += count;
ins = &normaliser->instructions.elements[dst];
- vsir_instruction_init(ins, location, VKD3DSIH_HS_CONTROL_POINT_PHASE);
+ vsir_instruction_init(ins, location, VSIR_OP_HS_CONTROL_POINT_PHASE);
++ins;
@@ -1706,7 +2509,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p
if (!e->used_mask)
continue;
- vsir_instruction_init(ins, location, VKD3DSIH_MOV);
+ vsir_instruction_init(ins, location, VSIR_OP_MOV);
ins->dst = shader_dst_param_allocator_get(&normaliser->instructions.dst_params, 1);
ins->dst_count = 1;
ins->src = shader_src_param_allocator_get(&normaliser->instructions.src_params, 1);
@@ -1733,7 +2536,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p
++ins;
}
- vsir_instruction_init(ins, location, VKD3DSIH_RET);
+ vsir_instruction_init(ins, location, VSIR_OP_RET);
return VKD3D_OK;
}
@@ -1741,11 +2544,11 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p
static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_io(
struct vsir_program *program, struct vsir_transformation_context *ctx)
{
- struct vkd3d_shader_instruction_array *instructions;
struct control_point_normaliser normaliser;
unsigned int input_control_point_count;
struct vkd3d_shader_location location;
struct vkd3d_shader_instruction *ins;
+ struct vsir_program_iterator it;
enum vkd3d_result ret;
unsigned int i, j;
@@ -1763,18 +2566,16 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
return VKD3D_ERROR_OUT_OF_MEMORY;
}
normaliser.instructions = program->instructions;
- instructions = &normaliser.instructions;
- normaliser.phase = VKD3DSIH_INVALID;
+ it = vsir_program_iterator(&normaliser.instructions);
+ normaliser.phase = VSIR_OP_INVALID;
- for (i = 0; i < normaliser.instructions.count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- ins = &instructions->elements[i];
-
switch (ins->opcode)
{
- case VKD3DSIH_HS_CONTROL_POINT_PHASE:
- case VKD3DSIH_HS_FORK_PHASE:
- case VKD3DSIH_HS_JOIN_PHASE:
+ case VSIR_OP_HS_CONTROL_POINT_PHASE:
+ case VSIR_OP_HS_FORK_PHASE:
+ case VSIR_OP_HS_JOIN_PHASE:
normaliser.phase = ins->opcode;
break;
default:
@@ -1786,24 +2587,22 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i
}
}
- normaliser.phase = VKD3DSIH_INVALID;
+ normaliser.phase = VSIR_OP_INVALID;
input_control_point_count = 1;
- for (i = 0; i < instructions->count; ++i)
+ for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i)
{
- ins = &instructions->elements[i];
-
switch (ins->opcode)
{
- case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT:
+ case VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT:
input_control_point_count = ins->declaration.count;
break;
- case VKD3DSIH_HS_CONTROL_POINT_PHASE:
+ case VSIR_OP_HS_CONTROL_POINT_PHASE:
program->instructions = normaliser.instructions;
program->normalisation_level = VSIR_NORMALISED_HULL_CONTROL_POINT_IO;
return VKD3D_OK;
- case VKD3DSIH_HS_FORK_PHASE:
- case VKD3DSIH_HS_JOIN_PHASE:
+ case VSIR_OP_HS_FORK_PHASE:
+ case VSIR_OP_HS_JOIN_PHASE:
/* ins may be relocated if the instruction array expands. */
location = ins->location;
ret = control_point_normaliser_emit_hs_input(&normaliser, &program->input_signature,
@@ -1835,7 +2634,7 @@ struct io_normaliser_register_data
struct io_normaliser
{
struct vkd3d_shader_message_context *message_context;
- struct vkd3d_shader_instruction_array instructions;
+ enum vkd3d_result result;
enum vkd3d_shader_type shader_type;
uint8_t major;
struct shader_signature *input_signature;
@@ -1861,7 +2660,7 @@ struct io_normaliser
static bool io_normaliser_is_in_fork_or_join_phase(const struct io_normaliser *normaliser)
{
- return normaliser->phase == VKD3DSIH_HS_FORK_PHASE || normaliser->phase == VKD3DSIH_HS_JOIN_PHASE;
+ return normaliser->phase == VSIR_OP_HS_FORK_PHASE || normaliser->phase == VSIR_OP_HS_JOIN_PHASE;
}
static bool shader_signature_find_element_for_reg(const struct shader_signature *signature,
@@ -2338,7 +3137,7 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par
}
static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_param,
- struct io_normaliser *normaliser)
+ struct io_normaliser *normaliser, struct vkd3d_shader_instruction *ins)
{
unsigned int i, id_idx, reg_idx, write_mask, element_idx, component_idx;
struct vkd3d_shader_register *reg = &src_param->reg;
@@ -2401,7 +3200,12 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par
id_idx = reg->idx_count - 1;
write_mask = VKD3DSP_WRITEMASK_0 << vsir_swizzle_get_component(src_param->swizzle, 0);
if (!shader_signature_find_element_for_reg(signature, reg_idx, write_mask, &element_idx))
- vkd3d_unreachable();
+ {
+ vkd3d_shader_error(normaliser->message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE,
+ "Unable to resolve I/O register to a signature element.");
+ normaliser->result = VKD3D_ERROR_INVALID_SHADER;
+ return;
+ }
e = &signature->elements[element_idx];
if ((e->register_count > 1 || vsir_sysval_semantic_is_tess_factor(e->sysval_semantic)))
@@ -2424,9 +3228,9 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
switch (ins->opcode)
{
- case VKD3DSIH_HS_CONTROL_POINT_PHASE:
- case VKD3DSIH_HS_FORK_PHASE:
- case VKD3DSIH_HS_JOIN_PHASE:
+ case VSIR_OP_HS_CONTROL_POINT_PHASE:
+ case VSIR_OP_HS_FORK_PHASE:
+ case VSIR_OP_HS_JOIN_PHASE:
normaliser->phase = ins->opcode;
memset(normaliser->input_dcl_params, 0, sizeof(normaliser->input_dcl_params));
memset(normaliser->output_dcl_params, 0, sizeof(normaliser->output_dcl_params));
@@ -2438,7 +3242,7 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
for (i = 0; i < ins->dst_count; ++i)
shader_dst_param_io_normalise(&ins->dst[i], normaliser);
for (i = 0; i < ins->src_count; ++i)
- shader_src_param_io_normalise(&ins->src[i], normaliser);
+ shader_src_param_io_normalise(&ins->src[i], normaliser, ins);
break;
}
}
@@ -2446,37 +3250,35 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program *program,
struct vsir_transformation_context *ctx)
{
- struct io_normaliser normaliser = {ctx->message_context, program->instructions};
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
+ struct io_normaliser normaliser = {ctx->message_context, VKD3D_OK};
struct vkd3d_shader_instruction *ins;
enum vkd3d_result ret;
- unsigned int i;
VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_HULL_CONTROL_POINT_IO);
- normaliser.phase = VKD3DSIH_INVALID;
+ normaliser.phase = VSIR_OP_INVALID;
normaliser.shader_type = program->shader_version.type;
normaliser.major = program->shader_version.major;
normaliser.input_signature = &program->input_signature;
normaliser.output_signature = &program->output_signature;
normaliser.patch_constant_signature = &program->patch_constant_signature;
- for (i = 0; i < program->instructions.count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- ins = &program->instructions.elements[i];
-
switch (ins->opcode)
{
- case VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT:
+ case VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT:
normaliser.output_control_point_count = ins->declaration.count;
break;
- case VKD3DSIH_DCL_INDEX_RANGE:
+ case VSIR_OP_DCL_INDEX_RANGE:
if ((ret = io_normaliser_add_index_range(&normaliser, ins)) < 0)
return ret;
vkd3d_shader_instruction_make_nop(ins);
break;
- case VKD3DSIH_HS_CONTROL_POINT_PHASE:
- case VKD3DSIH_HS_FORK_PHASE:
- case VKD3DSIH_HS_JOIN_PHASE:
+ case VSIR_OP_HS_CONTROL_POINT_PHASE:
+ case VSIR_OP_HS_FORK_PHASE:
+ case VSIR_OP_HS_JOIN_PHASE:
normaliser.phase = ins->opcode;
break;
default:
@@ -2489,19 +3291,17 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program
normaliser.output_range_map, false)) < 0
|| (ret = shader_signature_merge(&normaliser, &program->patch_constant_signature,
normaliser.pc_range_map, true)) < 0)
- {
- program->instructions = normaliser.instructions;
return ret;
- }
- normaliser.phase = VKD3DSIH_INVALID;
- for (i = 0; i < normaliser.instructions.count; ++i)
- shader_instruction_normalise_io_params(&normaliser.instructions.elements[i], &normaliser);
+ normaliser.phase = VSIR_OP_INVALID;
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
+ {
+ shader_instruction_normalise_io_params(ins, &normaliser);
+ }
- program->instructions = normaliser.instructions;
program->use_vocp = normaliser.use_vocp;
program->normalisation_level = VSIR_NORMALISED_SM6;
- return VKD3D_OK;
+ return normaliser.result;
}
struct flat_constant_def
@@ -2587,14 +3387,14 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par
static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_program *program,
struct vsir_transformation_context *ctx)
{
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
struct flat_constants_normaliser normaliser = {0};
- unsigned int i, j;
+ struct vkd3d_shader_instruction *ins;
+ unsigned int i;
- for (i = 0; i < program->instructions.count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
-
- if (ins->opcode == VKD3DSIH_DEF || ins->opcode == VKD3DSIH_DEFI || ins->opcode == VKD3DSIH_DEFB)
+ if (ins->opcode == VSIR_OP_DEF || ins->opcode == VSIR_OP_DEFI || ins->opcode == VSIR_OP_DEFB)
{
struct flat_constant_def *def;
@@ -2608,15 +3408,19 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr
def = &normaliser.defs[normaliser.def_count++];
get_flat_constant_register_type(&ins->dst[0].reg, &def->set, &def->index, NULL);
- for (j = 0; j < 4; ++j)
- def->value[j] = ins->src[0].reg.u.immconst_u32[j];
+ for (i = 0; i < 4; ++i)
+ {
+ def->value[i] = ins->src[0].reg.u.immconst_u32[i];
+ }
vkd3d_shader_instruction_make_nop(ins);
}
else
{
- for (j = 0; j < ins->src_count; ++j)
- shader_register_normalise_flat_constants(&ins->src[j], &normaliser);
+ for (i = 0; i < ins->src_count; ++i)
+ {
+ shader_register_normalise_flat_constants(&ins->src[i], &normaliser);
+ }
}
}
@@ -2627,18 +3431,18 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr
static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *program,
struct vsir_transformation_context *ctx)
{
- size_t i, depth = 0;
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
+ struct vkd3d_shader_instruction *ins;
bool dead = false;
+ size_t depth = 0;
- for (i = 0; i < program->instructions.count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
-
switch (ins->opcode)
{
- case VKD3DSIH_IF:
- case VKD3DSIH_LOOP:
- case VKD3DSIH_SWITCH:
+ case VSIR_OP_IF:
+ case VSIR_OP_LOOP:
+ case VSIR_OP_SWITCH:
if (dead)
{
vkd3d_shader_instruction_make_nop(ins);
@@ -2646,15 +3450,15 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog
}
break;
- case VKD3DSIH_ENDIF:
- case VKD3DSIH_ENDLOOP:
- case VKD3DSIH_ENDSWITCH:
- case VKD3DSIH_ELSE:
+ case VSIR_OP_ENDIF:
+ case VSIR_OP_ENDLOOP:
+ case VSIR_OP_ENDSWITCH:
+ case VSIR_OP_ELSE:
if (dead)
{
if (depth > 0)
{
- if (ins->opcode != VKD3DSIH_ELSE)
+ if (ins->opcode != VSIR_OP_ELSE)
--depth;
vkd3d_shader_instruction_make_nop(ins);
}
@@ -2669,9 +3473,9 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog
* segment began. So it starts at zero and it signals the
* termination of the dead code segment when it would
* become negative. */
- case VKD3DSIH_BREAK:
- case VKD3DSIH_RET:
- case VKD3DSIH_CONTINUE:
+ case VSIR_OP_BREAK:
+ case VSIR_OP_RET:
+ case VSIR_OP_CONTINUE:
if (dead)
{
vkd3d_shader_instruction_make_nop(ins);
@@ -2686,8 +3490,8 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog
/* If `case' or `default' appears at zero depth, it means
* that they are a possible target for the corresponding
* switch, so the code is live again. */
- case VKD3DSIH_CASE:
- case VKD3DSIH_DEFAULT:
+ case VSIR_OP_CASE:
+ case VSIR_OP_DEFAULT:
if (dead)
{
if (depth == 0)
@@ -2701,9 +3505,9 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog
* outside of any block. When a phase returns, control is
* moved to the following phase, so they make code live
* again. */
- case VKD3DSIH_HS_CONTROL_POINT_PHASE:
- case VKD3DSIH_HS_FORK_PHASE:
- case VKD3DSIH_HS_JOIN_PHASE:
+ case VSIR_OP_HS_CONTROL_POINT_PHASE:
+ case VSIR_OP_HS_FORK_PHASE:
+ case VSIR_OP_HS_JOIN_PHASE:
dead = false;
break;
@@ -2817,7 +3621,7 @@ static bool cf_flattener_copy_instruction(struct cf_flattener *flattener,
{
struct vkd3d_shader_instruction *dst_ins;
- if (instruction->opcode == VKD3DSIH_NOP)
+ if (instruction->opcode == VSIR_OP_NOP)
return true;
if (!(dst_ins = cf_flattener_require_space(flattener, 1)))
@@ -2871,7 +3675,7 @@ static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flatten
if (!(ins = cf_flattener_require_space(flattener, 1)))
return NULL;
- vsir_instruction_init(ins, &flattener->location, VKD3DSIH_BRANCH);
+ vsir_instruction_init(ins, &flattener->location, VSIR_OP_BRANCH);
if (condition)
{
@@ -3006,10 +3810,11 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
struct vkd3d_shader_message_context *message_context)
{
struct vkd3d_shader_instruction_array *instructions;
+ const struct vkd3d_shader_instruction *instruction;
struct vsir_program *program = flattener->program;
bool is_hull_shader, after_declarations_section;
struct vkd3d_shader_instruction *dst_ins;
- size_t i;
+ struct vsir_program_iterator it;
instructions = &program->instructions;
is_hull_shader = program->shader_version.type == VKD3D_SHADER_TYPE_HULL;
@@ -3018,10 +3823,10 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
if (!cf_flattener_require_space(flattener, instructions->count + 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
- for (i = 0; i < instructions->count; ++i)
+ it = vsir_program_iterator(instructions);
+ for (instruction = vsir_program_iterator_head(&it); instruction; instruction = vsir_program_iterator_next(&it))
{
unsigned int loop_header_block_id, loop_body_block_id, continue_block_id, merge_block_id, true_block_id;
- const struct vkd3d_shader_instruction *instruction = &instructions->elements[i];
const struct vkd3d_shader_src_param *src = instruction->src;
struct cf_flattener_info *cf_info;
@@ -3031,9 +3836,9 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
* phase instruction, and in all other shader types begins with the first label instruction.
* Declaring an indexable temp with function scope is not considered a declaration,
* because it needs to live inside a function. */
- if (!after_declarations_section && instruction->opcode != VKD3DSIH_NOP)
+ if (!after_declarations_section && instruction->opcode != VSIR_OP_NOP)
{
- bool is_function_indexable = instruction->opcode == VKD3DSIH_DCL_INDEXABLE_TEMP
+ bool is_function_indexable = instruction->opcode == VSIR_OP_DCL_INDEXABLE_TEMP
&& instruction->declaration.indexable_temp.has_function_scope;
if (!vsir_instruction_is_dcl(instruction) || is_function_indexable)
@@ -3048,22 +3853,22 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
switch (instruction->opcode)
{
- case VKD3DSIH_HS_CONTROL_POINT_PHASE:
- case VKD3DSIH_HS_FORK_PHASE:
- case VKD3DSIH_HS_JOIN_PHASE:
+ case VSIR_OP_HS_CONTROL_POINT_PHASE:
+ case VSIR_OP_HS_FORK_PHASE:
+ case VSIR_OP_HS_JOIN_PHASE:
if (!cf_flattener_copy_instruction(flattener, instruction))
return VKD3D_ERROR_OUT_OF_MEMORY;
- if (instruction->opcode != VKD3DSIH_HS_CONTROL_POINT_PHASE || !instruction->flags)
+ if (instruction->opcode != VSIR_OP_HS_CONTROL_POINT_PHASE || !instruction->flags)
after_declarations_section = false;
break;
- case VKD3DSIH_LABEL:
+ case VSIR_OP_LABEL:
vkd3d_shader_error(message_context, &instruction->location,
VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
"Aborting due to not yet implemented feature: Label instruction.");
return VKD3D_ERROR_NOT_IMPLEMENTED;
- case VKD3DSIH_IF:
+ case VSIR_OP_IF:
if (!(cf_info = cf_flattener_push_control_flow_level(flattener)))
return VKD3D_ERROR_OUT_OF_MEMORY;
@@ -3087,7 +3892,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
++flattener->branch_id;
break;
- case VKD3DSIH_ELSE:
+ case VSIR_OP_ELSE:
if (cf_info->inside_block)
cf_flattener_emit_unconditional_branch(flattener, cf_info->u.if_.merge_block_id);
@@ -3101,7 +3906,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
cf_info->inside_block = true;
break;
- case VKD3DSIH_ENDIF:
+ case VSIR_OP_ENDIF:
if (cf_info->inside_block)
cf_flattener_emit_unconditional_branch(flattener, cf_info->u.if_.merge_block_id);
@@ -3110,7 +3915,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
cf_flattener_pop_control_flow_level(flattener);
break;
- case VKD3DSIH_LOOP:
+ case VSIR_OP_LOOP:
if (!(cf_info = cf_flattener_push_control_flow_level(flattener)))
return VKD3D_ERROR_OUT_OF_MEMORY;
@@ -3139,7 +3944,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
++flattener->loop_id;
break;
- case VKD3DSIH_ENDLOOP:
+ case VSIR_OP_ENDLOOP:
if (cf_info->inside_block)
cf_flattener_emit_unconditional_branch(flattener, cf_info->u.loop.continue_block_id);
@@ -3150,7 +3955,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
cf_flattener_pop_control_flow_level(flattener);
break;
- case VKD3DSIH_SWITCH:
+ case VSIR_OP_SWITCH:
if (!(cf_info = cf_flattener_push_control_flow_level(flattener)))
return VKD3D_ERROR_OUT_OF_MEMORY;
@@ -3161,7 +3966,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
if (!(dst_ins = cf_flattener_require_space(flattener, 1)))
return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_instruction_init(dst_ins, &instruction->location, VKD3DSIH_SWITCH_MONOLITHIC);
+ vsir_instruction_init(dst_ins, &instruction->location, VSIR_OP_SWITCH_MONOLITHIC);
++flattener->instruction_count;
cf_info->u.switch_.id = flattener->switch_id;
@@ -3182,7 +3987,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
break;
- case VKD3DSIH_ENDSWITCH:
+ case VSIR_OP_ENDSWITCH:
{
struct vkd3d_shader_src_param *src_params;
unsigned int j;
@@ -3207,7 +4012,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
for (j = 0; j < cf_info->u.switch_.cases_count; ++j)
{
unsigned int index = j * 2 + 3;
- vsir_src_param_init(&src_params[index], VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0);
+ vsir_src_param_init(&src_params[index], VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0);
src_params[index].reg.u.immconst_u32[0] = cf_info->u.switch_.cases[j].value;
vsir_src_param_init_label(&src_params[index + 1], cf_info->u.switch_.cases[j].block_id);
}
@@ -3217,7 +4022,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
break;
}
- case VKD3DSIH_CASE:
+ case VSIR_OP_CASE:
{
unsigned int label_id, value;
@@ -3249,7 +4054,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
break;
}
- case VKD3DSIH_DEFAULT:
+ case VSIR_OP_DEFAULT:
cf_info->u.switch_.default_block_id = cf_flattener_alloc_block_id(flattener);
if (cf_info->inside_block) /* fall-through */
cf_flattener_emit_unconditional_branch(flattener, cf_info->u.switch_.default_block_id);
@@ -3261,7 +4066,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
cf_info->inside_block = true;
break;
- case VKD3DSIH_BREAK:
+ case VSIR_OP_BREAK:
{
struct cf_flattener_info *breakable_cf_info;
@@ -3284,7 +4089,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
break;
}
- case VKD3DSIH_BREAKP:
+ case VSIR_OP_BREAKP:
{
struct cf_flattener_info *loop_cf_info;
@@ -3299,7 +4104,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
break;
}
- case VKD3DSIH_CONTINUE:
+ case VSIR_OP_CONTINUE:
{
struct cf_flattener_info *loop_cf_info;
@@ -3315,7 +4120,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
break;
}
- case VKD3DSIH_CONTINUEP:
+ case VSIR_OP_CONTINUEP:
{
struct cf_flattener_info *loop_cf_info;
@@ -3330,7 +4135,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
break;
}
- case VKD3DSIH_RET:
+ case VSIR_OP_RET:
if (!cf_flattener_copy_instruction(flattener, instruction))
return VKD3D_ERROR_OUT_OF_MEMORY;
@@ -3447,14 +4252,14 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs
switch (ins->opcode)
{
- case VKD3DSIH_LABEL:
+ case VSIR_OP_LABEL:
current_label = label_from_src_param(&ins->src[0]);
if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1))
goto fail;
instructions[ins_count++] = *ins;
continue;
- case VKD3DSIH_SWITCH_MONOLITHIC:
+ case VSIR_OP_SWITCH_MONOLITHIC:
break;
default:
@@ -3475,7 +4280,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs
goto fail;
if (!vsir_instruction_init_with_params(program, &instructions[ins_count],
- &ins->location, VKD3DSIH_BRANCH, 0, 1))
+ &ins->location, VSIR_OP_BRANCH, 0, 1))
goto fail;
vsir_src_param_init_label(&instructions[ins_count].src[0], default_label);
++ins_count;
@@ -3491,7 +4296,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs
unsigned int fallthrough_label, case_label = label_from_src_param(&ins->src[3 + 2 * j + 1]);
if (!vsir_instruction_init_with_params(program,
- &instructions[ins_count], &ins->location, VKD3DSIH_IEQ, 1, 2))
+ &instructions[ins_count], &ins->location, VSIR_OP_IEQ, 1, 2))
goto fail;
dst_param_init_ssa_bool(&instructions[ins_count].dst[0], ssa_count);
instructions[ins_count].src[0] = ins->src[0];
@@ -3507,7 +4312,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs
fallthrough_label = block_count + 1;
if (!vsir_instruction_init_with_params(program, &instructions[ins_count],
- &ins->location, VKD3DSIH_BRANCH, 0, 3))
+ &ins->location, VSIR_OP_BRANCH, 0, 3))
goto fail;
src_param_init_ssa_bool(&instructions[ins_count].src[0], ssa_count);
vsir_src_param_init_label(&instructions[ins_count].src[1], case_label);
@@ -3529,7 +4334,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs
else
{
if (!vsir_instruction_init_with_params(program,
- &instructions[ins_count], &ins->location, VKD3DSIH_LABEL, 0, 1))
+ &instructions[ins_count], &ins->location, VSIR_OP_LABEL, 0, 1))
goto fail;
vsir_src_param_init_label(&instructions[ins_count].src[0], ++block_count);
++ins_count;
@@ -3620,10 +4425,12 @@ static void ssas_to_temps_block_info_cleanup(struct ssas_to_temps_block_info *bl
static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_program *program,
struct vsir_transformation_context *ctx)
{
- size_t ins_capacity = 0, ins_count = 0, phi_count, incoming_count, i;
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
+ size_t ins_capacity = 0, ins_count = 0, phi_count, incoming_count;
struct ssas_to_temps_block_info *info, *block_info = NULL;
struct vkd3d_shader_instruction *instructions = NULL;
struct ssas_to_temps_alloc alloc = {0};
+ struct vkd3d_shader_instruction *ins;
unsigned int current_label = 0;
VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS);
@@ -3637,14 +4444,15 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
if (!ssas_to_temps_alloc_init(&alloc, program->ssa_count, program->temp_count))
goto fail;
- for (i = 0, phi_count = 0, incoming_count = 0; i < program->instructions.count; ++i)
+ phi_count = 0;
+ incoming_count = 0;
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
unsigned int j, temp_idx;
/* Only phi src/dst SSA values need be converted here. Structurisation may
* introduce new cases of undominated SSA use, which will be handled later. */
- if (ins->opcode != VKD3DSIH_PHI)
+ if (ins->opcode != VSIR_OP_PHI)
continue;
++phi_count;
@@ -3682,9 +4490,9 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
if (!reserve_instructions(&instructions, &ins_capacity, program->instructions.count + incoming_count - phi_count))
goto fail;
- for (i = 0; i < program->instructions.count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- struct vkd3d_shader_instruction *mov_ins, *ins = &program->instructions.elements[i];
+ struct vkd3d_shader_instruction *mov_ins;
size_t j;
for (j = 0; j < ins->dst_count; ++j)
@@ -3695,12 +4503,12 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
switch (ins->opcode)
{
- case VKD3DSIH_LABEL:
+ case VSIR_OP_LABEL:
current_label = label_from_src_param(&ins->src[0]);
break;
- case VKD3DSIH_BRANCH:
- case VKD3DSIH_SWITCH_MONOLITHIC:
+ case VSIR_OP_BRANCH:
+ case VSIR_OP_SWITCH_MONOLITHIC:
info = &block_info[current_label - 1];
for (j = 0; j < info->incoming_count; ++j)
@@ -3708,7 +4516,7 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
struct phi_incoming_to_temp *incoming = &info->incomings[j];
mov_ins = &instructions[ins_count++];
- if (!vsir_instruction_init_with_params(program, mov_ins, &ins->location, VKD3DSIH_MOV, 1, 0))
+ if (!vsir_instruction_init_with_params(program, mov_ins, &ins->location, VSIR_OP_MOV, 1, 0))
goto fail;
*mov_ins->dst = *incoming->dst;
mov_ins->src = incoming->src;
@@ -3716,7 +4524,7 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
}
break;
- case VKD3DSIH_PHI:
+ case VSIR_OP_PHI:
continue;
default:
@@ -3753,7 +4561,7 @@ struct vsir_block_list
static void vsir_block_list_init(struct vsir_block_list *list)
{
- memset(list, 0, sizeof(*list));
+ *list = (struct vsir_block_list){0};
}
static void vsir_block_list_cleanup(struct vsir_block_list *list)
@@ -4125,11 +4933,11 @@ static void vsir_cfg_dump_dot(struct vsir_cfg *cfg)
switch (block->end->opcode)
{
- case VKD3DSIH_RET:
+ case VSIR_OP_RET:
shape = "trapezium";
break;
- case VKD3DSIH_BRANCH:
+ case VSIR_OP_BRANCH:
shape = vsir_register_is_label(&block->end->src[0].reg) ? "ellipse" : "box";
break;
@@ -4267,11 +5075,11 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program
switch (instruction->opcode)
{
- case VKD3DSIH_PHI:
- case VKD3DSIH_SWITCH_MONOLITHIC:
+ case VSIR_OP_PHI:
+ case VSIR_OP_SWITCH_MONOLITHIC:
vkd3d_unreachable();
- case VKD3DSIH_LABEL:
+ case VSIR_OP_LABEL:
{
unsigned int label = label_from_src_param(&instruction->src[0]);
@@ -4288,16 +5096,16 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program
break;
}
- case VKD3DSIH_BRANCH:
- case VKD3DSIH_RET:
+ case VSIR_OP_BRANCH:
+ case VSIR_OP_RET:
VKD3D_ASSERT(current_block);
current_block->end = instruction;
current_block = NULL;
break;
- case VKD3DSIH_HS_CONTROL_POINT_PHASE:
- case VKD3DSIH_HS_FORK_PHASE:
- case VKD3DSIH_HS_JOIN_PHASE:
+ case VSIR_OP_HS_CONTROL_POINT_PHASE:
+ case VSIR_OP_HS_FORK_PHASE:
+ case VSIR_OP_HS_JOIN_PHASE:
VKD3D_ASSERT(!current_block);
finish = true;
break;
@@ -4322,10 +5130,10 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program
switch (block->end->opcode)
{
- case VKD3DSIH_RET:
+ case VSIR_OP_RET:
break;
- case VKD3DSIH_BRANCH:
+ case VSIR_OP_BRANCH:
if (vsir_register_is_label(&block->end->src[0].reg))
{
if ((ret = vsir_cfg_add_edge(cfg, block, &block->end->src[0])) < 0)
@@ -5004,7 +5812,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg)
/* Generate between zero and two jump instructions. */
switch (block->end->opcode)
{
- case VKD3DSIH_BRANCH:
+ case VSIR_OP_BRANCH:
{
struct vsir_cfg_edge_action action_true, action_false;
bool invert_condition = false;
@@ -5090,7 +5898,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg)
break;
}
- case VKD3DSIH_RET:
+ case VSIR_OP_RET:
if (!(structure = vsir_cfg_structure_list_append(stack[stack_depth - 1], STRUCTURE_TYPE_JUMP)))
goto fail;
structure->u.jump.type = JUMP_RET;
@@ -5584,7 +6392,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg,
if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VKD3DSIH_LOOP);
+ vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_LOOP);
if ((ret = vsir_cfg_structure_list_emit(cfg, &loop->body, loop->idx)) < 0)
return ret;
@@ -5592,7 +6400,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg,
if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 5))
return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VKD3DSIH_ENDLOOP);
+ vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_ENDLOOP);
/* Add a trampoline to implement multilevel jumping depending on the stored
* jump_target value. */
@@ -5607,7 +6415,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg,
const unsigned int inner_break_target = loop->idx << 1;
if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
- &no_loc, VKD3DSIH_IEQ, 1, 2))
+ &no_loc, VSIR_OP_IEQ, 1, 2))
return VKD3D_ERROR_OUT_OF_MEMORY;
dst_param_init_temp_bool(&target->instructions[target->ins_count].dst[0], target->temp_count);
@@ -5617,7 +6425,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg,
++target->ins_count;
if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
- &no_loc, VKD3DSIH_CONTINUEP, 0, 1))
+ &no_loc, VSIR_OP_CONTINUEP, 0, 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
src_param_init_temp_bool(&target->instructions[target->ins_count].src[0], target->temp_count);
@@ -5626,7 +6434,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg,
++target->temp_count;
if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
- &no_loc, VKD3DSIH_IEQ, 1, 2))
+ &no_loc, VSIR_OP_IEQ, 1, 2))
return VKD3D_ERROR_OUT_OF_MEMORY;
dst_param_init_temp_bool(&target->instructions[target->ins_count].dst[0], target->temp_count);
@@ -5636,7 +6444,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg,
++target->ins_count;
if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
- &no_loc, VKD3DSIH_BREAKP, 0, 1))
+ &no_loc, VSIR_OP_BREAKP, 0, 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
target->instructions[target->ins_count].flags |= VKD3D_SHADER_CONDITIONAL_OP_Z;
@@ -5660,7 +6468,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_selection(struct vsir_cfg
return VKD3D_ERROR_OUT_OF_MEMORY;
if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
- &no_loc, VKD3DSIH_IF, 0, 1))
+ &no_loc, VSIR_OP_IF, 0, 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
target->instructions[target->ins_count].src[0] = *selection->condition;
@@ -5678,7 +6486,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_selection(struct vsir_cfg
if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VKD3DSIH_ELSE);
+ vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_ELSE);
if ((ret = vsir_cfg_structure_list_emit(cfg, &selection->else_body, loop_idx)) < 0)
return ret;
@@ -5687,7 +6495,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_selection(struct vsir_cfg
if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VKD3DSIH_ENDIF);
+ vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_ENDIF);
return VKD3D_OK;
}
@@ -5711,19 +6519,19 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg,
* in the lowest bit of jump_target. */
if (jump->target == loop_idx)
{
- opcode = jump->condition ? VKD3DSIH_CONTINUEP : VKD3DSIH_CONTINUE;
+ opcode = jump->condition ? VSIR_OP_CONTINUEP : VSIR_OP_CONTINUE;
break;
}
jump_target |= 1;
/* fall through */
case JUMP_BREAK:
- opcode = jump->condition ? VKD3DSIH_BREAKP : VKD3DSIH_BREAK;
+ opcode = jump->condition ? VSIR_OP_BREAKP : VSIR_OP_BREAK;
break;
case JUMP_RET:
VKD3D_ASSERT(!jump->condition);
- opcode = VKD3DSIH_RET;
+ opcode = VSIR_OP_RET;
break;
default:
@@ -5736,7 +6544,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg,
if (jump->needs_launcher)
{
if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count],
- &no_loc, VKD3DSIH_MOV, 1, 1))
+ &no_loc, VSIR_OP_MOV, 1, 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
dst_param_init_temp_uint(&target->instructions[target->ins_count].dst[0], target->jump_target_temp_idx);
@@ -5864,7 +6672,7 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program,
switch (ins->opcode)
{
- case VKD3DSIH_LABEL:
+ case VSIR_OP_LABEL:
VKD3D_ASSERT(program->shader_version.type != VKD3D_SHADER_TYPE_HULL);
TRACE("Structurizing a non-hull shader.\n");
if ((ret = vsir_program_structurize_function(program, message_context,
@@ -5873,9 +6681,9 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program,
VKD3D_ASSERT(i == program->instructions.count);
break;
- case VKD3DSIH_HS_CONTROL_POINT_PHASE:
- case VKD3DSIH_HS_FORK_PHASE:
- case VKD3DSIH_HS_JOIN_PHASE:
+ case VSIR_OP_HS_CONTROL_POINT_PHASE:
+ case VSIR_OP_HS_FORK_PHASE:
+ case VSIR_OP_HS_JOIN_PHASE:
VKD3D_ASSERT(program->shader_version.type == VKD3D_SHADER_TYPE_HULL);
TRACE("Structurizing phase %u of a hull shader.\n", ins->opcode);
target.instructions[target.ins_count++] = *ins;
@@ -6041,7 +6849,7 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru
switch (ins->opcode)
{
- case VKD3DSIH_LABEL:
+ case VSIR_OP_LABEL:
VKD3D_ASSERT(program->shader_version.type != VKD3D_SHADER_TYPE_HULL);
TRACE("Materializing undominated SSAs in a non-hull shader.\n");
if ((ret = vsir_program_materialize_undominated_ssas_to_temps_in_function(
@@ -6050,9 +6858,9 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru
VKD3D_ASSERT(i == program->instructions.count);
break;
- case VKD3DSIH_HS_CONTROL_POINT_PHASE:
- case VKD3DSIH_HS_FORK_PHASE:
- case VKD3DSIH_HS_JOIN_PHASE:
+ case VSIR_OP_HS_CONTROL_POINT_PHASE:
+ case VSIR_OP_HS_FORK_PHASE:
+ case VSIR_OP_HS_JOIN_PHASE:
VKD3D_ASSERT(program->shader_version.type == VKD3D_SHADER_TYPE_HULL);
TRACE("Materializing undominated SSAs in phase %u of a hull shader.\n", ins->opcode);
++i;
@@ -6125,14 +6933,12 @@ static enum vkd3d_result vsir_program_apply_flat_interpolation(struct vsir_progr
}
static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *program,
- const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_comparison_func compare_func,
+ struct vsir_program_iterator *it, enum vkd3d_shader_comparison_func compare_func,
const struct vkd3d_shader_parameter1 *ref, uint32_t colour_signature_idx,
- uint32_t colour_temp, size_t *ret_pos, struct vkd3d_shader_message_context *message_context)
+ uint32_t colour_temp, struct vkd3d_shader_message_context *message_context)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
- const struct vkd3d_shader_location loc = ret->location;
+ struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location;
static const struct vkd3d_shader_location no_loc;
- size_t pos = ret - instructions->elements;
struct vkd3d_shader_instruction *ins;
static const struct
@@ -6143,33 +6949,33 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr
}
opcodes[] =
{
- [VKD3D_SHADER_COMPARISON_FUNC_EQUAL] = {VKD3DSIH_EQO, VKD3DSIH_IEQ},
- [VKD3D_SHADER_COMPARISON_FUNC_NOT_EQUAL] = {VKD3DSIH_NEO, VKD3DSIH_INE},
- [VKD3D_SHADER_COMPARISON_FUNC_GREATER_EQUAL] = {VKD3DSIH_GEO, VKD3DSIH_UGE},
- [VKD3D_SHADER_COMPARISON_FUNC_LESS] = {VKD3DSIH_LTO, VKD3DSIH_ULT},
- [VKD3D_SHADER_COMPARISON_FUNC_LESS_EQUAL] = {VKD3DSIH_GEO, VKD3DSIH_UGE, true},
- [VKD3D_SHADER_COMPARISON_FUNC_GREATER] = {VKD3DSIH_LTO, VKD3DSIH_ULT, true},
+ [VKD3D_SHADER_COMPARISON_FUNC_EQUAL] = {VSIR_OP_EQO, VSIR_OP_IEQ},
+ [VKD3D_SHADER_COMPARISON_FUNC_NOT_EQUAL] = {VSIR_OP_NEO, VSIR_OP_INE},
+ [VKD3D_SHADER_COMPARISON_FUNC_GREATER_EQUAL] = {VSIR_OP_GEO, VSIR_OP_UGE},
+ [VKD3D_SHADER_COMPARISON_FUNC_LESS] = {VSIR_OP_LTO, VSIR_OP_ULT},
+ [VKD3D_SHADER_COMPARISON_FUNC_LESS_EQUAL] = {VSIR_OP_GEO, VSIR_OP_UGE, true},
+ [VKD3D_SHADER_COMPARISON_FUNC_GREATER] = {VSIR_OP_LTO, VSIR_OP_ULT, true},
};
if (compare_func == VKD3D_SHADER_COMPARISON_FUNC_NEVER)
{
- if (!shader_instruction_array_insert_at(&program->instructions, pos, 1))
+ vsir_program_iterator_prev(it);
+ if (!vsir_program_iterator_insert_after(it, 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
- ret = NULL;
- ins = &program->instructions.elements[pos];
+ ins = vsir_program_iterator_next(it);
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_DISCARD, 0, 1);
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DISCARD, 0, 1);
ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z;
src_param_init_const_uint(&ins->src[0], 0);
+ vsir_program_iterator_next(it);
- *ret_pos = pos + 1;
return VKD3D_OK;
}
- if (!shader_instruction_array_insert_at(&program->instructions, pos, 3))
+ vsir_program_iterator_prev(it);
+ if (!vsir_program_iterator_insert_after(it, 3))
return VKD3D_ERROR_OUT_OF_MEMORY;
- ret = NULL;
- ins = &program->instructions.elements[pos];
+ ins = vsir_program_iterator_next(it);
switch (ref->data_type)
{
@@ -6177,14 +6983,14 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr
vsir_instruction_init_with_params(program, ins, &loc, opcodes[compare_func].float_opcode, 1, 2);
src_param_init_temp_float(&ins->src[opcodes[compare_func].swap ? 1 : 0], colour_temp);
src_param_init_parameter(&ins->src[opcodes[compare_func].swap ? 0 : 1],
- VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VKD3D_DATA_FLOAT);
+ VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VSIR_DATA_F32);
break;
case VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32:
vsir_instruction_init_with_params(program, ins, &loc, opcodes[compare_func].uint_opcode, 1, 2);
src_param_init_temp_uint(&ins->src[opcodes[compare_func].swap ? 1 : 0], colour_temp);
src_param_init_parameter(&ins->src[opcodes[compare_func].swap ? 0 : 1],
- VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VKD3D_DATA_UINT);
+ VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VSIR_DATA_U32);
break;
case VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4:
@@ -6201,16 +7007,16 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr
ins->src[opcodes[compare_func].swap ? 1 : 0].reg.dimension = VSIR_DIMENSION_VEC4;
ins->src[opcodes[compare_func].swap ? 1 : 0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W);
- ++ins;
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_DISCARD, 0, 1);
+ ins = vsir_program_iterator_next(it);
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DISCARD, 0, 1);
ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z;
src_param_init_ssa_bool(&ins->src[0], program->ssa_count);
++program->ssa_count;
- ++ins;
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1);
- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1);
+ ins = vsir_program_iterator_next(it);
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1);
+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VSIR_DATA_F32, 1);
ins->dst[0].reg.idx[0].offset = colour_signature_idx;
ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
ins->dst[0].write_mask = program->output_signature.elements[colour_signature_idx].mask;
@@ -6218,20 +7024,21 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
- *ret_pos = pos + 3;
+ vsir_program_iterator_next(it);
+
return VKD3D_OK;
}
static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *program,
struct vsir_transformation_context *ctx)
{
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
struct vkd3d_shader_message_context *message_context = ctx->message_context;
const struct vkd3d_shader_parameter1 *func = NULL, *ref = NULL;
uint32_t colour_signature_idx, colour_temp = ~0u;
static const struct vkd3d_shader_location no_loc;
enum vkd3d_shader_comparison_func compare_func;
struct vkd3d_shader_instruction *ins;
- size_t new_pos;
int ret;
if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL)
@@ -6268,19 +7075,16 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro
if (compare_func != VKD3D_SHADER_COMPARISON_FUNC_NEVER)
colour_temp = program->temp_count++;
- for (size_t i = 0; i < program->instructions.count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- ins = &program->instructions.elements[i];
-
if (vsir_instruction_is_dcl(ins))
continue;
- if (ins->opcode == VKD3DSIH_RET)
+ if (ins->opcode == VSIR_OP_RET)
{
- if ((ret = insert_alpha_test_before_ret(program, ins, compare_func,
- ref, colour_signature_idx, colour_temp, &new_pos, message_context)) < 0)
+ if ((ret = insert_alpha_test_before_ret(program, &it, compare_func,
+ ref, colour_signature_idx, colour_temp, message_context)) < 0)
return ret;
- i = new_pos;
continue;
}
@@ -6306,32 +7110,30 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro
}
static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *program,
- const struct vkd3d_shader_instruction *ret, uint32_t mask, uint32_t position_signature_idx,
- uint32_t position_temp, uint32_t low_signature_idx, uint32_t high_signature_idx, size_t *ret_pos)
+ struct vsir_program_iterator *it, uint32_t mask, uint32_t position_signature_idx,
+ uint32_t position_temp, uint32_t low_signature_idx, uint32_t high_signature_idx)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
- const struct vkd3d_shader_location loc = ret->location;
- size_t pos = ret - instructions->elements;
+ const struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location;
struct vkd3d_shader_instruction *ins;
unsigned int output_idx = 0;
- if (!shader_instruction_array_insert_at(&program->instructions, pos, vkd3d_popcount(mask) + 1))
+ vsir_program_iterator_prev(it);
+ if (!vsir_program_iterator_insert_after(it, vkd3d_popcount(mask) + 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
- ret = NULL;
- ins = &program->instructions.elements[pos];
+ ins = vsir_program_iterator_next(it);
for (unsigned int i = 0; i < 8; ++i)
{
if (!(mask & (1u << i)))
continue;
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_DP4, 1, 2);
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DP4, 1, 2);
src_param_init_temp_float4(&ins->src[0], position_temp);
- src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_CLIP_PLANE_0 + i, VKD3D_DATA_FLOAT);
+ src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_CLIP_PLANE_0 + i, VSIR_DATA_F32);
ins->src[1].swizzle = VKD3D_SHADER_NO_SWIZZLE;
ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1);
+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VSIR_DATA_F32, 1);
if (output_idx < 4)
ins->dst[0].reg.idx[0].offset = low_signature_idx;
else
@@ -6340,34 +7142,34 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog
ins->dst[0].write_mask = (1u << (output_idx % 4));
++output_idx;
- ++ins;
+ ins = vsir_program_iterator_next(it);
}
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1);
- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1);
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1);
+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VSIR_DATA_F32, 1);
ins->dst[0].reg.idx[0].offset = position_signature_idx;
ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
ins->dst[0].write_mask = program->output_signature.elements[position_signature_idx].mask;
src_param_init_temp_float(&ins->src[0], position_temp);
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
+ ins = vsir_program_iterator_next(it);
- *ret_pos = pos + vkd3d_popcount(mask) + 1;
return VKD3D_OK;
}
static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *program,
struct vsir_transformation_context *ctx)
{
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
struct shader_signature *signature = &program->output_signature;
unsigned int low_signature_idx = ~0u, high_signature_idx = ~0u;
const struct vkd3d_shader_parameter1 *mask_parameter = NULL;
- struct signature_element *new_elements, *clip_element;
uint32_t position_signature_idx, position_temp, mask;
static const struct vkd3d_shader_location no_loc;
+ struct signature_element *clip_element;
struct vkd3d_shader_instruction *ins;
unsigned int plane_count;
- size_t new_pos;
int ret;
if (program->shader_version.type != VKD3D_SHADER_TYPE_VERTEX)
@@ -6422,33 +7224,20 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr
plane_count = vkd3d_popcount(mask);
- if (!(new_elements = vkd3d_realloc(signature->elements,
- (signature->element_count + 2) * sizeof(*signature->elements))))
+ /* Register mask is ignored since we operate after I/O normalisation. */
+ if (!(clip_element = add_signature_element(signature, "SV_ClipDistance", 0,
+ vkd3d_write_mask_from_component_count(min(plane_count, 4)), 0, VKD3DSIM_NONE)))
return VKD3D_ERROR_OUT_OF_MEMORY;
- signature->elements = new_elements;
-
- low_signature_idx = signature->element_count;
- clip_element = &signature->elements[signature->element_count++];
- memset(clip_element, 0, sizeof(*clip_element));
+ low_signature_idx = clip_element - signature->elements;
clip_element->sysval_semantic = VKD3D_SHADER_SV_CLIP_DISTANCE;
- clip_element->component_type = VKD3D_SHADER_COMPONENT_FLOAT;
- clip_element->register_count = 1;
- clip_element->mask = vkd3d_write_mask_from_component_count(min(plane_count, 4));
- clip_element->used_mask = clip_element->mask;
- clip_element->min_precision = VKD3D_SHADER_MINIMUM_PRECISION_NONE;
if (plane_count > 4)
{
- high_signature_idx = signature->element_count;
- clip_element = &signature->elements[signature->element_count++];
- memset(clip_element, 0, sizeof(*clip_element));
+ if (!(clip_element = add_signature_element(signature, "SV_ClipDistance", 1,
+ vkd3d_write_mask_from_component_count(plane_count - 4), 0, VKD3DSIM_NONE)))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ high_signature_idx = clip_element - signature->elements;
clip_element->sysval_semantic = VKD3D_SHADER_SV_CLIP_DISTANCE;
- clip_element->semantic_index = 1;
- clip_element->component_type = VKD3D_SHADER_COMPONENT_FLOAT;
- clip_element->register_count = 1;
- clip_element->mask = vkd3d_write_mask_from_component_count(plane_count - 4);
- clip_element->used_mask = clip_element->mask;
- clip_element->min_precision = VKD3D_SHADER_MINIMUM_PRECISION_NONE;
}
/* We're going to be reading from the output position, so we need to go
@@ -6456,19 +7245,16 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr
position_temp = program->temp_count++;
- for (size_t i = 0; i < program->instructions.count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- ins = &program->instructions.elements[i];
-
if (vsir_instruction_is_dcl(ins))
continue;
- if (ins->opcode == VKD3DSIH_RET)
+ if (ins->opcode == VSIR_OP_RET)
{
- if ((ret = insert_clip_planes_before_ret(program, ins, mask, position_signature_idx,
- position_temp, low_signature_idx, high_signature_idx, &new_pos)) < 0)
+ if ((ret = insert_clip_planes_before_ret(program, &it, mask, position_signature_idx,
+ position_temp, low_signature_idx, high_signature_idx)) < 0)
return ret;
- i = new_pos;
continue;
}
@@ -6497,32 +7283,32 @@ static bool is_pre_rasterization_shader(enum vkd3d_shader_type type)
}
static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *program,
- const struct vkd3d_shader_instruction *ret, size_t *ret_pos)
+ struct vsir_program_iterator *it)
{
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
- const struct vkd3d_shader_location loc = ret->location;
- size_t pos = ret - instructions->elements;
+ const struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location;
struct vkd3d_shader_instruction *ins;
- if (!shader_instruction_array_insert_at(&program->instructions, pos, 1))
+ vsir_program_iterator_prev(it);
+ if (!vsir_program_iterator_insert_after(it, 1))
return VKD3D_ERROR_OUT_OF_MEMORY;
- ret = NULL;
- ins = &program->instructions.elements[pos];
+ ins = vsir_program_iterator_next(it);
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1);
- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1);
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1);
+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1);
ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE;
- src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE, VKD3D_DATA_FLOAT);
+ src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE, VSIR_DATA_F32);
+ ins = vsir_program_iterator_next(it);
- *ret_pos = pos + 1;
return VKD3D_OK;
}
static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *program,
struct vsir_transformation_context *ctx)
{
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
const struct vkd3d_shader_parameter1 *size_parameter = NULL;
static const struct vkd3d_shader_location no_loc;
+ struct vkd3d_shader_instruction *ins;
if (program->has_point_size)
return VKD3D_OK;
@@ -6551,18 +7337,14 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro
program->has_point_size = true;
/* Append a point size write before each ret. */
- for (size_t i = 0; i < program->instructions.count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
-
- if (ins->opcode == VKD3DSIH_RET)
+ if (ins->opcode == VSIR_OP_RET)
{
- size_t new_pos;
int ret;
- if ((ret = insert_point_size_before_ret(program, ins, &new_pos)) < 0)
+ if ((ret = insert_point_size_before_ret(program, &it)) < 0)
return ret;
- i = new_pos;
}
}
@@ -6573,7 +7355,9 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra
struct vsir_transformation_context *ctx)
{
const struct vkd3d_shader_parameter1 *min_parameter = NULL, *max_parameter = NULL;
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
static const struct vkd3d_shader_location no_loc;
+ struct vkd3d_shader_instruction *ins;
if (!program->has_point_size)
return VKD3D_OK;
@@ -6610,9 +7394,8 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra
/* Replace writes to the point size by inserting a clamp before each write. */
- for (size_t i = 0; i < program->instructions.count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
const struct vkd3d_shader_location *loc;
unsigned int ssa_value;
bool clamp = false;
@@ -6636,17 +7419,17 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra
if (!clamp)
continue;
- if (!shader_instruction_array_insert_at(&program->instructions, i + 1, !!min_parameter + !!max_parameter))
+ if (!vsir_program_iterator_insert_after(&it, !!min_parameter + !!max_parameter))
return VKD3D_ERROR_OUT_OF_MEMORY;
- ins = &program->instructions.elements[i + 1];
- loc = &program->instructions.elements[i].location;
+ loc = &vsir_program_iterator_current(&it)->location;
+ ins = vsir_program_iterator_next(&it);
if (min_parameter)
{
- vsir_instruction_init_with_params(program, ins, loc, VKD3DSIH_MAX, 1, 2);
+ vsir_instruction_init_with_params(program, ins, loc, VSIR_OP_MAX, 1, 2);
src_param_init_ssa_float(&ins->src[0], ssa_value);
- src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MIN, VKD3D_DATA_FLOAT);
+ src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MIN, VSIR_DATA_F32);
if (max_parameter)
{
dst_param_init_ssa_float(&ins->dst[0], program->ssa_count);
@@ -6654,22 +7437,20 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra
}
else
{
- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1);
+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1);
ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE;
}
- ++ins;
- ++i;
+ ins = vsir_program_iterator_next(&it);
}
if (max_parameter)
{
- vsir_instruction_init_with_params(program, ins, loc, VKD3DSIH_MIN, 1, 2);
+ vsir_instruction_init_with_params(program, ins, loc, VSIR_OP_MIN, 1, 2);
src_param_init_ssa_float(&ins->src[0], ssa_value);
- src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX, VKD3D_DATA_FLOAT);
- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1);
+ src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX, VSIR_DATA_F32);
+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1);
ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE;
-
- ++i;
+ ins = vsir_program_iterator_next(&it);
}
}
@@ -6747,12 +7528,13 @@ static bool replace_texcoord_with_point_coord(struct vsir_program *program,
static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *program,
struct vsir_transformation_context *ctx)
{
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions), it2;
const struct vkd3d_shader_parameter1 *sprite_parameter = NULL;
static const struct vkd3d_shader_location no_loc;
struct vkd3d_shader_instruction *ins;
bool used_texcoord = false;
unsigned int coord_temp;
- size_t i, insert_pos;
+ size_t i;
if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL)
return VKD3D_OK;
@@ -6793,21 +7575,16 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr
/* Construct the new temp after all LABEL, DCL, and NOP instructions.
* We need to skip NOP instructions because they might result from removed
* DCLs, and there could still be DCLs after NOPs. */
- for (i = 0; i < program->instructions.count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- ins = &program->instructions.elements[i];
-
- if (!vsir_instruction_is_dcl(ins) && ins->opcode != VKD3DSIH_LABEL && ins->opcode != VKD3DSIH_NOP)
+ if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP)
break;
}
- insert_pos = i;
-
+ it2 = it;
/* Replace each texcoord read with a read from the point coord. */
- for (; i < program->instructions.count; ++i)
+ for (; ins; ins = vsir_program_iterator_next(&it2))
{
- ins = &program->instructions.elements[i];
-
if (vsir_instruction_is_dcl(ins))
continue;
@@ -6836,24 +7613,25 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr
if (used_texcoord)
{
- if (!shader_instruction_array_insert_at(&program->instructions, insert_pos, 2))
+ vsir_program_iterator_prev(&it);
+ if (!vsir_program_iterator_insert_after(&it, 2))
return VKD3D_ERROR_OUT_OF_MEMORY;
- ins = &program->instructions.elements[insert_pos];
+ ins = vsir_program_iterator_next(&it);
- vsir_instruction_init_with_params(program, ins, &no_loc, VKD3DSIH_MOV, 1, 1);
+ vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1);
dst_param_init_temp_float4(&ins->dst[0], coord_temp);
ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1;
- vsir_src_param_init(&ins->src[0], VKD3DSPR_POINT_COORD, VKD3D_DATA_FLOAT, 0);
+ vsir_src_param_init(&ins->src[0], VKD3DSPR_POINT_COORD, VSIR_DATA_F32, 0);
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
- ++ins;
+ ins = vsir_program_iterator_next(&it);
- vsir_instruction_init_with_params(program, ins, &no_loc, VKD3DSIH_MOV, 1, 1);
+ vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1);
dst_param_init_temp_float4(&ins->dst[0], coord_temp);
ins->dst[0].write_mask = VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3;
- vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0);
+ vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0);
ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
- ++ins;
+ vsir_program_iterator_next(&it);
program->has_point_coord = true;
}
@@ -6919,20 +7697,20 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro
ins = &program->instructions.elements[pos];
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_ADD, 1, 2);
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2);
dst_param_init_ssa_float(&ins->dst[0], ssa_temp);
- src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_END, VKD3D_DATA_FLOAT);
- vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 1);
+ src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_END, VSIR_DATA_F32);
+ vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VSIR_DATA_F32, 1);
ins->src[1].reg.idx[0].offset = fog_signature_idx;
ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
ins->src[1].modifiers = VKD3DSPSM_NEG;
- vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_MUL, 1, 2);
+ vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MUL, 1, 2);
dst_param_init_ssa_float(&ins->dst[0], ssa_factor);
ins->dst[0].modifiers = VKD3DSPDM_SATURATE;
src_param_init_ssa_float(&ins->src[0], ssa_temp);
- src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VKD3D_DATA_FLOAT);
+ src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32);
break;
case VKD3D_SHADER_FOG_FRAGMENT_EXP:
@@ -6951,15 +7729,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro
ins = &program->instructions.elements[pos];
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MUL, 1, 2);
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2);
dst_param_init_ssa_float(&ins->dst[0], ssa_temp);
- src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VKD3D_DATA_FLOAT);
- vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 1);
+ src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32);
+ vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VSIR_DATA_F32, 1);
ins->src[1].reg.idx[0].offset = fog_signature_idx;
ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
- vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_EXP, 1, 1);
+ vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_EXP, 1, 1);
dst_param_init_ssa_float(&ins->dst[0], ssa_factor);
ins->dst[0].modifiers = VKD3DSPDM_SATURATE;
src_param_init_ssa_float(&ins->src[0], ssa_temp);
@@ -6984,20 +7762,20 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro
ins = &program->instructions.elements[pos];
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MUL, 1, 2);
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2);
dst_param_init_ssa_float(&ins->dst[0], ssa_temp);
- src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VKD3D_DATA_FLOAT);
- vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 1);
+ src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32);
+ vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VSIR_DATA_F32, 1);
ins->src[1].reg.idx[0].offset = fog_signature_idx;
ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
- vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_MUL, 1, 2);
+ vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MUL, 1, 2);
dst_param_init_ssa_float(&ins->dst[0], ssa_temp2);
src_param_init_ssa_float(&ins->src[0], ssa_temp);
src_param_init_ssa_float(&ins->src[1], ssa_temp);
- vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_EXP, 1, 1);
+ vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_EXP, 1, 1);
dst_param_init_ssa_float(&ins->dst[0], ssa_factor);
ins->dst[0].modifiers = VKD3DSPDM_SATURATE;
src_param_init_ssa_float(&ins->src[0], ssa_temp2);
@@ -7014,18 +7792,18 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro
* mad oC0, sr0, srFACTOR, FOG_COLOUR
*/
- vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_ADD, 1, 2);
+ vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_ADD, 1, 2);
dst_param_init_ssa_float4(&ins->dst[0], program->ssa_count++);
src_param_init_temp_float4(&ins->src[0], colour_temp);
- src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VKD3D_DATA_FLOAT);
+ src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32);
ins->src[1].modifiers = VKD3DSPSM_NEG;
- vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_MAD, 1, 3);
- dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, colour_signature_idx,
+ vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MAD, 1, 3);
+ dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, colour_signature_idx,
program->output_signature.elements[colour_signature_idx].mask);
src_param_init_ssa_float4(&ins->src[0], program->ssa_count - 1);
src_param_init_ssa_float(&ins->src[1], ssa_factor);
- src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VKD3D_DATA_FLOAT);
+ src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32);
return VKD3D_OK;
}
@@ -7088,200 +7866,1096 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p
if (vsir_instruction_is_dcl(ins))
continue;
- if (ins->opcode == VKD3DSIH_RET)
+ if (ins->opcode == VSIR_OP_RET)
+ {
+ if ((ret = insert_fragment_fog_before_ret(program, ins, mode, fog_signature_idx,
+ colour_signature_idx, colour_temp, &new_pos, message_context)) < 0)
+ return ret;
+ i = new_pos;
+ continue;
+ }
+
+ for (size_t j = 0; j < ins->dst_count; ++j)
+ {
+ struct vkd3d_shader_dst_param *dst = &ins->dst[j];
+
+ /* Note we run after I/O normalization. */
+ if (dst->reg.type == VKD3DSPR_OUTPUT && dst->reg.idx[0].offset == colour_signature_idx)
+ {
+ dst->reg.type = VKD3DSPR_TEMP;
+ dst->reg.idx[0].offset = colour_temp;
+ }
+ }
+ }
+
+ return VKD3D_OK;
+}
+
+static enum vkd3d_result vsir_program_add_fog_output(struct vsir_program *program,
+ struct vsir_transformation_context *ctx)
+{
+ struct shader_signature *signature = &program->output_signature;
+ const struct vkd3d_shader_parameter1 *source_parameter;
+ uint32_t register_idx = 0;
+
+ if (!is_pre_rasterization_shader(program->shader_version.type))
+ return VKD3D_OK;
+
+ if (!(source_parameter = vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_FOG_SOURCE)))
+ return VKD3D_OK;
+
+ if (source_parameter->type == VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT)
+ {
+ enum vkd3d_shader_fog_source source = source_parameter->u.immediate_constant.u.u32;
+
+ if (source == VKD3D_SHADER_FOG_SOURCE_FOG)
+ return VKD3D_OK;
+
+ if (source == VKD3D_SHADER_FOG_SOURCE_FOG_OR_SPECULAR_W
+ && !vsir_signature_find_element_by_name(signature, "COLOR", 1))
+ return VKD3D_OK;
+ }
+
+ if (vsir_signature_find_element_by_name(signature, "FOG", 0))
+ return VKD3D_OK;
+
+ for (unsigned int i = 0; i < signature->element_count; ++i)
+ register_idx = max(register_idx, signature->elements[i].register_index + 1);
+
+ if (!add_signature_element(signature, "FOG", 0, VKD3DSP_WRITEMASK_0, register_idx, VKD3DSIM_LINEAR))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ return VKD3D_OK;
+}
+
+static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *program,
+ const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_fog_source source, uint32_t temp,
+ uint32_t fog_signature_idx, uint32_t source_signature_idx, size_t *ret_pos)
+{
+ const struct signature_element *e = &program->output_signature.elements[source_signature_idx];
+ struct vkd3d_shader_instruction_array *instructions = &program->instructions;
+ const struct vkd3d_shader_location loc = ret->location;
+ size_t pos = ret - instructions->elements;
+ struct vkd3d_shader_instruction *ins;
+
+ if (!shader_instruction_array_insert_at(&program->instructions, pos, 2))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ ret = NULL;
+
+ ins = &program->instructions.elements[pos];
+
+ /* Write the fog output. */
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1);
+ dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, fog_signature_idx, 0x1);
+ src_param_init_temp_float4(&ins->src[0], temp);
+ if (source == VKD3D_SHADER_FOG_SOURCE_Z)
+ ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z);
+ else /* Position or specular W. */
+ ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W);
+ ++ins;
+
+ /* Write the position or specular output. */
+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1);
+ dst_param_init_output(&ins->dst[0], vsir_data_type_from_component_type(e->component_type),
+ source_signature_idx, e->mask);
+ src_param_init_temp_float4(&ins->src[0], temp);
+ ++ins;
+
+ *ret_pos = pos + 2;
+ return VKD3D_OK;
+}
+
+static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *program,
+ struct vsir_transformation_context *ctx)
+{
+ struct vkd3d_shader_message_context *message_context = ctx->message_context;
+ const struct vkd3d_shader_parameter1 *source_parameter = NULL;
+ uint32_t fog_signature_idx, source_signature_idx, temp;
+ static const struct vkd3d_shader_location no_loc;
+ enum vkd3d_shader_fog_source source;
+ const struct signature_element *e;
+
+ if (!is_pre_rasterization_shader(program->shader_version.type))
+ return VKD3D_OK;
+
+ if (!(source_parameter = vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_FOG_SOURCE)))
+ return VKD3D_OK;
+
+ if (source_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT)
+ {
+ vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
+ "Unsupported fog source parameter type %#x.", source_parameter->type);
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
+ }
+ if (source_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32)
+ {
+ vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Invalid fog source parameter data type %#x.", source_parameter->data_type);
+ return VKD3D_ERROR_INVALID_ARGUMENT;
+ }
+ source = source_parameter->u.immediate_constant.u.u32;
+
+ TRACE("Fog source %#x.\n", source);
+
+ if (source == VKD3D_SHADER_FOG_SOURCE_FOG)
+ return VKD3D_OK;
+
+ if (source == VKD3D_SHADER_FOG_SOURCE_FOG_OR_SPECULAR_W)
+ {
+ if (program->has_fog || !(e = vsir_signature_find_element_by_name(&program->output_signature, "COLOR", 1)))
+ return VKD3D_OK;
+ source_signature_idx = e - program->output_signature.elements;
+ }
+ else
+ {
+ if (!vsir_signature_find_sysval(&program->output_signature,
+ VKD3D_SHADER_SV_POSITION, 0, &source_signature_idx))
+ {
+ vkd3d_shader_error(ctx->message_context, &no_loc,
+ VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC, "Shader does not write position.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ }
+
+ if (!(e = vsir_signature_find_element_by_name(&program->output_signature, "FOG", 0)))
+ {
+ ERR("Fog output not found.\n");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ fog_signature_idx = e - program->output_signature.elements;
+
+ temp = program->temp_count++;
+
+ /* Insert a fog write before each ret, and convert either specular or
+ * position output to a temp. */
+ for (size_t i = 0; i < program->instructions.count; ++i)
+ {
+ struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
+
+ if (vsir_instruction_is_dcl(ins))
+ continue;
+
+ if (ins->opcode == VSIR_OP_RET)
+ {
+ size_t new_pos;
+ int ret;
+
+ if ((ret = insert_vertex_fog_before_ret(program, ins, source, temp,
+ fog_signature_idx, source_signature_idx, &new_pos)) < 0)
+ return ret;
+ i = new_pos;
+ continue;
+ }
+
+ for (size_t j = 0; j < ins->dst_count; ++j)
+ {
+ struct vkd3d_shader_dst_param *dst = &ins->dst[j];
+
+ /* Note we run after I/O normalization. */
+ if (dst->reg.type == VKD3DSPR_OUTPUT && dst->reg.idx[0].offset == source_signature_idx)
+ {
+ dst->reg.type = VKD3DSPR_TEMP;
+ dst->reg.idx[0].offset = temp;
+ }
+ }
+ }
+
+ program->has_fog = true;
+
+ return VKD3D_OK;
+}
+
+
+/* Distinguishes between instruction sources which are masked, where the used
+ * components of the source are determined by the write mask, and sources which
+ * are not masked, where the used components are pre-defined.
+ *
+ * E.g. "add r0.yz, r1.xyzw, r2.xyzw" uses the .yz components of r1 and r2, and
+ * therefore those sources are considered "masked", but
+ * "dp3 r0.y, r1.xyzw, r2.xyzw" uses the .xyz components. */
+static bool vsir_src_is_masked(enum vkd3d_shader_opcode opcode, unsigned int src_idx)
+{
+ switch (opcode)
+ {
+ case VSIR_OP_ABS:
+ case VSIR_OP_ACOS:
+ case VSIR_OP_ADD:
+ case VSIR_OP_AND:
+ case VSIR_OP_ASIN:
+ case VSIR_OP_ATAN:
+ case VSIR_OP_BFI:
+ case VSIR_OP_BFREV:
+ case VSIR_OP_CMP:
+ case VSIR_OP_CND:
+ case VSIR_OP_COS:
+ case VSIR_OP_COUNTBITS:
+ case VSIR_OP_DADD: /* NB: These are masked, but the mask is double-sized. */
+ case VSIR_OP_DDIV:
+ case VSIR_OP_DFMA:
+ case VSIR_OP_DIV:
+ case VSIR_OP_DMAX:
+ case VSIR_OP_DMIN:
+ case VSIR_OP_DMOV:
+ case VSIR_OP_DMOVC:
+ case VSIR_OP_DMUL:
+ case VSIR_OP_DRCP:
+ case VSIR_OP_DSX:
+ case VSIR_OP_DSX_COARSE:
+ case VSIR_OP_DSX_FINE:
+ case VSIR_OP_DSY:
+ case VSIR_OP_DSY_COARSE:
+ case VSIR_OP_DSY_FINE:
+ case VSIR_OP_EQO:
+ case VSIR_OP_EQU:
+ case VSIR_OP_EXP:
+ case VSIR_OP_EXPP:
+ case VSIR_OP_F16TOF32:
+ case VSIR_OP_F32TOF16:
+ case VSIR_OP_FIRSTBIT_HI:
+ case VSIR_OP_FIRSTBIT_LO:
+ case VSIR_OP_FIRSTBIT_SHI:
+ case VSIR_OP_FRC:
+ case VSIR_OP_FREM:
+ case VSIR_OP_FTOD:
+ case VSIR_OP_FTOI:
+ case VSIR_OP_FTOU:
+ case VSIR_OP_GEO:
+ case VSIR_OP_GEU:
+ case VSIR_OP_HCOS:
+ case VSIR_OP_HSIN:
+ case VSIR_OP_HTAN:
+ case VSIR_OP_IADD:
+ case VSIR_OP_IBFE:
+ case VSIR_OP_IDIV:
+ case VSIR_OP_IEQ:
+ case VSIR_OP_IGE:
+ case VSIR_OP_ILT:
+ case VSIR_OP_IMAD:
+ case VSIR_OP_IMAX:
+ case VSIR_OP_IMIN:
+ case VSIR_OP_IMUL:
+ case VSIR_OP_IMUL_LOW:
+ case VSIR_OP_INE:
+ case VSIR_OP_INEG:
+ case VSIR_OP_IREM:
+ case VSIR_OP_ISFINITE:
+ case VSIR_OP_ISHL:
+ case VSIR_OP_ISHR:
+ case VSIR_OP_ISINF:
+ case VSIR_OP_ISNAN:
+ case VSIR_OP_ITOD:
+ case VSIR_OP_ITOF:
+ case VSIR_OP_ITOI:
+ case VSIR_OP_LOG:
+ case VSIR_OP_LOGP:
+ case VSIR_OP_LRP:
+ case VSIR_OP_LTO:
+ case VSIR_OP_LTU:
+ case VSIR_OP_MAD:
+ case VSIR_OP_MAX:
+ case VSIR_OP_MIN:
+ case VSIR_OP_MOV:
+ case VSIR_OP_MOVA:
+ case VSIR_OP_MOVC:
+ case VSIR_OP_MSAD: /* FIXME: Is this correct? */
+ case VSIR_OP_MUL:
+ case VSIR_OP_NEO:
+ case VSIR_OP_NEU:
+ case VSIR_OP_NOT:
+ case VSIR_OP_OR:
+ case VSIR_OP_ORD:
+ case VSIR_OP_PHI:
+ case VSIR_OP_POW:
+ case VSIR_OP_QUAD_READ_ACROSS_D:
+ case VSIR_OP_QUAD_READ_ACROSS_X:
+ case VSIR_OP_QUAD_READ_ACROSS_Y:
+ case VSIR_OP_RCP:
+ case VSIR_OP_ROUND_NE:
+ case VSIR_OP_ROUND_NI:
+ case VSIR_OP_ROUND_PI:
+ case VSIR_OP_ROUND_Z:
+ case VSIR_OP_RSQ:
+ case VSIR_OP_SETP:
+ case VSIR_OP_SGE:
+ case VSIR_OP_SGN:
+ case VSIR_OP_SIN:
+ case VSIR_OP_SINCOS: /* FIXME: Only for sm4. */
+ case VSIR_OP_SLT:
+ case VSIR_OP_SQRT:
+ case VSIR_OP_SUB:
+ case VSIR_OP_SWAPC:
+ case VSIR_OP_TAN:
+ case VSIR_OP_UBFE:
+ case VSIR_OP_UDIV:
+ case VSIR_OP_UDIV_SIMPLE:
+ case VSIR_OP_UGE:
+ case VSIR_OP_ULT:
+ case VSIR_OP_UMAX:
+ case VSIR_OP_UMIN:
+ case VSIR_OP_UMUL:
+ case VSIR_OP_UNO:
+ case VSIR_OP_UREM:
+ case VSIR_OP_USHR:
+ case VSIR_OP_UTOD:
+ case VSIR_OP_UTOF:
+ case VSIR_OP_UTOU:
+ case VSIR_OP_WAVE_ACTIVE_ALL_EQUAL:
+ case VSIR_OP_WAVE_ACTIVE_BIT_AND:
+ case VSIR_OP_WAVE_ACTIVE_BIT_OR:
+ case VSIR_OP_WAVE_ACTIVE_BIT_XOR:
+ case VSIR_OP_WAVE_ALL_TRUE:
+ case VSIR_OP_WAVE_ANY_TRUE:
+ case VSIR_OP_WAVE_OP_ADD:
+ case VSIR_OP_WAVE_OP_IMAX:
+ case VSIR_OP_WAVE_OP_IMIN:
+ case VSIR_OP_WAVE_OP_MAX:
+ case VSIR_OP_WAVE_OP_MIN:
+ case VSIR_OP_WAVE_OP_MUL:
+ case VSIR_OP_WAVE_OP_UMAX:
+ case VSIR_OP_WAVE_OP_UMIN:
+ case VSIR_OP_WAVE_READ_LANE_FIRST:
+ case VSIR_OP_XOR:
+ return true;
+
+ /* Atomics can't have a writemask. */
+ case VSIR_OP_ATOMIC_AND:
+ case VSIR_OP_ATOMIC_CMP_STORE:
+ case VSIR_OP_ATOMIC_IADD:
+ case VSIR_OP_ATOMIC_IMAX:
+ case VSIR_OP_ATOMIC_IMIN:
+ case VSIR_OP_ATOMIC_OR:
+ case VSIR_OP_ATOMIC_UMAX:
+ case VSIR_OP_ATOMIC_UMIN:
+ case VSIR_OP_ATOMIC_XOR:
+ case VSIR_OP_BEM:
+ case VSIR_OP_BRANCH:
+ case VSIR_OP_BREAK:
+ case VSIR_OP_BREAKC:
+ case VSIR_OP_BREAKP:
+ case VSIR_OP_BUFINFO:
+ case VSIR_OP_CALL:
+ case VSIR_OP_CALLNZ:
+ case VSIR_OP_CASE:
+ case VSIR_OP_CHECK_ACCESS_FULLY_MAPPED: /* FIXME: Is this correct? */
+ case VSIR_OP_CONTINUE:
+ case VSIR_OP_CONTINUEP:
+ case VSIR_OP_CRS:
+ case VSIR_OP_CUT:
+ case VSIR_OP_CUT_STREAM:
+ case VSIR_OP_DCL:
+ case VSIR_OP_DCL_CONSTANT_BUFFER:
+ case VSIR_OP_DCL_FUNCTION_BODY:
+ case VSIR_OP_DCL_FUNCTION_TABLE:
+ case VSIR_OP_DCL_GLOBAL_FLAGS:
+ case VSIR_OP_DCL_GS_INSTANCES:
+ case VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT:
+ case VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT:
+ case VSIR_OP_DCL_HS_MAX_TESSFACTOR:
+ case VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER:
+ case VSIR_OP_DCL_INDEXABLE_TEMP:
+ case VSIR_OP_DCL_INDEX_RANGE:
+ case VSIR_OP_DCL_INPUT:
+ case VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT:
+ case VSIR_OP_DCL_INPUT_PRIMITIVE:
+ case VSIR_OP_DCL_INPUT_PS:
+ case VSIR_OP_DCL_INPUT_PS_SGV:
+ case VSIR_OP_DCL_INPUT_PS_SIV:
+ case VSIR_OP_DCL_INPUT_SGV:
+ case VSIR_OP_DCL_INPUT_SIV:
+ case VSIR_OP_DCL_INTERFACE:
+ case VSIR_OP_DCL_OUTPUT:
+ case VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT:
+ case VSIR_OP_DCL_OUTPUT_SGV:
+ case VSIR_OP_DCL_OUTPUT_SIV:
+ case VSIR_OP_DCL_OUTPUT_TOPOLOGY:
+ case VSIR_OP_DCL_RESOURCE_RAW:
+ case VSIR_OP_DCL_RESOURCE_STRUCTURED:
+ case VSIR_OP_DCL_SAMPLER:
+ case VSIR_OP_DCL_STREAM:
+ case VSIR_OP_DCL_TEMPS:
+ case VSIR_OP_DCL_TESSELLATOR_DOMAIN:
+ case VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE:
+ case VSIR_OP_DCL_TESSELLATOR_PARTITIONING:
+ case VSIR_OP_DCL_TGSM_RAW:
+ case VSIR_OP_DCL_TGSM_STRUCTURED:
+ case VSIR_OP_DCL_THREAD_GROUP:
+ case VSIR_OP_DCL_UAV_RAW:
+ case VSIR_OP_DCL_UAV_STRUCTURED:
+ case VSIR_OP_DCL_UAV_TYPED:
+ case VSIR_OP_DCL_VERTICES_OUT:
+ case VSIR_OP_DEF:
+ case VSIR_OP_DEFAULT:
+ case VSIR_OP_DEFB:
+ case VSIR_OP_DEFI:
+ case VSIR_OP_DEQO:
+ case VSIR_OP_DGEO:
+ case VSIR_OP_DISCARD:
+ case VSIR_OP_DLT:
+ case VSIR_OP_DNE:
+ case VSIR_OP_DP2:
+ case VSIR_OP_DP2ADD:
+ case VSIR_OP_DP3:
+ case VSIR_OP_DP4:
+ case VSIR_OP_DST:
+ case VSIR_OP_DTOF:
+ case VSIR_OP_DTOI:
+ case VSIR_OP_DTOU:
+ case VSIR_OP_ELSE:
+ case VSIR_OP_EMIT:
+ case VSIR_OP_EMIT_STREAM:
+ case VSIR_OP_ENDIF:
+ case VSIR_OP_ENDLOOP:
+ case VSIR_OP_ENDREP:
+ case VSIR_OP_ENDSWITCH:
+ case VSIR_OP_FCALL:
+ case VSIR_OP_HS_CONTROL_POINT_PHASE:
+ case VSIR_OP_HS_DECLS:
+ case VSIR_OP_HS_FORK_PHASE:
+ case VSIR_OP_HS_JOIN_PHASE:
+ case VSIR_OP_IF:
+ case VSIR_OP_IFC:
+ /* It's unclear if any mapping is done for the source value.
+ * Does it require replicate swizzle? */
+ case VSIR_OP_IMM_ATOMIC_ALLOC:
+ case VSIR_OP_IMM_ATOMIC_AND:
+ case VSIR_OP_IMM_ATOMIC_CMP_EXCH:
+ case VSIR_OP_IMM_ATOMIC_CONSUME:
+ case VSIR_OP_IMM_ATOMIC_EXCH:
+ case VSIR_OP_IMM_ATOMIC_IADD:
+ case VSIR_OP_IMM_ATOMIC_IMAX:
+ case VSIR_OP_IMM_ATOMIC_IMIN:
+ case VSIR_OP_IMM_ATOMIC_OR:
+ case VSIR_OP_IMM_ATOMIC_UMAX:
+ case VSIR_OP_IMM_ATOMIC_UMIN:
+ case VSIR_OP_IMM_ATOMIC_XOR:
+ case VSIR_OP_LABEL:
+ case VSIR_OP_LOOP:
+ case VSIR_OP_LIT:
+ case VSIR_OP_M3x2:
+ case VSIR_OP_M3x3:
+ case VSIR_OP_M3x4:
+ case VSIR_OP_M4x3:
+ case VSIR_OP_M4x4:
+ case VSIR_OP_NOP:
+ /* NRM writemask must be .xyz or .xyzw. */
+ case VSIR_OP_NRM:
+ case VSIR_OP_PHASE:
+ case VSIR_OP_REP:
+ case VSIR_OP_RET:
+ case VSIR_OP_RETP:
+ /* Store instructions always require a trivial writemask. */
+ case VSIR_OP_STORE_RAW:
+ case VSIR_OP_STORE_STRUCTURED:
+ case VSIR_OP_STORE_UAV_TYPED:
+ case VSIR_OP_SWITCH:
+ case VSIR_OP_SWITCH_MONOLITHIC:
+ case VSIR_OP_SYNC:
+ case VSIR_OP_TEX:
+ case VSIR_OP_TEXBEM:
+ case VSIR_OP_TEXBEML:
+ case VSIR_OP_TEXCOORD:
+ case VSIR_OP_TEXCRD:
+ case VSIR_OP_TEXDEPTH:
+ case VSIR_OP_TEXDP3:
+ case VSIR_OP_TEXDP3TEX:
+ case VSIR_OP_TEXKILL:
+ case VSIR_OP_TEXLD:
+ case VSIR_OP_TEXLDD:
+ case VSIR_OP_TEXLDL:
+ case VSIR_OP_TEXM3x2DEPTH:
+ case VSIR_OP_TEXM3x2PAD:
+ case VSIR_OP_TEXM3x2TEX:
+ case VSIR_OP_TEXM3x3:
+ case VSIR_OP_TEXM3x3DIFF:
+ case VSIR_OP_TEXM3x3PAD:
+ case VSIR_OP_TEXM3x3SPEC:
+ case VSIR_OP_TEXM3x3TEX:
+ case VSIR_OP_TEXM3x3VSPEC:
+ case VSIR_OP_TEXREG2AR:
+ case VSIR_OP_TEXREG2GB:
+ case VSIR_OP_TEXREG2RGB:
+ case VSIR_OP_WAVE_ACTIVE_BALLOT:
+ case VSIR_OP_WAVE_ALL_BIT_COUNT:
+ case VSIR_OP_WAVE_IS_FIRST_LANE:
+ case VSIR_OP_WAVE_PREFIX_BIT_COUNT:
+ return false;
+
+ case VSIR_OP_QUAD_READ_LANE_AT:
+ case VSIR_OP_WAVE_READ_LANE_AT:
+ return (src_idx == 0);
+
+ /* sm4 resource instructions are an odd case, since they're not actually
+ * per-component. However, the "swizzle" placed on the resource allows
+ * arbitrary destination writemasks to be used.
+ *
+ * This means that for the purposes of the "remapping" done by
+ * temp_allocator_set_dst(), we can basically treat those sources as
+ * "mapped", altering them when we reassign the destination writemask. */
+
+ /* FIXME: The documentation seems to say that these instructions behave
+ * this way, but is it correct?
+ * (It's silent about EVAL_*, but presumably they behave the same way.) */
+ case VSIR_OP_EVAL_CENTROID:
+ case VSIR_OP_EVAL_SAMPLE_INDEX:
+ case VSIR_OP_SAMPLE_INFO:
+ case VSIR_OP_SAMPLE_POS:
+ return (src_idx == 0);
+ case VSIR_OP_GATHER4:
+ case VSIR_OP_GATHER4_C:
+ case VSIR_OP_GATHER4_C_S:
+ case VSIR_OP_GATHER4_S:
+ case VSIR_OP_LD:
+ case VSIR_OP_LD2DMS:
+ case VSIR_OP_LD2DMS_S:
+ case VSIR_OP_LD_RAW:
+ case VSIR_OP_LD_RAW_S:
+ case VSIR_OP_LD_S:
+ case VSIR_OP_LD_UAV_TYPED:
+ case VSIR_OP_LD_UAV_TYPED_S:
+ case VSIR_OP_LOD:
+ case VSIR_OP_RESINFO:
+ case VSIR_OP_SAMPLE:
+ case VSIR_OP_SAMPLE_B:
+ case VSIR_OP_SAMPLE_B_CL_S:
+ case VSIR_OP_SAMPLE_C:
+ case VSIR_OP_SAMPLE_CL_S:
+ case VSIR_OP_SAMPLE_C_CL_S:
+ case VSIR_OP_SAMPLE_C_LZ:
+ case VSIR_OP_SAMPLE_C_LZ_S:
+ case VSIR_OP_SAMPLE_GRAD:
+ case VSIR_OP_SAMPLE_GRAD_CL_S:
+ case VSIR_OP_SAMPLE_LOD:
+ case VSIR_OP_SAMPLE_LOD_S:
+ return (src_idx == 1);
+ case VSIR_OP_GATHER4_PO:
+ case VSIR_OP_GATHER4_PO_C:
+ case VSIR_OP_GATHER4_PO_C_S:
+ case VSIR_OP_GATHER4_PO_S:
+ case VSIR_OP_LD_STRUCTURED:
+ case VSIR_OP_LD_STRUCTURED_S:
+ return (src_idx == 2);
+
+ case VSIR_OP_INVALID:
+ case VSIR_OP_COUNT:
+ break;
+ }
+
+ vkd3d_unreachable();
+}
+
+struct liveness_tracker
+{
+ struct liveness_tracker_reg
+ {
+ bool written;
+ bool fixed_mask;
+ uint8_t mask;
+ unsigned int first_write, last_access;
+ } *ssa_regs;
+};
+
+static void liveness_track_src(struct liveness_tracker *tracker,
+ struct vkd3d_shader_src_param *src, unsigned int index)
+{
+ for (unsigned int k = 0; k < src->reg.idx_count; ++k)
+ {
+ if (src->reg.idx[k].rel_addr)
+ liveness_track_src(tracker, src->reg.idx[k].rel_addr, index);
+ }
+
+ if (src->reg.type == VKD3DSPR_SSA)
+ tracker->ssa_regs[src->reg.idx[0].offset].last_access = index;
+}
+
+static void liveness_track_dst(struct liveness_tracker *tracker, struct vkd3d_shader_dst_param *dst,
+ unsigned int index, const struct vkd3d_shader_version *version, enum vkd3d_shader_opcode opcode)
+{
+ struct liveness_tracker_reg *reg;
+
+ for (unsigned int k = 0; k < dst->reg.idx_count; ++k)
+ {
+ if (dst->reg.idx[k].rel_addr)
+ liveness_track_src(tracker, dst->reg.idx[k].rel_addr, index);
+ }
+
+ if (dst->reg.type == VKD3DSPR_SSA)
+ reg = &tracker->ssa_regs[dst->reg.idx[0].offset];
+ else
+ return;
+
+ if (!reg->written)
+ reg->first_write = index;
+ reg->last_access = index;
+ reg->written = true;
+ reg->mask |= dst->write_mask;
+
+ switch (opcode)
+ {
+ case VSIR_OP_BEM:
+ case VSIR_OP_CRS:
+ case VSIR_OP_DST:
+ case VSIR_OP_LIT:
+ case VSIR_OP_M3x2:
+ case VSIR_OP_M3x3:
+ case VSIR_OP_M3x4:
+ case VSIR_OP_M4x3:
+ case VSIR_OP_M4x4:
+ case VSIR_OP_NRM:
+ case VSIR_OP_TEX:
+ case VSIR_OP_TEXBEM:
+ case VSIR_OP_TEXBEML:
+ case VSIR_OP_TEXCOORD:
+ case VSIR_OP_TEXCRD:
+ case VSIR_OP_TEXDEPTH:
+ case VSIR_OP_TEXDP3:
+ case VSIR_OP_TEXDP3TEX:
+ case VSIR_OP_TEXLD:
+ case VSIR_OP_TEXLDD:
+ case VSIR_OP_TEXLDL:
+ case VSIR_OP_TEXM3x2DEPTH:
+ case VSIR_OP_TEXM3x2PAD:
+ case VSIR_OP_TEXM3x2TEX:
+ case VSIR_OP_TEXM3x3:
+ case VSIR_OP_TEXM3x3DIFF:
+ case VSIR_OP_TEXM3x3PAD:
+ case VSIR_OP_TEXM3x3SPEC:
+ case VSIR_OP_TEXM3x3TEX:
+ case VSIR_OP_TEXM3x3VSPEC:
+ case VSIR_OP_TEXREG2AR:
+ case VSIR_OP_TEXREG2GB:
+ case VSIR_OP_TEXREG2RGB:
+ /* All of these instructions have fixed destinations—they can
+ * in some cases be masked, but the destination cannot be
+ * reallocated to a different set of components. */
+ case VSIR_OP_IMUL:
+ case VSIR_OP_SWAPC:
+ case VSIR_OP_UDIV:
+ case VSIR_OP_UMUL:
+ /* These instructions don't have fixed destinations, but they have
+ * multiple destination and are per-component, meaning that the
+ * destination masks for each component have to match.
+ * This is a bit tricky to pull off, so for now we just force
+ * these to have a fixed mask as well.
+ * This assumes that the destination masks are equal to each other
+ * to begin with! */
+ reg->fixed_mask = true;
+ break;
+
+ case VSIR_OP_SINCOS:
+ /* sm1 has a fixed destination like LIT, NRM.
+ * sm4 is two-component and masked, like IMUL. */
+ if (version->major < 3)
+ {
+ /* We have the additional constraint here that sincos scratches
+ * whichever components of .xyz it doesn't write. We can achieve
+ * this by simply adding those components to reg->mask. */
+ reg->mask |= 0x7;
+ }
+ reg->fixed_mask = true;
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void liveness_tracker_cleanup(struct liveness_tracker *tracker)
+{
+ vkd3d_free(tracker->ssa_regs);
+}
+
+static enum vkd3d_result track_liveness(struct vsir_program *program, struct liveness_tracker *tracker)
+{
+ struct liveness_tracker_reg *regs;
+ unsigned int loop_depth = 0;
+ unsigned int loop_start = 0;
+
+ memset(tracker, 0, sizeof(*tracker));
+
+ if (!(regs = vkd3d_calloc(program->ssa_count, sizeof(*regs))))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ tracker->ssa_regs = regs;
+
+ for (unsigned int i = 0; i < program->instructions.count; ++i)
+ {
+ const struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
+
+ if (ins->opcode == VSIR_OP_LOOP || ins->opcode == VSIR_OP_REP)
+ {
+ if (!loop_depth++)
+ loop_start = i;
+ }
+ else if (ins->opcode == VSIR_OP_ENDLOOP || ins->opcode == VSIR_OP_ENDREP)
+ {
+ if (!--loop_depth)
+ {
+ /* Go through the allocator, find anything that was touched
+ * during the loop, and extend its liveness to the whole range
+ * of the loop.
+ * This isn't very sophisticated (e.g. we could try to avoid
+ * this for registers first written inside a loop body and only
+ * ever read inside one), but many of the cases that matter are
+ * affected by other optimizations such as copy propagation
+ * anyway.
+ *
+ * This is overkill for SSA registers. If an SSA register is
+ * written in loop L and last read in L, we don't need to touch
+ * its liveness. If it's last read in an inferior loop of L, we
+ * only need to extend its last-read to the end of L. (And it
+ * should be illegal for an SSA value to be read in a block
+ * containing L.)
+ * We don't try to perform this optimization yet, in the name of
+ * maximal simplicity, and also because this code is intended to
+ * be extended to non-SSA values. */
+ for (unsigned int j = 0; j < program->ssa_count; ++j)
+ {
+ struct liveness_tracker_reg *reg = &tracker->ssa_regs[j];
+
+ if (reg->first_write > loop_start)
+ reg->first_write = loop_start;
+ if (reg->last_access < i)
+ reg->last_access = i;
+ }
+ }
+ }
+
+ for (unsigned int j = 0; j < ins->dst_count; ++j)
+ liveness_track_dst(tracker, &ins->dst[j], i, &program->shader_version, ins->opcode);
+ for (unsigned int j = 0; j < ins->src_count; ++j)
+ liveness_track_src(tracker, &ins->src[j], i);
+ }
+
+ return VKD3D_OK;
+}
+
+struct temp_allocator
+{
+ struct vkd3d_shader_message_context *message_context;
+ struct temp_allocator_reg
+ {
+ uint8_t allocated_mask;
+ uint32_t temp_id;
+ } *ssa_regs;
+ size_t allocated_ssa_count;
+ enum vkd3d_result result;
+};
+
+static uint8_t get_available_writemask(const struct temp_allocator *allocator,
+ struct liveness_tracker *tracker, unsigned int first_write, unsigned int last_access, uint32_t temp_id)
+{
+ uint8_t writemask = VKD3DSP_WRITEMASK_ALL;
+
+ for (size_t i = 0; i < allocator->allocated_ssa_count; ++i)
+ {
+ const struct temp_allocator_reg *reg = &allocator->ssa_regs[i];
+ const struct liveness_tracker_reg *liveness_reg = &tracker->ssa_regs[i];
+
+ /* We do not overlap if first write == last read:
+ * this is the case where we are allocating the result of that
+ * expression, e.g. "add r0, r0, r1". */
+
+ if (reg->temp_id == temp_id
+ && first_write < liveness_reg->last_access
+ && last_access > liveness_reg->first_write)
+ writemask &= ~reg->allocated_mask;
+
+ if (!writemask)
+ return writemask;
+ }
+
+ return writemask;
+}
+
+static bool temp_allocator_allocate(struct temp_allocator *allocator, struct liveness_tracker *tracker,
+ struct temp_allocator_reg *reg, const struct liveness_tracker_reg *liveness_reg, uint32_t base_id)
+{
+ if (!liveness_reg->written)
+ return false;
+
+ for (uint32_t id = base_id;; ++id)
+ {
+ uint8_t available_mask = get_available_writemask(allocator, tracker,
+ liveness_reg->first_write, liveness_reg->last_access, id);
+
+ if (liveness_reg->fixed_mask)
{
- if ((ret = insert_fragment_fog_before_ret(program, ins, mode, fog_signature_idx,
- colour_signature_idx, colour_temp, &new_pos, message_context)) < 0)
- return ret;
- i = new_pos;
- continue;
+ if ((available_mask & liveness_reg->mask) == liveness_reg->mask)
+ {
+ reg->temp_id = id;
+ reg->allocated_mask = liveness_reg->mask;
+ return true;
+ }
}
-
- for (size_t j = 0; j < ins->dst_count; ++j)
+ else
{
- struct vkd3d_shader_dst_param *dst = &ins->dst[j];
+ /* For SSA values the mask is always zero-based and contiguous.
+ * We don't correctly handle cases where it's not, currently. */
+ VKD3D_ASSERT((liveness_reg->mask | (liveness_reg->mask - 1)) == liveness_reg->mask);
- /* Note we run after I/O normalization. */
- if (dst->reg.type == VKD3DSPR_OUTPUT && dst->reg.idx[0].offset == colour_signature_idx)
+ if (vkd3d_popcount(available_mask) >= vkd3d_popcount(liveness_reg->mask))
{
- dst->reg.type = VKD3DSPR_TEMP;
- dst->reg.idx[0].offset = colour_temp;
+ reg->temp_id = id;
+ reg->allocated_mask = vsir_combine_write_masks(available_mask, liveness_reg->mask);
+ return true;
}
}
}
-
- return VKD3D_OK;
}
-static enum vkd3d_result vsir_program_add_fog_output(struct vsir_program *program,
- struct vsir_transformation_context *ctx)
+static void temp_allocator_set_src(struct temp_allocator *allocator, struct vkd3d_shader_src_param *src)
{
- struct shader_signature *signature = &program->output_signature;
- const struct vkd3d_shader_parameter1 *source_parameter;
- uint32_t register_idx = 0;
+ struct temp_allocator_reg *reg;
- if (!is_pre_rasterization_shader(program->shader_version.type))
- return VKD3D_OK;
-
- if (!(source_parameter = vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_FOG_SOURCE)))
- return VKD3D_OK;
-
- if (source_parameter->type == VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT)
+ for (unsigned int k = 0; k < src->reg.idx_count; ++k)
{
- enum vkd3d_shader_fog_source source = source_parameter->u.immediate_constant.u.u32;
-
- if (source == VKD3D_SHADER_FOG_SOURCE_FOG)
- return VKD3D_OK;
-
- if (source == VKD3D_SHADER_FOG_SOURCE_FOG_OR_SPECULAR_W
- && !vsir_signature_find_element_by_name(signature, "COLOR", 1))
- return VKD3D_OK;
+ if (src->reg.idx[k].rel_addr)
+ temp_allocator_set_src(allocator, src->reg.idx[k].rel_addr);
}
- if (vsir_signature_find_element_by_name(signature, "FOG", 0))
- return VKD3D_OK;
-
- for (unsigned int i = 0; i < signature->element_count; ++i)
- register_idx = max(register_idx, signature->elements[i].register_index + 1);
+ if (src->reg.type == VKD3DSPR_SSA)
+ reg = &allocator->ssa_regs[src->reg.idx[0].offset];
+ else
+ return;
- if (!add_signature_element(signature, "FOG", 0, VKD3DSP_WRITEMASK_0, register_idx, VKD3DSIM_LINEAR))
- return VKD3D_ERROR_OUT_OF_MEMORY;
- return VKD3D_OK;
+ src->reg.type = VKD3DSPR_TEMP;
+ src->reg.dimension = VSIR_DIMENSION_VEC4;
+ src->reg.idx[0].offset = reg->temp_id;
+ src->swizzle = vsir_combine_swizzles(vsir_swizzle_from_writemask(reg->allocated_mask), src->swizzle);
}
-static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *program,
- const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_fog_source source, uint32_t temp,
- uint32_t fog_signature_idx, uint32_t source_signature_idx, size_t *ret_pos)
+static uint32_t vsir_map_swizzle(uint32_t swizzle, unsigned int writemask)
{
- const struct signature_element *e = &program->output_signature.elements[source_signature_idx];
- struct vkd3d_shader_instruction_array *instructions = &program->instructions;
- const struct vkd3d_shader_location loc = ret->location;
- size_t pos = ret - instructions->elements;
- struct vkd3d_shader_instruction *ins;
+ unsigned int src_component = 0;
+ uint32_t ret = 0;
- if (!shader_instruction_array_insert_at(&program->instructions, pos, 2))
- return VKD3D_ERROR_OUT_OF_MEMORY;
- ret = NULL;
+ /* Leave replicate swizzles alone; some instructions need them. */
+ if (swizzle == VKD3D_SHADER_SWIZZLE(X, X, X, X)
+ || swizzle == VKD3D_SHADER_SWIZZLE(Y, Y, Y, Y)
+ || swizzle == VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z)
+ || swizzle == VKD3D_SHADER_SWIZZLE(W, W, W, W))
+ return swizzle;
- ins = &program->instructions.elements[pos];
+ for (unsigned int dst_component = 0; dst_component < VKD3D_VEC4_SIZE; ++dst_component)
+ {
+ if (writemask & (1u << dst_component))
+ vsir_swizzle_set_component(&ret, dst_component, vsir_swizzle_get_component(swizzle, src_component++));
+ }
+ return ret;
+}
- /* Write the fog output. */
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1);
- dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, fog_signature_idx, 0x1);
- src_param_init_temp_float4(&ins->src[0], temp);
- if (source == VKD3D_SHADER_FOG_SOURCE_Z)
- ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z);
- else /* Position or specular W. */
- ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W);
- ++ins;
+static void vsir_remap_immconst(struct vkd3d_shader_src_param *src, unsigned int writemask)
+{
+ union vsir_immediate_constant prev = src->reg.u;
+ unsigned int src_component = 0;
- /* Write the position or specular output. */
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1);
- dst_param_init_output(&ins->dst[0], vkd3d_data_type_from_component_type(e->component_type),
- source_signature_idx, e->mask);
- src_param_init_temp_float4(&ins->src[0], temp);
- ++ins;
+ for (unsigned int dst_component = 0; dst_component < VKD3D_VEC4_SIZE; ++dst_component)
+ {
+ if (writemask & (1u << dst_component))
+ src->reg.u.immconst_u32[dst_component] = prev.immconst_u32[src_component++];
+ }
+}
- *ret_pos = pos + 2;
- return VKD3D_OK;
+static void vsir_remap_immconst64(struct vkd3d_shader_src_param *src, unsigned int writemask)
+{
+ if (writemask == (VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3))
+ src->reg.u.immconst_u64[1] = src->reg.u.immconst_u64[0];
}
-static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *program,
- struct vsir_transformation_context *ctx)
+static bool vsir_opcode_is_double(enum vkd3d_shader_opcode opcode)
{
- struct vkd3d_shader_message_context *message_context = ctx->message_context;
- const struct vkd3d_shader_parameter1 *source_parameter = NULL;
- uint32_t fog_signature_idx, source_signature_idx, temp;
- static const struct vkd3d_shader_location no_loc;
- enum vkd3d_shader_fog_source source;
- const struct signature_element *e;
+ switch (opcode)
+ {
+ case VSIR_OP_DADD:
+ case VSIR_OP_DDIV:
+ case VSIR_OP_DFMA:
+ case VSIR_OP_DMAX:
+ case VSIR_OP_DMIN:
+ case VSIR_OP_DMOV:
+ case VSIR_OP_DMOVC:
+ case VSIR_OP_DMUL:
+ case VSIR_OP_DRCP:
+ case VSIR_OP_DEQO:
+ case VSIR_OP_DGEO:
+ case VSIR_OP_DLT:
+ case VSIR_OP_DNE:
+ case VSIR_OP_DTOF:
+ case VSIR_OP_DTOI:
+ case VSIR_OP_DTOU:
+ case VSIR_OP_FTOD:
+ return true;
- if (!is_pre_rasterization_shader(program->shader_version.type))
- return VKD3D_OK;
+ default:
+ return false;
+ }
+}
- if (!(source_parameter = vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_FOG_SOURCE)))
- return VKD3D_OK;
+static void temp_allocator_set_dst(struct temp_allocator *allocator,
+ struct vkd3d_shader_dst_param *dst, const struct vkd3d_shader_instruction *ins)
+{
+ struct temp_allocator_reg *reg;
- if (source_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT)
+ for (unsigned int k = 0; k < dst->reg.idx_count; ++k)
{
- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
- "Unsupported fog source parameter type %#x.", source_parameter->type);
- return VKD3D_ERROR_NOT_IMPLEMENTED;
+ if (dst->reg.idx[k].rel_addr)
+ temp_allocator_set_src(allocator, dst->reg.idx[k].rel_addr);
}
- if (source_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32)
+
+ if (dst->reg.type == VKD3DSPR_SSA)
+ reg = &allocator->ssa_regs[dst->reg.idx[0].offset];
+ else
+ return;
+
+ dst->reg.type = VKD3DSPR_TEMP;
+ dst->reg.dimension = VSIR_DIMENSION_VEC4;
+ dst->reg.idx[0].offset = reg->temp_id;
+ if (reg->allocated_mask != dst->write_mask)
{
- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
- "Invalid fog source parameter data type %#x.", source_parameter->data_type);
- return VKD3D_ERROR_INVALID_ARGUMENT;
+ dst->write_mask = reg->allocated_mask;
+
+ if (vsir_opcode_is_double(ins->opcode))
+ {
+ vkd3d_shader_error(allocator->message_context, &ins->location,
+ VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, "Doubles are not currently handled.");
+ allocator->result = VKD3D_ERROR_NOT_IMPLEMENTED;
+ }
+
+ for (unsigned int i = 0; i < ins->src_count; ++i)
+ {
+ struct vkd3d_shader_src_param *src = &ins->src[i];
+
+ if (vsir_src_is_masked(ins->opcode, i))
+ {
+ if (src->reg.type == VKD3DSPR_IMMCONST)
+ vsir_remap_immconst(src, dst->write_mask);
+ else if (src->reg.type == VKD3DSPR_IMMCONST64)
+ vsir_remap_immconst64(src, dst->write_mask);
+ else
+ src->swizzle = vsir_map_swizzle(src->swizzle, dst->write_mask);
+ }
+ }
}
- source = source_parameter->u.immediate_constant.u.u32;
+}
- TRACE("Fog source %#x.\n", source);
+enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program,
+ struct vkd3d_shader_message_context *message_context)
+{
+ const unsigned int prev_temp_count = program->temp_count;
+ struct temp_allocator allocator = {0};
+ struct temp_allocator_reg *regs;
+ struct liveness_tracker tracker;
+ enum vkd3d_result ret;
- if (source == VKD3D_SHADER_FOG_SOURCE_FOG)
+ if (!program->ssa_count)
return VKD3D_OK;
- if (source == VKD3D_SHADER_FOG_SOURCE_FOG_OR_SPECULAR_W)
+ if ((ret = track_liveness(program, &tracker)))
+ return ret;
+
+ if (!(regs = vkd3d_calloc(program->ssa_count, sizeof(*regs))))
{
- if (program->has_fog || !(e = vsir_signature_find_element_by_name(&program->output_signature, "COLOR", 1)))
- return VKD3D_OK;
- source_signature_idx = e - program->output_signature.elements;
+ liveness_tracker_cleanup(&tracker);
+ return VKD3D_ERROR_OUT_OF_MEMORY;
}
- else
+ allocator.message_context = message_context;
+ allocator.ssa_regs = regs;
+
+ for (unsigned int i = 0; i < program->ssa_count; ++i)
{
- if (!vsir_signature_find_sysval(&program->output_signature,
- VKD3D_SHADER_SV_POSITION, 0, &source_signature_idx))
+ const struct liveness_tracker_reg *liveness_reg = &tracker.ssa_regs[i];
+ struct temp_allocator_reg *reg = &allocator.ssa_regs[i];
+
+ if (temp_allocator_allocate(&allocator, &tracker, reg, liveness_reg, prev_temp_count))
{
- vkd3d_shader_error(ctx->message_context, &no_loc,
- VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC, "Shader does not write position.");
- return VKD3D_ERROR_INVALID_SHADER;
+ TRACE("Allocated r%u%s to sr%u (liveness %u-%u).\n",
+ reg->temp_id, debug_vsir_writemask(reg->allocated_mask), i,
+ liveness_reg->first_write, liveness_reg->last_access);
+ program->temp_count = max(program->temp_count, reg->temp_id + 1);
}
+ ++allocator.allocated_ssa_count;
}
- if (!(e = vsir_signature_find_element_by_name(&program->output_signature, "FOG", 0)))
+ for (unsigned int i = 0; i < program->instructions.count; ++i)
{
- ERR("Fog output not found.\n");
- return VKD3D_ERROR_INVALID_SHADER;
+ const struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
+
+ /* Make sure we do the srcs first; setting the dst writemask may need
+ * to remap their swizzles. */
+ for (unsigned int j = 0; j < ins->src_count; ++j)
+ temp_allocator_set_src(&allocator, &ins->src[j]);
+ for (unsigned int j = 0; j < ins->dst_count; ++j)
+ temp_allocator_set_dst(&allocator, &ins->dst[j], ins);
}
- fog_signature_idx = e - program->output_signature.elements;
- temp = program->temp_count++;
+ program->ssa_count = 0;
- /* Insert a fog write before each ret, and convert either specular or
- * position output to a temp. */
- for (size_t i = 0; i < program->instructions.count; ++i)
+ vkd3d_free(regs);
+ liveness_tracker_cleanup(&tracker);
+ return allocator.result;
+}
+
+/* Rewrite dcl_temps to reflect the new temp count.
+ * Note that dcl_temps appears once per phase, and should reflect only the
+ * number of temps needed by that phase.
+ * Therefore we iterate backwards through the shader, finding the maximum
+ * register used by any instruction, update the dcl_temps at the beginning
+ * of each phase, and then reset the temp count back to 0 for the next
+ * phase (if any). */
+enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program,
+ struct vkd3d_shader_message_context *message_context)
+{
+ unsigned int temp_count = 0;
+
+ for (int i = program->instructions.count - 1; i >= 0; --i)
{
struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
- if (vsir_instruction_is_dcl(ins))
+ if (ins->opcode == VSIR_OP_DCL_TEMPS)
+ {
+ ins->declaration.count = temp_count;
+ temp_count = 0;
continue;
+ }
- if (ins->opcode == VKD3DSIH_RET)
+ if (temp_count && program->shader_version.major >= 4
+ && (ins->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE
+ || ins->opcode == VSIR_OP_HS_FORK_PHASE
+ || ins->opcode == VSIR_OP_HS_JOIN_PHASE))
{
- size_t new_pos;
- int ret;
+ /* The phase didn't have a dcl_temps instruction, but we added
+ * temps here, so we need to insert one. */
+ if (!shader_instruction_array_insert_at(&program->instructions, i + 1, 1))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
- if ((ret = insert_vertex_fog_before_ret(program, ins, source, temp,
- fog_signature_idx, source_signature_idx, &new_pos)) < 0)
- return ret;
- i = new_pos;
+ ins = &program->instructions.elements[i + 1];
+ vsir_instruction_init(ins, &program->instructions.elements[i].location, VSIR_OP_DCL_TEMPS);
+ ins->declaration.count = temp_count;
+ temp_count = 0;
continue;
}
- for (size_t j = 0; j < ins->dst_count; ++j)
+ for (unsigned int j = 0; j < ins->src_count; ++j)
{
- struct vkd3d_shader_dst_param *dst = &ins->dst[j];
+ if (ins->src[j].reg.type == VKD3DSPR_TEMP)
+ temp_count = max(temp_count, ins->src[j].reg.idx[0].offset + 1);
+ }
- /* Note we run after I/O normalization. */
- if (dst->reg.type == VKD3DSPR_OUTPUT && dst->reg.idx[0].offset == source_signature_idx)
- {
- dst->reg.type = VKD3DSPR_TEMP;
- dst->reg.idx[0].offset = temp;
- }
+ for (unsigned int j = 0; j < ins->dst_count; ++j)
+ {
+ if (ins->dst[j].reg.type == VKD3DSPR_TEMP)
+ temp_count = max(temp_count, ins->dst[j].reg.idx[0].offset + 1);
}
}
- program->has_fog = true;
+ if (temp_count && program->shader_version.major >= 4)
+ {
+ struct vkd3d_shader_instruction *ins;
+
+ if (!shader_instruction_array_insert_at(&program->instructions, 0, 1))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+
+ ins = &program->instructions.elements[0];
+ vsir_instruction_init(ins, &program->instructions.elements[1].location, VSIR_OP_DCL_TEMPS);
+ ins->declaration.count = temp_count;
+ }
return VKD3D_OK;
}
@@ -7307,7 +8981,7 @@ struct validation_context
struct validation_context_ssa_data
{
enum vsir_dimension dimension;
- enum vkd3d_data_type data_type;
+ enum vsir_data_type data_type;
size_t first_seen;
uint32_t write_mask;
uint32_t read_mask;
@@ -7538,10 +9212,10 @@ static const bool vsir_get_io_register_data(struct validation_context *ctx,
switch (ctx->phase)
{
- case VKD3DSIH_HS_CONTROL_POINT_PHASE: phase = PHASE_CONTROL_POINT; break;
- case VKD3DSIH_HS_FORK_PHASE: phase = PHASE_FORK; break;
- case VKD3DSIH_HS_JOIN_PHASE: phase = PHASE_JOIN; break;
- case VKD3DSIH_INVALID: phase = PHASE_NONE; break;
+ case VSIR_OP_HS_CONTROL_POINT_PHASE: phase = PHASE_CONTROL_POINT; break;
+ case VSIR_OP_HS_FORK_PHASE: phase = PHASE_FORK; break;
+ case VSIR_OP_HS_JOIN_PHASE: phase = PHASE_JOIN; break;
+ case VSIR_OP_INVALID: phase = PHASE_NONE; break;
default:
vkd3d_unreachable();
@@ -7783,7 +9457,7 @@ static void vsir_validate_label_register(struct validation_context *ctx,
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION,
"Invalid precision %#x for a LABEL register.", reg->precision);
- if (reg->data_type != VKD3D_DATA_UNUSED)
+ if (reg->data_type != VSIR_DATA_UNUSED)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
"Invalid data type %#x for a LABEL register.", reg->data_type);
@@ -7841,10 +9515,6 @@ static void vsir_validate_descriptor_indices(struct validation_context *ctx,
static void vsir_validate_constbuffer_register(struct validation_context *ctx,
const struct vkd3d_shader_register *reg)
{
- if (reg->precision != VKD3D_SHADER_REGISTER_PRECISION_DEFAULT)
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION,
- "Invalid precision %#x for a CONSTBUFFER register.", reg->precision);
-
if (reg->dimension != VSIR_DIMENSION_VEC4)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION,
"Invalid dimension %#x for a CONSTBUFFER register.", reg->dimension);
@@ -7866,7 +9536,7 @@ static void vsir_validate_sampler_register(struct validation_context *ctx,
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION,
"Invalid precision %#x for a SAMPLER register.", reg->precision);
- if (reg->data_type != VKD3D_DATA_UNUSED)
+ if (reg->data_type != VSIR_DATA_UNUSED)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
"Invalid data type %#x for a SAMPLER register.", reg->data_type);
@@ -7892,7 +9562,7 @@ static void vsir_validate_resource_register(struct validation_context *ctx,
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION,
"Invalid precision %#x for a RESOURCE register.", reg->precision);
- if (reg->data_type != VKD3D_DATA_UNUSED)
+ if (reg->data_type != VSIR_DATA_UNUSED)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
"Invalid data type %#x for a RESOURCE register.", reg->data_type);
@@ -7918,7 +9588,7 @@ static void vsir_validate_uav_register(struct validation_context *ctx,
"Invalid precision %#x for a UAV register.",
reg->precision);
- if (reg->data_type != VKD3D_DATA_UNUSED)
+ if (reg->data_type != VSIR_DATA_UNUSED)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
"Invalid data type %#x for a UAV register.",
reg->data_type);
@@ -8005,6 +9675,30 @@ static void vsir_validate_src_param(struct validation_context *ctx,
static void vsir_validate_register(struct validation_context *ctx,
const struct vkd3d_shader_register *reg)
{
+ static const struct register_validation_data
+ {
+ bool valid;
+ unsigned int idx_count;
+ enum vsir_dimension dimension;
+ }
+ register_validation_data[] =
+ {
+ [VKD3DSPR_DEPTHOUT] = {true, 0, VSIR_DIMENSION_SCALAR},
+ [VKD3DSPR_PRIMID] = {true, 0, VSIR_DIMENSION_SCALAR},
+ [VKD3DSPR_OUTPOINTID] = {true, 0, VSIR_DIMENSION_SCALAR},
+ [VKD3DSPR_THREADID] = {true, 0, VSIR_DIMENSION_VEC4},
+ [VKD3DSPR_THREADGROUPID] = {true, 0, VSIR_DIMENSION_VEC4},
+ [VKD3DSPR_LOCALTHREADID] = {true, 0, VSIR_DIMENSION_VEC4},
+ [VKD3DSPR_LOCALTHREADINDEX] = {true, 0, VSIR_DIMENSION_VEC4},
+ [VKD3DSPR_COVERAGE] = {true, 0, VSIR_DIMENSION_VEC4},
+ [VKD3DSPR_SAMPLEMASK] = {true, 0, VSIR_DIMENSION_SCALAR},
+ [VKD3DSPR_GSINSTID] = {true, 0, VSIR_DIMENSION_VEC4},
+ [VKD3DSPR_DEPTHOUTGE] = {true, 0, VSIR_DIMENSION_SCALAR},
+ [VKD3DSPR_DEPTHOUTLE] = {true, 0, VSIR_DIMENSION_SCALAR},
+ [VKD3DSPR_OUTSTENCILREF] = {true, 0, VSIR_DIMENSION_SCALAR},
+ };
+
+ const struct register_validation_data *validation_data;
unsigned int i;
if (reg->type >= VKD3DSPR_COUNT)
@@ -8015,7 +9709,7 @@ static void vsir_validate_register(struct validation_context *ctx,
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, "Invalid register precision %#x.",
reg->precision);
- if (reg->data_type >= VKD3D_DATA_COUNT)
+ if (reg->data_type >= VSIR_DATA_TYPE_COUNT)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid register data type %#x.",
reg->data_type);
@@ -8070,10 +9764,6 @@ static void vsir_validate_register(struct validation_context *ctx,
vsir_validate_io_register(ctx, reg);
break;
- case VKD3DSPR_DEPTHOUT:
- vsir_validate_register_without_indices(ctx, reg);
- break;
-
case VKD3DSPR_MISCTYPE:
vsir_validate_misctype_register(ctx, reg);
break;
@@ -8094,10 +9784,6 @@ static void vsir_validate_register(struct validation_context *ctx,
vsir_validate_constbuffer_register(ctx, reg);
break;
- case VKD3DSPR_PRIMID:
- vsir_validate_register_without_indices(ctx, reg);
- break;
-
case VKD3DSPR_NULL:
vsir_validate_register_without_indices(ctx, reg);
break;
@@ -8110,75 +9796,31 @@ static void vsir_validate_register(struct validation_context *ctx,
vsir_validate_resource_register(ctx, reg);
break;
- case VKD3DSPR_UAV:
- vsir_validate_uav_register(ctx, reg);
- break;
-
- case VKD3DSPR_OUTPOINTID:
- vsir_validate_register_without_indices(ctx, reg);
- break;
-
- case VKD3DSPR_FORKINSTID:
- vsir_validate_register_without_indices(ctx, reg);
- break;
-
- case VKD3DSPR_JOININSTID:
- vsir_validate_register_without_indices(ctx, reg);
- break;
-
- case VKD3DSPR_INCONTROLPOINT:
- vsir_validate_io_register(ctx, reg);
- break;
-
- case VKD3DSPR_OUTCONTROLPOINT:
- vsir_validate_io_register(ctx, reg);
- break;
-
- case VKD3DSPR_PATCHCONST:
- vsir_validate_io_register(ctx, reg);
- break;
-
- case VKD3DSPR_TESSCOORD:
- vsir_validate_register_without_indices(ctx, reg);
- break;
-
- case VKD3DSPR_THREADID:
- vsir_validate_register_without_indices(ctx, reg);
- break;
-
- case VKD3DSPR_THREADGROUPID:
- vsir_validate_register_without_indices(ctx, reg);
- break;
-
- case VKD3DSPR_LOCALTHREADID:
- vsir_validate_register_without_indices(ctx, reg);
- break;
-
- case VKD3DSPR_LOCALTHREADINDEX:
- vsir_validate_register_without_indices(ctx, reg);
+ case VKD3DSPR_UAV:
+ vsir_validate_uav_register(ctx, reg);
break;
- case VKD3DSPR_COVERAGE:
+ case VKD3DSPR_FORKINSTID:
vsir_validate_register_without_indices(ctx, reg);
break;
- case VKD3DSPR_SAMPLEMASK:
+ case VKD3DSPR_JOININSTID:
vsir_validate_register_without_indices(ctx, reg);
break;
- case VKD3DSPR_GSINSTID:
- vsir_validate_register_without_indices(ctx, reg);
+ case VKD3DSPR_INCONTROLPOINT:
+ vsir_validate_io_register(ctx, reg);
break;
- case VKD3DSPR_DEPTHOUTGE:
- vsir_validate_register_without_indices(ctx, reg);
+ case VKD3DSPR_OUTCONTROLPOINT:
+ vsir_validate_io_register(ctx, reg);
break;
- case VKD3DSPR_DEPTHOUTLE:
- vsir_validate_register_without_indices(ctx, reg);
+ case VKD3DSPR_PATCHCONST:
+ vsir_validate_io_register(ctx, reg);
break;
- case VKD3DSPR_OUTSTENCILREF:
+ case VKD3DSPR_TESSCOORD:
vsir_validate_register_without_indices(ctx, reg);
break;
@@ -8197,6 +9839,24 @@ static void vsir_validate_register(struct validation_context *ctx,
default:
break;
}
+
+ if (reg->type >= ARRAY_SIZE(register_validation_data))
+ return;
+
+ validation_data = &register_validation_data[reg->type];
+
+ if (!validation_data->valid)
+ return;
+
+ if (reg->idx_count != validation_data->idx_count)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT,
+ "Invalid index count %u for a register of type %#x, expected %u.",
+ reg->idx_count, reg->type, validation_data->idx_count);
+
+ if (reg->dimension != validation_data->dimension)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT,
+ "Invalid dimension %#x for a register of type %#x, expected %#x.",
+ reg->dimension, reg->type, validation_data->dimension);
}
static void vsir_validate_io_dst_param(struct validation_context *ctx,
@@ -8242,15 +9902,37 @@ static void vsir_validate_dst_param(struct validation_context *ctx,
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Destination has invalid modifiers %#x.",
dst->modifiers);
+ if (dst->modifiers & VKD3DSPDM_SATURATE)
+ {
+ switch (dst->reg.data_type)
+ {
+ case VSIR_DATA_F16:
+ case VSIR_DATA_F32:
+ case VSIR_DATA_F64:
+ break;
+
+ default:
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Invalid data type %#x for destination with saturate modifier.", dst->reg.data_type);
+ break;
+
+ }
+ }
+
switch (dst->shift)
{
case 0:
+ break;
+
case 1:
case 2:
case 3:
case 13:
case 14:
case 15:
+ if (dst->reg.data_type != VSIR_DATA_F32)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Invalid data type %#x for destination with shift.", dst->reg.data_type);
break;
default:
@@ -8332,9 +10014,44 @@ static void vsir_validate_io_src_param(struct validation_context *ctx,
"Invalid register type %#x used as source parameter.", src->reg.type);
}
+#define F64_BIT (1u << VSIR_DATA_F64)
+#define F32_BIT (1u << VSIR_DATA_F32)
+#define F16_BIT (1u << VSIR_DATA_F16)
+
+#define I32_BIT (1u << VSIR_DATA_I32)
+
+#define U64_BIT (1u << VSIR_DATA_U64)
+#define U32_BIT (1u << VSIR_DATA_U32)
+#define U16_BIT (1u << VSIR_DATA_U16)
+
static void vsir_validate_src_param(struct validation_context *ctx,
const struct vkd3d_shader_src_param *src)
{
+ static const struct
+ {
+ uint32_t data_type_mask;
+ }
+ src_modifier_data[VKD3DSPSM_COUNT] =
+ {
+ [VKD3DSPSM_NEG] = {F64_BIT | F32_BIT | F16_BIT | I32_BIT | U64_BIT | U32_BIT | U16_BIT},
+ [VKD3DSPSM_BIAS] = {F32_BIT},
+ [VKD3DSPSM_BIASNEG] = {F32_BIT},
+ [VKD3DSPSM_SIGN] = {F32_BIT},
+ [VKD3DSPSM_SIGNNEG] = {F32_BIT},
+ [VKD3DSPSM_COMP] = {F32_BIT},
+ [VKD3DSPSM_X2] = {F32_BIT},
+ [VKD3DSPSM_X2NEG] = {F32_BIT},
+ [VKD3DSPSM_DZ] = {F32_BIT},
+ [VKD3DSPSM_DW] = {F32_BIT},
+ [VKD3DSPSM_ABS] = {F64_BIT | F32_BIT | F16_BIT},
+ [VKD3DSPSM_ABSNEG] = {F64_BIT | F32_BIT | F16_BIT},
+ /* This doesn't make a lot of sense. NOT is used only by D3DBC, and
+ * apparently only for IF instructions reading from a CONSTBOOL register.
+ * However, currently the D3DBC parser generates those registers of
+ * type float, so for the moment let's allow that. */
+ [VKD3DSPSM_NOT] = {F32_BIT},
+ };
+
vsir_validate_register(ctx, &src->reg);
if (src->swizzle & ~0x03030303u)
@@ -8349,6 +10066,13 @@ static void vsir_validate_src_param(struct validation_context *ctx,
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Source has invalid modifiers %#x.",
src->modifiers);
+ if (src->modifiers != VKD3DSPSM_NONE && src->modifiers < ARRAY_SIZE(src_modifier_data))
+ {
+ if (!(src_modifier_data[src->modifiers].data_type_mask & (1u << src->reg.data_type)))
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS,
+ "Source has invalid modifier %#x for data type %u.", src->modifiers, src->reg.data_type);
+ }
+
switch (src->reg.type)
{
case VKD3DSPR_SSA:
@@ -8400,8 +10124,9 @@ static void vsir_validate_dst_count(struct validation_context *ctx,
{
if (instruction->dst_count != count)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT,
- "Invalid destination count %u for an instruction of type %#x, expected %u.",
- instruction->dst_count, instruction->opcode, count);
+ "Invalid destination parameter count %zu for instruction \"%s\" (%#x); expected %u.",
+ instruction->dst_count, vsir_opcode_get_name(instruction->opcode, "<unknown>"),
+ instruction->opcode, count);
}
static void vsir_validate_src_count(struct validation_context *ctx,
@@ -8409,8 +10134,9 @@ static void vsir_validate_src_count(struct validation_context *ctx,
{
if (instruction->src_count != count)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT,
- "Invalid source count %u for an instruction of type %#x, expected %u.",
- instruction->src_count, instruction->opcode, count);
+ "Invalid source parameter count %zu for instruction \"%s\" (%#x); expected %u.",
+ instruction->src_count, vsir_opcode_get_name(instruction->opcode, "<unknown>"),
+ instruction->opcode, count);
}
static bool vsir_validate_src_min_count(struct validation_context *ctx,
@@ -8419,8 +10145,9 @@ static bool vsir_validate_src_min_count(struct validation_context *ctx,
if (instruction->src_count < count)
{
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT,
- "Invalid source count %u for an instruction of type %#x, expected at least %u.",
- instruction->src_count, instruction->opcode, count);
+ "Invalid source parameter count %zu for instruction \"%s\" (%#x); expected at least %u.",
+ instruction->src_count, vsir_opcode_get_name(instruction->opcode, "<unknown>"),
+ instruction->opcode, count);
return false;
}
@@ -8433,8 +10160,9 @@ static bool vsir_validate_src_max_count(struct validation_context *ctx,
if (instruction->src_count > count)
{
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT,
- "Invalid source count %u for an instruction of type %#x, expected at most %u.",
- instruction->src_count, instruction->opcode, count);
+ "Invalid source parameter count %zu for instruction \"%s\" (%#x); expected at most %u.",
+ instruction->src_count, vsir_opcode_get_name(instruction->opcode, "<unknown>"),
+ instruction->opcode, count);
return false;
}
@@ -8874,6 +10602,7 @@ static void vsir_validate_descriptors(struct validation_context *ctx)
for (i = 0; i < descriptors->descriptor_count; ++i)
{
const struct vkd3d_shader_descriptor_info1 *descriptor = &descriptors->descriptors[i];
+ uint32_t flags_mask = 0, uav_flags_mask = 0;
if (descriptor->type >= VKD3D_SHADER_DESCRIPTOR_TYPE_COUNT)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_TYPE,
@@ -8888,10 +10617,10 @@ static void vsir_validate_descriptors(struct validation_context *ctx)
"Descriptor %u has invalid resource type %#x for descriptor type %#x.",
i, descriptor->resource_type, descriptor->type);
- if (descriptor->resource_data_type >= VKD3D_DATA_COUNT)
+ if (descriptor->resource_data_type >= VSIR_DATA_TYPE_COUNT)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
"Descriptor %u has invalid resource data type %#x.", i, descriptor->resource_data_type);
- else if ((descriptor->resource_data_type == VKD3D_DATA_UNUSED)
+ else if ((descriptor->resource_data_type == VSIR_DATA_UNUSED)
!= (descriptor->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER))
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
"Descriptor %u has invalid resource data type %#x for descriptor type %#x.",
@@ -8902,6 +10631,43 @@ static void vsir_validate_descriptors(struct validation_context *ctx)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_COUNT,
"Descriptor %u has invalid descriptor count %u starting at index %u.",
i, descriptor->count, descriptor->register_index);
+
+ switch (descriptor->type)
+ {
+ case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV:
+ flags_mask = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER;
+ break;
+
+ case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV:
+ flags_mask = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER
+ | VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ
+ | VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS
+ | VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER;
+ uav_flags_mask = VKD3DSUF_GLOBALLY_COHERENT
+ | VKD3DSUF_RASTERISER_ORDERED_VIEW
+ | VKD3DSUF_ORDER_PRESERVING_COUNTER;
+ break;
+
+ case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
+ break;
+
+ case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER:
+ flags_mask = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE;
+ break;
+
+ case VKD3D_SHADER_DESCRIPTOR_TYPE_FORCE_32BIT:
+ break;
+ }
+
+ if (descriptor->flags & ~flags_mask)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_FLAGS,
+ "Descriptor %u of type %#x has invalid flags %#x.",
+ i, descriptor->type, descriptor->flags);
+
+ if (descriptor->uav_flags & ~uav_flags_mask)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_FLAGS,
+ "Descriptor %u of type %#x has invalid UAV flags %#x.",
+ i, descriptor->type, descriptor->uav_flags);
}
}
@@ -8922,7 +10688,9 @@ static void vsir_validate_cf_type(struct validation_context *ctx,
const struct vkd3d_shader_instruction *instruction, enum vsir_control_flow_type expected_type)
{
if (ctx->program->cf_type != expected_type)
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "Invalid instruction %#x in %s shader.",
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
+ "Invalid instruction \"%s\" (%#x) in %s shader.",
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"),
instruction->opcode, name_from_cf_type(ctx->program->cf_type));
}
@@ -8940,17 +10708,230 @@ static void vsir_validate_hull_shader_phase(struct validation_context *ctx,
const struct vkd3d_shader_instruction *instruction)
{
if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL)
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER,
- "Phase instruction %#x is only valid in a hull shader.",
- instruction->opcode);
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_OPCODE,
+ "Phase instruction \"%s\" (%#x) is only valid in a hull shader.",
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
if (ctx->depth != 0)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
- "Phase instruction %#x must appear to top level.",
- instruction->opcode);
+ "Phase instruction \"%s\" (%#x) must appear at the top level.",
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
ctx->phase = instruction->opcode;
ctx->dcl_temps_found = false;
}
+static void vsir_validate_elementwise_operation(struct validation_context *ctx,
+ const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT])
+{
+ enum vsir_data_type dst_data_type;
+ unsigned int i;
+
+ if (instruction->dst_count < 1)
+ return;
+
+ dst_data_type = instruction->dst[0].reg.data_type;
+
+ if (dst_data_type >= VSIR_DATA_TYPE_COUNT)
+ return;
+
+ if (!types[dst_data_type])
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Invalid data type %#x for elementwise operation \"%s\" (%#x).",
+ dst_data_type, vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
+
+ for (i = 0; i < instruction->src_count; ++i)
+ {
+ if (instruction->src[i].reg.data_type != dst_data_type)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Data type %#x for operand %u doesn't match the destination data type %#x "
+ "for elementwise operation \"%s\" (%#x).",
+ instruction->src[i].reg.data_type, i, dst_data_type,
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
+ }
+}
+
+static void vsir_validate_double_elementwise_operation(struct validation_context *ctx,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ static const bool types[VSIR_DATA_TYPE_COUNT] =
+ {
+ [VSIR_DATA_F64] = true,
+ };
+
+ vsir_validate_elementwise_operation(ctx, instruction, types);
+}
+
+static void vsir_validate_float_elementwise_operation(struct validation_context *ctx,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ static const bool types[VSIR_DATA_TYPE_COUNT] =
+ {
+ [VSIR_DATA_F32] = true,
+ };
+
+ vsir_validate_elementwise_operation(ctx, instruction, types);
+}
+
+static void vsir_validate_integer_elementwise_operation(struct validation_context *ctx,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ static const bool types[VSIR_DATA_TYPE_COUNT] =
+ {
+ [VSIR_DATA_I32] = true,
+ [VSIR_DATA_U32] = true,
+ [VSIR_DATA_U64] = true,
+ };
+
+ vsir_validate_elementwise_operation(ctx, instruction, types);
+}
+
+static void vsir_validate_logic_elementwise_operation(struct validation_context *ctx,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ static const bool types[VSIR_DATA_TYPE_COUNT] =
+ {
+ [VSIR_DATA_BOOL] = true,
+ [VSIR_DATA_I32] = true,
+ [VSIR_DATA_U32] = true,
+ [VSIR_DATA_U64] = true,
+ };
+
+ vsir_validate_elementwise_operation(ctx, instruction, types);
+}
+
+static void vsir_validate_comparison_operation(struct validation_context *ctx,
+ const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT])
+{
+ enum vsir_data_type dst_data_type, src_data_type;
+ unsigned int i;
+
+ if (instruction->dst_count < 1)
+ return;
+
+ dst_data_type = instruction->dst[0].reg.data_type;
+
+ if (dst_data_type != VSIR_DATA_U32 && dst_data_type != VSIR_DATA_BOOL)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Invalid data type %#x for result of comparison operation \"%s\" (%#x).",
+ dst_data_type, vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
+
+ if (instruction->src_count == 0)
+ return;
+
+ src_data_type = instruction->src[0].reg.data_type;
+
+ if (src_data_type >= VSIR_DATA_TYPE_COUNT)
+ return;
+
+ if (!types[src_data_type])
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Invalid data type %#x for comparison operation \"%s\" (%#x).",
+ src_data_type, vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
+
+ for (i = 1; i < instruction->src_count; ++i)
+ {
+ if (instruction->src[i].reg.data_type != src_data_type)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Data type %#x for operand %u doesn't match the first operands data type %#x "
+ "for comparison operation \"%s\" (%#x).",
+ instruction->src[i].reg.data_type, i, src_data_type,
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
+ }
+}
+
+static void vsir_validate_double_comparison_operation(struct validation_context *ctx,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ static const bool types[VSIR_DATA_TYPE_COUNT] =
+ {
+ [VSIR_DATA_F64] = true,
+ };
+
+ vsir_validate_comparison_operation(ctx, instruction, types);
+}
+
+static void vsir_validate_float_comparison_operation(struct validation_context *ctx,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ static const bool types[VSIR_DATA_TYPE_COUNT] =
+ {
+ [VSIR_DATA_F32] = true,
+ [VSIR_DATA_F64] = true,
+ };
+
+ vsir_validate_comparison_operation(ctx, instruction, types);
+}
+
+static void vsir_validate_integer_comparison_operation(struct validation_context *ctx,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ static const bool types[VSIR_DATA_TYPE_COUNT] =
+ {
+ [VSIR_DATA_I32] = true,
+ [VSIR_DATA_U32] = true,
+ [VSIR_DATA_U64] = true,
+ };
+
+ vsir_validate_comparison_operation(ctx, instruction, types);
+}
+
+static void vsir_validate_cast_operation(struct validation_context *ctx,
+ const struct vkd3d_shader_instruction *instruction,
+ const bool src_types[VSIR_DATA_TYPE_COUNT], const bool dst_types[VSIR_DATA_TYPE_COUNT])
+{
+ enum vsir_data_type dst_data_type, src_data_type;
+
+ if (instruction->dst_count < 1 || instruction->src_count < 1)
+ return;
+
+ dst_data_type = instruction->dst[0].reg.data_type;
+ src_data_type = instruction->src[0].reg.data_type;
+
+ if (src_data_type >= VSIR_DATA_TYPE_COUNT || dst_data_type >= VSIR_DATA_TYPE_COUNT)
+ return;
+
+ if (!src_types[src_data_type])
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Invalid source data type %#x for cast operation \"%s\" (%#x).",
+ src_data_type, vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
+
+ if (!dst_types[dst_data_type])
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Invalid destination data type %#x for cast operation \"%s\" (%#x).",
+ dst_data_type, vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
+}
+
+static void vsir_validate_shift_operation(struct validation_context *ctx,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ enum vsir_data_type data_type;
+
+ static const bool types[] =
+ {
+ [VSIR_DATA_I32] = true,
+ [VSIR_DATA_U32] = true,
+ [VSIR_DATA_U64] = true,
+ };
+
+ data_type = instruction->dst[0].reg.data_type;
+ if ((size_t)data_type >= ARRAY_SIZE(types) || !types[data_type])
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Invalid destination data type %#x for shift operation \"%s\" (%#x).",
+ data_type, vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
+
+ if (instruction->src[0].reg.data_type != data_type)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Data type %#x for source operand 0 doesn't match destination data type %#x "
+ "for shift operation \"%s\" (%#x).",
+ instruction->src[0].reg.data_type, data_type,
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
+
+ data_type = instruction->src[1].reg.data_type;
+ if ((size_t)data_type >= ARRAY_SIZE(types) || !types[data_type])
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Invalid source operand 1 data type %#x for shift operation \"%s\" (%#x).",
+ data_type, vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
+}
+
static void vsir_validate_branch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
{
size_t i;
@@ -9026,7 +11007,7 @@ static void vsir_validate_dcl_index_range(struct validation_context *ctx,
if (ctx->program->normalisation_level >= VSIR_NORMALISED_SM6)
{
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER,
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_OPCODE,
"DCL_INDEX_RANGE is not allowed with fully normalised input/output.");
return;
}
@@ -9416,18 +11397,18 @@ static void vsir_validate_dcl_vertices_out(struct validation_context *ctx,
static void vsir_validate_else(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
{
vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
- if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_IF)
+ if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VSIR_OP_IF)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
"ELSE instruction doesn't terminate IF block.");
else
- ctx->blocks[ctx->depth - 1] = VKD3DSIH_ELSE;
+ ctx->blocks[ctx->depth - 1] = VSIR_OP_ELSE;
}
static void vsir_validate_endif(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
{
vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
- if (ctx->depth == 0 || (ctx->blocks[ctx->depth - 1] != VKD3DSIH_IF
- && ctx->blocks[ctx->depth - 1] != VKD3DSIH_ELSE))
+ if (ctx->depth == 0 || (ctx->blocks[ctx->depth - 1] != VSIR_OP_IF
+ && ctx->blocks[ctx->depth - 1] != VSIR_OP_ELSE))
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
"ENDIF instruction doesn't terminate IF/ELSE block.");
else
@@ -9437,7 +11418,7 @@ static void vsir_validate_endif(struct validation_context *ctx, const struct vkd
static void vsir_validate_endloop(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
{
vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
- if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_LOOP)
+ if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VSIR_OP_LOOP)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
"ENDLOOP instruction doesn't terminate LOOP block.");
else
@@ -9447,7 +11428,7 @@ static void vsir_validate_endloop(struct validation_context *ctx, const struct v
static void vsir_validate_endrep(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
{
vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
- if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_REP)
+ if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VSIR_OP_REP)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
"ENDREP instruction doesn't terminate REP block.");
else
@@ -9457,23 +11438,88 @@ static void vsir_validate_endrep(struct validation_context *ctx, const struct vk
static void vsir_validate_endswitch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
{
vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
- if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_SWITCH)
+ if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VSIR_OP_SWITCH)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
"ENDSWITCH instruction doesn't terminate SWITCH block.");
else
--ctx->depth;
}
+static void vsir_validate_ftoi(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
+{
+ static const bool src_types[VSIR_DATA_TYPE_COUNT] =
+ {
+ [VSIR_DATA_F16] = true,
+ [VSIR_DATA_F32] = true,
+ [VSIR_DATA_F64] = true,
+ };
+ static const bool dst_types[VSIR_DATA_TYPE_COUNT] =
+ {
+ [VSIR_DATA_I32] = true,
+ [VSIR_DATA_U32] = true,
+ };
+
+ vsir_validate_cast_operation(ctx, instruction, src_types, dst_types);
+}
+
+static void vsir_validate_ftou(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
+{
+ static const bool src_types[VSIR_DATA_TYPE_COUNT] =
+ {
+ [VSIR_DATA_F16] = true,
+ [VSIR_DATA_F32] = true,
+ [VSIR_DATA_F64] = true,
+ };
+ static const bool dst_types[VSIR_DATA_TYPE_COUNT] =
+ {
+ [VSIR_DATA_U32] = true,
+ };
+
+ vsir_validate_cast_operation(ctx, instruction, src_types, dst_types);
+}
+
static void vsir_validate_if(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
{
vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
- vsir_validator_push_block(ctx, VKD3DSIH_IF);
+ vsir_validator_push_block(ctx, VSIR_OP_IF);
}
static void vsir_validate_ifc(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
{
vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
- vsir_validator_push_block(ctx, VKD3DSIH_IF);
+ vsir_validator_push_block(ctx, VSIR_OP_IF);
+}
+
+static void vsir_validate_itof(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
+{
+ static const bool src_types[VSIR_DATA_TYPE_COUNT] =
+ {
+ [VSIR_DATA_BOOL] = true,
+ [VSIR_DATA_I32] = true,
+ [VSIR_DATA_U32] = true,
+ [VSIR_DATA_U64] = true,
+ };
+ static const bool dst_types[VSIR_DATA_TYPE_COUNT] =
+ {
+ [VSIR_DATA_F16] = true,
+ [VSIR_DATA_F32] = true,
+ [VSIR_DATA_F64] = true,
+ };
+
+ vsir_validate_cast_operation(ctx, instruction, src_types, dst_types);
+}
+
+static void vsir_validate_itoi(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
+{
+ static const bool types[VSIR_DATA_TYPE_COUNT] =
+ {
+ [VSIR_DATA_BOOL] = true,
+ [VSIR_DATA_I32] = true,
+ [VSIR_DATA_U32] = true,
+ [VSIR_DATA_U64] = true,
+ };
+
+ vsir_validate_cast_operation(ctx, instruction, types, types);
}
static void vsir_validate_label(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
@@ -9494,7 +11540,7 @@ static void vsir_validate_loop(struct validation_context *ctx, const struct vkd3
{
vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
vsir_validate_src_count(ctx, instruction, ctx->program->shader_version.major <= 3 ? 2 : 0);
- vsir_validator_push_block(ctx, VKD3DSIH_LOOP);
+ vsir_validator_push_block(ctx, VSIR_OP_LOOP);
}
static void vsir_validate_nop(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
@@ -9511,7 +11557,7 @@ static void vsir_validate_phi(struct validation_context *ctx, const struct vkd3d
if (instruction->src_count % 2 != 0)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT,
- "Invalid source count %u for a PHI instruction, it must be an even number.",
+ "Invalid source count %zu for a PHI instruction, it must be an even number.",
instruction->src_count);
incoming_count = instruction->src_count / 2;
@@ -9564,7 +11610,7 @@ static void vsir_validate_phi(struct validation_context *ctx, const struct vkd3d
static void vsir_validate_rep(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
{
vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
- vsir_validator_push_block(ctx, VKD3DSIH_REP);
+ vsir_validator_push_block(ctx, VSIR_OP_REP);
}
static void vsir_validate_ret(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
@@ -9572,10 +11618,58 @@ static void vsir_validate_ret(struct validation_context *ctx, const struct vkd3d
ctx->inside_block = false;
}
+static void vsir_validate_throw_invalid_dst_type_error_with_flags(struct validation_context *ctx,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ enum vsir_data_type dst_data_type = instruction->dst[0].reg.data_type;
+
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
+ "Invalid destination data type %#x for operation \"%s\" (%#x) with flags %#x.", dst_data_type,
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode, instruction->flags);
+}
+
+static void vsir_validate_sample_info(struct validation_context *ctx,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ enum vsir_data_type dst_data_type = instruction->dst[0].reg.data_type;
+
+ switch (dst_data_type)
+ {
+ case VSIR_DATA_F32:
+ case VSIR_DATA_U32:
+ if (!!(instruction->flags & VKD3DSI_SAMPLE_INFO_UINT) != (dst_data_type == VSIR_DATA_U32))
+ vsir_validate_throw_invalid_dst_type_error_with_flags(ctx, instruction);
+ break;
+
+ default:
+ vsir_validate_throw_invalid_dst_type_error_with_flags(ctx, instruction);
+ break;
+ }
+}
+
+static void vsir_validate_resinfo(struct validation_context *ctx,
+ const struct vkd3d_shader_instruction *instruction)
+{
+ enum vsir_data_type dst_data_type = instruction->dst[0].reg.data_type;
+
+ switch (dst_data_type)
+ {
+ case VSIR_DATA_F32:
+ case VSIR_DATA_U32:
+ if (!!(instruction->flags & VKD3DSI_RESINFO_UINT) != (dst_data_type == VSIR_DATA_U32))
+ vsir_validate_throw_invalid_dst_type_error_with_flags(ctx, instruction);
+ break;
+
+ default:
+ vsir_validate_throw_invalid_dst_type_error_with_flags(ctx, instruction);
+ break;
+ }
+}
+
static void vsir_validate_switch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction)
{
vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED);
- vsir_validator_push_block(ctx, VKD3DSIH_SWITCH);
+ vsir_validator_push_block(ctx, VSIR_OP_SWITCH);
}
static void vsir_validate_switch_monolithic(struct validation_context *ctx,
@@ -9593,7 +11687,7 @@ static void vsir_validate_switch_monolithic(struct validation_context *ctx,
if (instruction->src_count % 2 != 1)
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT,
- "Invalid source count %u for a monolithic SWITCH instruction, it must be an odd number.",
+ "Invalid source count %zu for a monolithic SWITCH instruction, it must be an odd number.",
instruction->src_count);
if (!vsir_register_is_label(&instruction->src[1].reg))
@@ -9636,45 +11730,116 @@ struct vsir_validator_instruction_desc
static const struct vsir_validator_instruction_desc vsir_validator_instructions[] =
{
- [VKD3DSIH_BRANCH] = {0, ~0u, vsir_validate_branch},
- [VKD3DSIH_HS_CONTROL_POINT_PHASE] = {0, 0, vsir_validate_hull_shader_phase},
- [VKD3DSIH_HS_DECLS] = {0, 0, vsir_validate_hull_shader_phase},
- [VKD3DSIH_HS_FORK_PHASE] = {0, 0, vsir_validate_hull_shader_phase},
- [VKD3DSIH_HS_JOIN_PHASE] = {0, 0, vsir_validate_hull_shader_phase},
- [VKD3DSIH_DCL_GS_INSTANCES] = {0, 0, vsir_validate_dcl_gs_instances},
- [VKD3DSIH_DCL_HS_MAX_TESSFACTOR] = {0, 0, vsir_validate_dcl_hs_max_tessfactor},
- [VKD3DSIH_DCL_INDEX_RANGE] = {0, 0, vsir_validate_dcl_index_range},
- [VKD3DSIH_DCL_INPUT] = {0, 0, vsir_validate_dcl_input},
- [VKD3DSIH_DCL_INPUT_PRIMITIVE] = {0, 0, vsir_validate_dcl_input_primitive},
- [VKD3DSIH_DCL_INPUT_PS] = {0, 0, vsir_validate_dcl_input_ps},
- [VKD3DSIH_DCL_INPUT_PS_SGV] = {0, 0, vsir_validate_dcl_input_ps_sgv},
- [VKD3DSIH_DCL_INPUT_PS_SIV] = {0, 0, vsir_validate_dcl_input_ps_siv},
- [VKD3DSIH_DCL_INPUT_SGV] = {0, 0, vsir_validate_dcl_input_sgv},
- [VKD3DSIH_DCL_INPUT_SIV] = {0, 0, vsir_validate_dcl_input_siv},
- [VKD3DSIH_DCL_OUTPUT] = {0, 0, vsir_validate_dcl_output},
- [VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT] = {0, 0, vsir_validate_dcl_output_control_point_count},
- [VKD3DSIH_DCL_OUTPUT_SIV] = {0, 0, vsir_validate_dcl_output_siv},
- [VKD3DSIH_DCL_OUTPUT_TOPOLOGY] = {0, 0, vsir_validate_dcl_output_topology},
- [VKD3DSIH_DCL_TEMPS] = {0, 0, vsir_validate_dcl_temps},
- [VKD3DSIH_DCL_TESSELLATOR_DOMAIN] = {0, 0, vsir_validate_dcl_tessellator_domain},
- [VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = {0, 0, vsir_validate_dcl_tessellator_output_primitive},
- [VKD3DSIH_DCL_TESSELLATOR_PARTITIONING] = {0, 0, vsir_validate_dcl_tessellator_partitioning},
- [VKD3DSIH_DCL_VERTICES_OUT] = {0, 0, vsir_validate_dcl_vertices_out},
- [VKD3DSIH_ELSE] = {0, 0, vsir_validate_else},
- [VKD3DSIH_ENDIF] = {0, 0, vsir_validate_endif},
- [VKD3DSIH_ENDLOOP] = {0, 0, vsir_validate_endloop},
- [VKD3DSIH_ENDREP] = {0, 0, vsir_validate_endrep},
- [VKD3DSIH_ENDSWITCH] = {0, 0, vsir_validate_endswitch},
- [VKD3DSIH_IF] = {0, 1, vsir_validate_if},
- [VKD3DSIH_IFC] = {0, 2, vsir_validate_ifc},
- [VKD3DSIH_LABEL] = {0, 1, vsir_validate_label},
- [VKD3DSIH_LOOP] = {0, ~0u, vsir_validate_loop},
- [VKD3DSIH_NOP] = {0, 0, vsir_validate_nop},
- [VKD3DSIH_PHI] = {1, ~0u, vsir_validate_phi},
- [VKD3DSIH_REP] = {0, 1, vsir_validate_rep},
- [VKD3DSIH_RET] = {0, 0, vsir_validate_ret},
- [VKD3DSIH_SWITCH] = {0, 1, vsir_validate_switch},
- [VKD3DSIH_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic},
+ [VSIR_OP_ABS] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_ACOS] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_ADD] = {1, 2, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_AND] = {1, 2, vsir_validate_logic_elementwise_operation},
+ [VSIR_OP_ASIN] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_ATAN] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_BRANCH] = {0, ~0u, vsir_validate_branch},
+ [VSIR_OP_DADD] = {1, 2, vsir_validate_double_elementwise_operation},
+ [VSIR_OP_DCL_GS_INSTANCES] = {0, 0, vsir_validate_dcl_gs_instances},
+ [VSIR_OP_DCL_HS_MAX_TESSFACTOR] = {0, 0, vsir_validate_dcl_hs_max_tessfactor},
+ [VSIR_OP_DCL_INDEX_RANGE] = {0, 0, vsir_validate_dcl_index_range},
+ [VSIR_OP_DCL_INPUT] = {0, 0, vsir_validate_dcl_input},
+ [VSIR_OP_DCL_INPUT_PRIMITIVE] = {0, 0, vsir_validate_dcl_input_primitive},
+ [VSIR_OP_DCL_INPUT_PS] = {0, 0, vsir_validate_dcl_input_ps},
+ [VSIR_OP_DCL_INPUT_PS_SGV] = {0, 0, vsir_validate_dcl_input_ps_sgv},
+ [VSIR_OP_DCL_INPUT_PS_SIV] = {0, 0, vsir_validate_dcl_input_ps_siv},
+ [VSIR_OP_DCL_INPUT_SGV] = {0, 0, vsir_validate_dcl_input_sgv},
+ [VSIR_OP_DCL_INPUT_SIV] = {0, 0, vsir_validate_dcl_input_siv},
+ [VSIR_OP_DCL_OUTPUT] = {0, 0, vsir_validate_dcl_output},
+ [VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT] = {0, 0, vsir_validate_dcl_output_control_point_count},
+ [VSIR_OP_DCL_OUTPUT_SIV] = {0, 0, vsir_validate_dcl_output_siv},
+ [VSIR_OP_DCL_OUTPUT_TOPOLOGY] = {0, 0, vsir_validate_dcl_output_topology},
+ [VSIR_OP_DCL_TEMPS] = {0, 0, vsir_validate_dcl_temps},
+ [VSIR_OP_DCL_TESSELLATOR_DOMAIN] = {0, 0, vsir_validate_dcl_tessellator_domain},
+ [VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = {0, 0, vsir_validate_dcl_tessellator_output_primitive},
+ [VSIR_OP_DCL_TESSELLATOR_PARTITIONING] = {0, 0, vsir_validate_dcl_tessellator_partitioning},
+ [VSIR_OP_DCL_VERTICES_OUT] = {0, 0, vsir_validate_dcl_vertices_out},
+ [VSIR_OP_DDIV] = {1, 2, vsir_validate_double_elementwise_operation},
+ [VSIR_OP_DEQO] = {1, 2, vsir_validate_double_comparison_operation},
+ [VSIR_OP_DFMA] = {1, 3, vsir_validate_double_elementwise_operation},
+ [VSIR_OP_DGEO] = {1, 2, vsir_validate_double_comparison_operation},
+ [VSIR_OP_DIV] = {1, 2, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_DLT] = {1, 2, vsir_validate_double_comparison_operation},
+ [VSIR_OP_DMAX] = {1, 2, vsir_validate_double_elementwise_operation},
+ [VSIR_OP_DMIN] = {1, 2, vsir_validate_double_elementwise_operation},
+ [VSIR_OP_DMOV] = {1, 1, vsir_validate_double_elementwise_operation},
+ [VSIR_OP_DMUL] = {1, 2, vsir_validate_double_elementwise_operation},
+ [VSIR_OP_DNE] = {1, 2, vsir_validate_double_comparison_operation},
+ [VSIR_OP_DRCP] = {1, 1, vsir_validate_double_elementwise_operation},
+ [VSIR_OP_DSX] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_DSX_COARSE] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_DSX_FINE] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_DSY] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_DSY_COARSE] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_DSY_FINE] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_ELSE] = {0, 0, vsir_validate_else},
+ [VSIR_OP_ENDIF] = {0, 0, vsir_validate_endif},
+ [VSIR_OP_ENDLOOP] = {0, 0, vsir_validate_endloop},
+ [VSIR_OP_ENDREP] = {0, 0, vsir_validate_endrep},
+ [VSIR_OP_ENDSWITCH] = {0, 0, vsir_validate_endswitch},
+ [VSIR_OP_EQO] = {1, 2, vsir_validate_float_comparison_operation},
+ [VSIR_OP_EQU] = {1, 2, vsir_validate_float_comparison_operation},
+ [VSIR_OP_EXP] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_FRC] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_FREM] = {1, 2, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_FTOI] = {1, 1, vsir_validate_ftoi},
+ [VSIR_OP_FTOU] = {1, 1, vsir_validate_ftou},
+ [VSIR_OP_GEO] = {1, 2, vsir_validate_float_comparison_operation},
+ [VSIR_OP_GEU] = {1, 2, vsir_validate_float_comparison_operation},
+ [VSIR_OP_HCOS] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_HSIN] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_HS_CONTROL_POINT_PHASE] = {0, 0, vsir_validate_hull_shader_phase},
+ [VSIR_OP_HS_DECLS] = {0, 0, vsir_validate_hull_shader_phase},
+ [VSIR_OP_HS_FORK_PHASE] = {0, 0, vsir_validate_hull_shader_phase},
+ [VSIR_OP_HS_JOIN_PHASE] = {0, 0, vsir_validate_hull_shader_phase},
+ [VSIR_OP_HTAN] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_IADD] = {1, 2, vsir_validate_integer_elementwise_operation},
+ [VSIR_OP_IEQ] = {1, 2, vsir_validate_integer_comparison_operation},
+ [VSIR_OP_IF] = {0, 1, vsir_validate_if},
+ [VSIR_OP_IFC] = {0, 2, vsir_validate_ifc},
+ [VSIR_OP_IGE] = {1, 2, vsir_validate_integer_comparison_operation},
+ [VSIR_OP_ILT] = {1, 2, vsir_validate_integer_comparison_operation},
+ [VSIR_OP_IMAD] = {1, 3, vsir_validate_integer_elementwise_operation},
+ [VSIR_OP_IMAX] = {1, 2, vsir_validate_integer_elementwise_operation},
+ [VSIR_OP_IMIN] = {1, 2, vsir_validate_integer_elementwise_operation},
+ [VSIR_OP_INE] = {1, 2, vsir_validate_integer_comparison_operation},
+ [VSIR_OP_INEG] = {1, 1, vsir_validate_integer_elementwise_operation},
+ [VSIR_OP_IREM] = {1, 2, vsir_validate_integer_elementwise_operation},
+ [VSIR_OP_ISFINITE] = {1, 1, vsir_validate_float_comparison_operation},
+ [VSIR_OP_ISHL] = {1, 2, vsir_validate_shift_operation},
+ [VSIR_OP_ISHR] = {1, 2, vsir_validate_shift_operation},
+ [VSIR_OP_ISINF] = {1, 1, vsir_validate_float_comparison_operation},
+ [VSIR_OP_ISNAN] = {1, 1, vsir_validate_float_comparison_operation},
+ [VSIR_OP_ITOF] = {1, 1, vsir_validate_itof},
+ [VSIR_OP_ITOI] = {1, 1, vsir_validate_itoi},
+ [VSIR_OP_LABEL] = {0, 1, vsir_validate_label},
+ [VSIR_OP_LOG] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_LOOP] = {0, ~0u, vsir_validate_loop},
+ [VSIR_OP_LTO] = {1, 2, vsir_validate_float_comparison_operation},
+ [VSIR_OP_LTU] = {1, 2, vsir_validate_float_comparison_operation},
+ [VSIR_OP_MAD] = {1, 3, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_MAX] = {1, 2, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_MIN] = {1, 2, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_MUL] = {1, 2, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_NEO] = {1, 2, vsir_validate_float_comparison_operation},
+ [VSIR_OP_NEU] = {1, 2, vsir_validate_float_comparison_operation},
+ [VSIR_OP_NOP] = {0, 0, vsir_validate_nop},
+ [VSIR_OP_NOT] = {1, 1, vsir_validate_logic_elementwise_operation},
+ [VSIR_OP_OR] = {1, 2, vsir_validate_logic_elementwise_operation},
+ [VSIR_OP_ORD] = {1, 2, vsir_validate_float_comparison_operation},
+ [VSIR_OP_PHI] = {1, ~0u, vsir_validate_phi},
+ [VSIR_OP_RCP] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_REP] = {0, 1, vsir_validate_rep},
+ [VSIR_OP_RESINFO] = {1, 2, vsir_validate_resinfo},
+ [VSIR_OP_RET] = {0, 0, vsir_validate_ret},
+ [VSIR_OP_ROUND_NE] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_ROUND_NI] = {1, 1, vsir_validate_float_elementwise_operation},
+ [VSIR_OP_SAMPLE_INFO] = {1, 1, vsir_validate_sample_info},
+ [VSIR_OP_SWITCH] = {0, 1, vsir_validate_switch},
+ [VSIR_OP_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic},
};
static void vsir_validate_instruction(struct validation_context *ctx)
@@ -9691,28 +11856,28 @@ static void vsir_validate_instruction(struct validation_context *ctx)
for (i = 0; i < instruction->src_count; ++i)
vsir_validate_src_param(ctx, &instruction->src[i]);
- if (instruction->opcode >= VKD3DSIH_INVALID)
+ if (instruction->opcode >= VSIR_OP_INVALID)
{
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, "Invalid instruction handler %#x.",
- instruction->opcode);
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_OPCODE,
+ "Invalid opcode %#x.", instruction->opcode);
}
- if (version->type == VKD3D_SHADER_TYPE_HULL && ctx->phase == VKD3DSIH_INVALID)
+ if (version->type == VKD3D_SHADER_TYPE_HULL && ctx->phase == VSIR_OP_INVALID)
{
switch (instruction->opcode)
{
- case VKD3DSIH_NOP:
- case VKD3DSIH_HS_DECLS:
- case VKD3DSIH_HS_CONTROL_POINT_PHASE:
- case VKD3DSIH_HS_FORK_PHASE:
- case VKD3DSIH_HS_JOIN_PHASE:
+ case VSIR_OP_NOP:
+ case VSIR_OP_HS_DECLS:
+ case VSIR_OP_HS_CONTROL_POINT_PHASE:
+ case VSIR_OP_HS_FORK_PHASE:
+ case VSIR_OP_HS_JOIN_PHASE:
break;
default:
if (!vsir_instruction_is_dcl(instruction))
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER,
- "Instruction %#x appear before any phase instruction in a hull shader.",
- instruction->opcode);
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_OPCODE,
+ "Instruction \"%s\" (%#x) appears before any phase instruction in a hull shader.",
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
break;
}
}
@@ -9721,19 +11886,19 @@ static void vsir_validate_instruction(struct validation_context *ctx)
{
switch (instruction->opcode)
{
- case VKD3DSIH_NOP:
- case VKD3DSIH_LABEL:
- case VKD3DSIH_HS_DECLS:
- case VKD3DSIH_HS_CONTROL_POINT_PHASE:
- case VKD3DSIH_HS_FORK_PHASE:
- case VKD3DSIH_HS_JOIN_PHASE:
+ case VSIR_OP_NOP:
+ case VSIR_OP_LABEL:
+ case VSIR_OP_HS_DECLS:
+ case VSIR_OP_HS_CONTROL_POINT_PHASE:
+ case VSIR_OP_HS_FORK_PHASE:
+ case VSIR_OP_HS_JOIN_PHASE:
break;
default:
if (!vsir_instruction_is_dcl(instruction))
validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW,
- "Invalid instruction %#x outside any block.",
- instruction->opcode);
+ "Invalid instruction \"%s\" (%#x) outside any block.",
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
break;
}
}
@@ -9764,7 +11929,7 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c
.program = program,
.null_location = {.source_name = source_name},
.status = VKD3D_OK,
- .phase = VKD3DSIH_INVALID,
+ .phase = VSIR_OP_INVALID,
.invalid_instruction_idx = true,
.outer_tess_idxs[0] = ~0u,
.outer_tess_idxs[1] = ~0u,
@@ -9970,6 +12135,28 @@ enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uin
return ctx.result;
}
+enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_t config_flags,
+ const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
+{
+ struct vsir_transformation_context ctx =
+ {
+ .result = VKD3D_OK,
+ .program = program,
+ .config_flags = config_flags,
+ .compile_info = compile_info,
+ .message_context = message_context,
+ };
+
+ vsir_transform(&ctx, vsir_program_lower_d3dbc_instructions);
+ if (program->shader_version.major == 1 && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL)
+ vsir_transform(&ctx, vsir_program_normalise_ps1_output);
+
+ if (TRACE_ON())
+ vsir_program_trace(program);
+
+ return ctx.result;
+}
+
enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context)
{
@@ -9989,8 +12176,11 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t
vsir_transform(&ctx, vsir_program_materialise_phi_ssas_to_temps);
vsir_transform(&ctx, vsir_program_lower_switch_to_selection_ladder);
vsir_transform(&ctx, vsir_program_structurize);
- vsir_transform(&ctx, vsir_program_flatten_control_flow_constructs);
- vsir_transform(&ctx, vsir_program_materialize_undominated_ssas_to_temps);
+ if (compile_info->target_type != VKD3D_SHADER_TARGET_MSL)
+ {
+ vsir_transform(&ctx, vsir_program_flatten_control_flow_constructs);
+ vsir_transform(&ctx, vsir_program_materialize_undominated_ssas_to_temps);
+ }
}
else
{
diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c
index 4f37468af86..c6e048adb20 100644
--- a/libs/vkd3d/libs/vkd3d-shader/msl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c
@@ -18,6 +18,8 @@
#include "vkd3d_shader_private.h"
+#define MAX_IO_REG_COUNT 32
+
enum msl_data_type
{
MSL_DATA_FLOAT,
@@ -48,19 +50,29 @@ struct msl_generator
const char *prefix;
bool failed;
- bool write_depth;
+ bool read_vertex_id;
const struct vkd3d_shader_interface_info *interface_info;
};
struct msl_resource_type_info
{
- size_t read_coord_size;
+ /* The number of coordinates needed to address/sample the resource type. */
+ size_t coord_size;
+ /* Whether the resource type is an array type. */
bool array;
- bool lod;
+ /* Whether the resource type has a shadow/comparison variant. */
+ bool comparison;
+ /* Whether the resource type supports texel sample offsets. */
+ bool offset;
+ /* The type suffix for the resource type. I.e., the "2d_ms" part of
+ * "texture2d_ms_array" or "depth2d_ms_array". */
const char *type_suffix;
};
+static void msl_print_subscript(struct vkd3d_string_buffer *buffer, struct msl_generator *gen,
+ const struct vkd3d_shader_src_param *rel_addr, unsigned int offset);
+
static void VKD3D_PRINTF_FUNC(3, 4) msl_compiler_error(struct msl_generator *gen,
enum vkd3d_shader_error error, const char *fmt, ...)
{
@@ -76,17 +88,17 @@ static const struct msl_resource_type_info *msl_get_resource_type_info(enum vkd3
{
static const struct msl_resource_type_info info[] =
{
- [VKD3D_SHADER_RESOURCE_NONE] = {0, false, false, "none"},
- [VKD3D_SHADER_RESOURCE_BUFFER] = {1, false, false, "_buffer"},
- [VKD3D_SHADER_RESOURCE_TEXTURE_1D] = {1, false, false, "1d"},
- [VKD3D_SHADER_RESOURCE_TEXTURE_2D] = {2, false, true, "2d"},
- [VKD3D_SHADER_RESOURCE_TEXTURE_2DMS] = {2, false, false, "2d_ms"},
- [VKD3D_SHADER_RESOURCE_TEXTURE_3D] = {3, false, true, "3d"},
- [VKD3D_SHADER_RESOURCE_TEXTURE_CUBE] = {2, false, true, "cube"},
- [VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY] = {1, true, false, "1d_array"},
- [VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY] = {2, true, true, "2d_array"},
- [VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY] = {2, true, false, "2d_ms_array"},
- [VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY] = {2, true, true, "cube_array"},
+ [VKD3D_SHADER_RESOURCE_NONE] = {0, 0, 0, 0, "none"},
+ [VKD3D_SHADER_RESOURCE_BUFFER] = {1, 0, 0, 0, "_buffer"},
+ [VKD3D_SHADER_RESOURCE_TEXTURE_1D] = {1, 0, 0, 0, "1d"},
+ [VKD3D_SHADER_RESOURCE_TEXTURE_2D] = {2, 0, 1, 1, "2d"},
+ [VKD3D_SHADER_RESOURCE_TEXTURE_2DMS] = {2, 0, 1, 0, "2d_ms"},
+ [VKD3D_SHADER_RESOURCE_TEXTURE_3D] = {3, 0, 0, 1, "3d"},
+ [VKD3D_SHADER_RESOURCE_TEXTURE_CUBE] = {3, 0, 1, 0, "cube"},
+ [VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY] = {1, 1, 0, 0, "1d"},
+ [VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY] = {2, 1, 1, 1, "2d"},
+ [VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY] = {2, 1, 1, 0, "2d_ms"},
+ [VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY] = {3, 1, 1, 0, "cube"},
};
if (!t || t >= ARRAY_SIZE(info))
@@ -123,19 +135,19 @@ static void msl_print_indent(struct vkd3d_string_buffer *buffer, unsigned int in
}
static void msl_print_resource_datatype(struct msl_generator *gen,
- struct vkd3d_string_buffer *buffer, enum vkd3d_data_type data_type)
+ struct vkd3d_string_buffer *buffer, enum vsir_data_type data_type)
{
switch (data_type)
{
- case VKD3D_DATA_FLOAT:
- case VKD3D_DATA_UNORM:
- case VKD3D_DATA_SNORM:
+ case VSIR_DATA_F32:
+ case VSIR_DATA_SNORM:
+ case VSIR_DATA_UNORM:
vkd3d_string_buffer_printf(buffer, "float");
break;
- case VKD3D_DATA_INT:
+ case VSIR_DATA_I32:
vkd3d_string_buffer_printf(buffer, "int");
break;
- case VKD3D_DATA_UINT:
+ case VSIR_DATA_U32:
vkd3d_string_buffer_printf(buffer, "uint");
break;
default:
@@ -147,18 +159,18 @@ static void msl_print_resource_datatype(struct msl_generator *gen,
}
static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer,
- struct msl_generator *gen, enum vkd3d_data_type data_type)
+ struct msl_generator *gen, enum vsir_data_type data_type)
{
vkd3d_string_buffer_printf(buffer, ".");
switch (data_type)
{
- case VKD3D_DATA_FLOAT:
+ case VSIR_DATA_F32:
vkd3d_string_buffer_printf(buffer, "f");
break;
- case VKD3D_DATA_INT:
+ case VSIR_DATA_I32:
vkd3d_string_buffer_printf(buffer, "i");
break;
- case VKD3D_DATA_UINT:
+ case VSIR_DATA_U32:
vkd3d_string_buffer_printf(buffer, "u");
break;
default:
@@ -226,6 +238,35 @@ static const struct vkd3d_shader_descriptor_binding *msl_get_cbv_binding(const s
return NULL;
}
+static const struct vkd3d_shader_descriptor_binding *msl_get_sampler_binding(const struct msl_generator *gen,
+ unsigned int register_space, unsigned int register_idx)
+{
+ const struct vkd3d_shader_interface_info *interface_info = gen->interface_info;
+ const struct vkd3d_shader_resource_binding *binding;
+ unsigned int i;
+
+ if (!interface_info)
+ return NULL;
+
+ for (i = 0; i < interface_info->binding_count; ++i)
+ {
+ binding = &interface_info->bindings[i];
+
+ if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER)
+ continue;
+ if (binding->register_space != register_space)
+ continue;
+ if (binding->register_index != register_idx)
+ continue;
+ if (!msl_check_shader_visibility(gen, binding->shader_visibility))
+ continue;
+
+ return &binding->binding;
+ }
+
+ return NULL;
+}
+
static const struct vkd3d_shader_descriptor_binding *msl_get_srv_binding(const struct msl_generator *gen,
unsigned int register_space, unsigned int register_idx, enum vkd3d_shader_resource_type resource_type)
{
@@ -260,20 +301,71 @@ static const struct vkd3d_shader_descriptor_binding *msl_get_srv_binding(const s
return NULL;
}
+static const struct vkd3d_shader_descriptor_binding *msl_get_uav_binding(const struct msl_generator *gen,
+ unsigned int register_space, unsigned int register_idx, enum vkd3d_shader_resource_type resource_type)
+{
+ const struct vkd3d_shader_interface_info *interface_info = gen->interface_info;
+ const struct vkd3d_shader_resource_binding *binding;
+ enum vkd3d_shader_binding_flag resource_type_flag;
+ unsigned int i;
+
+ if (!interface_info)
+ return NULL;
+
+ resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER
+ ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE;
+
+ for (i = 0; i < interface_info->binding_count; ++i)
+ {
+ binding = &interface_info->bindings[i];
+
+ if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_UAV)
+ continue;
+ if (binding->register_space != register_space)
+ continue;
+ if (binding->register_index != register_idx)
+ continue;
+ if (!msl_check_shader_visibility(gen, binding->shader_visibility))
+ continue;
+ if (!(binding->flags & resource_type_flag))
+ continue;
+
+ return &binding->binding;
+ }
+
+ return NULL;
+}
+
static void msl_print_cbv_name(struct vkd3d_string_buffer *buffer, unsigned int binding)
{
vkd3d_string_buffer_printf(buffer, "descriptors[%u].buf<vkd3d_vec4>()", binding);
}
+static void msl_print_sampler_name(struct vkd3d_string_buffer *buffer, unsigned int binding)
+{
+ vkd3d_string_buffer_printf(buffer, "descriptors[%u].as<sampler>()", binding);
+}
+
static void msl_print_srv_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, unsigned int binding,
- const struct msl_resource_type_info *resource_type_info, enum vkd3d_data_type resource_data_type)
+ const struct msl_resource_type_info *resource_type_info, enum vsir_data_type resource_data_type, bool compare)
{
- vkd3d_string_buffer_printf(buffer, "descriptors[%u].tex<texture%s<",
- binding, resource_type_info->type_suffix);
+ vkd3d_string_buffer_printf(buffer, "descriptors[%u].as<%s%s%s<",
+ binding, compare ? "depth" : "texture", resource_type_info->type_suffix,
+ resource_type_info->array ? "_array" : "");
msl_print_resource_datatype(gen, buffer, resource_data_type);
vkd3d_string_buffer_printf(buffer, ">>()");
}
+static void msl_print_uav_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, unsigned int binding,
+ const struct msl_resource_type_info *resource_type_info, enum vsir_data_type resource_data_type)
+{
+ vkd3d_string_buffer_printf(buffer, "descriptors[%u].as<texture%s%s<",
+ binding, resource_type_info->type_suffix,
+ resource_type_info->array ? "_array" : "");
+ msl_print_resource_datatype(gen, buffer, resource_data_type);
+ vkd3d_string_buffer_printf(buffer, ", access::read_write>>()");
+}
+
static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *buffer,
struct msl_generator *gen, const struct vkd3d_shader_register *reg)
{
@@ -359,25 +451,40 @@ static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *bu
vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
return MSL_DATA_UNION;
}
- if (reg->idx[0].rel_addr || reg->idx[1].rel_addr || reg->idx[2].rel_addr)
+ if (reg->idx[0].rel_addr || reg->idx[1].rel_addr)
{
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
"Internal compiler error: Unhandled constant buffer register indirect addressing.");
vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
return MSL_DATA_UNION;
}
+ /* FIXME: This should use vkd3d_shader_find_descriptor() to
+ * find the resource index/space from the resource ID. */
if (!(binding = msl_get_cbv_binding(gen, 0, reg->idx[1].offset)))
{
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND,
- "Cannot finding binding for CBV register %u.", reg->idx[0].offset);
+ "No descriptor binding specified for CBV %u.", reg->idx[0].offset);
vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type);
return MSL_DATA_UNION;
}
msl_print_cbv_name(buffer, binding->binding);
- vkd3d_string_buffer_printf(buffer, "[%u]", reg->idx[2].offset);
+ msl_print_subscript(buffer, gen, reg->idx[2].rel_addr, reg->idx[2].offset);
return MSL_DATA_UNION;
}
+ case VKD3DSPR_IDXTEMP:
+ vkd3d_string_buffer_printf(buffer, "x%u", reg->idx[0].offset);
+ msl_print_subscript(buffer, gen, reg->idx[1].rel_addr, reg->idx[1].offset);
+ return MSL_DATA_UNION;
+
+ case VKD3DSPR_SAMPLEMASK:
+ if (gen->program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled sample coverage mask in shader type #%x.",
+ gen->program->shader_version.type);
+ vkd3d_string_buffer_printf(buffer, "o_mask");
+ return MSL_DATA_UNION;
+
default:
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
"Internal compiler error: Unhandled register type %#x.", reg->type);
@@ -418,21 +525,21 @@ static void msl_src_cleanup(struct msl_src *src, struct vkd3d_string_buffer_cach
}
static void msl_print_bitcast(struct vkd3d_string_buffer *dst, struct msl_generator *gen, const char *src,
- enum vkd3d_data_type dst_data_type, enum msl_data_type src_data_type, enum vsir_dimension dimension)
+ enum vsir_data_type dst_data_type, enum msl_data_type src_data_type, enum vsir_dimension dimension)
{
bool write_cast = false;
- if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM)
- dst_data_type = VKD3D_DATA_FLOAT;
+ if (dst_data_type == VSIR_DATA_UNORM || dst_data_type == VSIR_DATA_SNORM)
+ dst_data_type = VSIR_DATA_F32;
switch (src_data_type)
{
case MSL_DATA_FLOAT:
- write_cast = dst_data_type != VKD3D_DATA_FLOAT;
+ write_cast = dst_data_type != VSIR_DATA_F32;
break;
case MSL_DATA_UINT:
- write_cast = dst_data_type != VKD3D_DATA_UINT;
+ write_cast = dst_data_type != VSIR_DATA_U32;
break;
case MSL_DATA_UNION:
@@ -456,7 +563,7 @@ static void msl_print_bitcast(struct vkd3d_string_buffer *dst, struct msl_genera
}
static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct msl_generator *gen,
- const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vkd3d_data_type data_type)
+ const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vsir_data_type data_type)
{
const struct vkd3d_shader_register *reg = &vsir_src->reg;
struct vkd3d_string_buffer *register_name, *str;
@@ -488,6 +595,9 @@ static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct m
case VKD3DSPSM_ABS:
vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer);
break;
+ case VKD3DSPSM_ABSNEG:
+ vkd3d_string_buffer_printf(buffer, "-abs(%s)", str->buffer);
+ break;
default:
vkd3d_string_buffer_printf(buffer, "<unhandled modifier %#x>(%s)",
vsir_src->modifiers, str->buffer);
@@ -539,12 +649,34 @@ static uint32_t msl_dst_init(struct msl_dst *msl_dst, struct msl_generator *gen,
return write_mask;
}
+static void msl_print_subscript(struct vkd3d_string_buffer *buffer, struct msl_generator *gen,
+ const struct vkd3d_shader_src_param *rel_addr, unsigned int offset)
+{
+ struct msl_src r;
+
+ if (!rel_addr)
+ {
+ vkd3d_string_buffer_printf(buffer, "[%u]", offset);
+ return;
+ }
+
+ msl_src_init(&r, gen, rel_addr, VKD3DSP_WRITEMASK_0);
+ vkd3d_string_buffer_printf(buffer, "[%s", r.str->buffer);
+ if (offset)
+ vkd3d_string_buffer_printf(buffer, " + %u", offset);
+ vkd3d_string_buffer_printf(buffer, "]");
+ msl_src_cleanup(&r, &gen->string_buffers);
+}
+
static void VKD3D_PRINTF_FUNC(3, 4) msl_print_assignment(
struct msl_generator *gen, struct msl_dst *dst, const char *format, ...)
{
uint32_t modifiers = dst->vsir->modifiers;
va_list args;
+ /* It is always legitimate to ignore _pp. */
+ modifiers &= ~VKD3DSPDM_PARTIALPRECISION;
+
if (dst->vsir->shift)
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
"Internal compiler error: Unhandled destination shift %#x.", dst->vsir->shift);
@@ -570,10 +702,12 @@ static void VKD3D_PRINTF_FUNC(3, 4) msl_print_assignment(
static void msl_unhandled(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
{
+ const char *name = vsir_opcode_get_name(ins->opcode, "<unknown>");
+
msl_print_indent(gen->buffer, gen->indent);
- vkd3d_string_buffer_printf(gen->buffer, "/* <unhandled instruction %#x> */\n", ins->opcode);
+ vkd3d_string_buffer_printf(gen->buffer, "/* <unhandled instruction \"%s\" (%#x)> */\n", name, ins->opcode);
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
- "Internal compiler error: Unhandled instruction %#x.", ins->opcode);
+ "Internal compiler error: Unhandled instruction \"%s\" (%#x).", name, ins->opcode);
}
static void msl_binop(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *op)
@@ -695,19 +829,36 @@ static void msl_begin_block(struct msl_generator *gen)
++gen->indent;
}
-static void msl_if(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
+static void msl_print_condition(struct vkd3d_string_buffer *buffer, struct msl_generator *gen,
+ enum vkd3d_shader_conditional_op op, const struct vkd3d_shader_src_param *arg)
{
const char *condition;
struct msl_src src;
- msl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0);
+ msl_src_init(&src, gen, arg, VKD3DSP_WRITEMASK_0);
- msl_print_indent(gen->buffer, gen->indent);
- condition = ins->flags == VKD3D_SHADER_CONDITIONAL_OP_NZ ? "bool" : "!bool";
- vkd3d_string_buffer_printf(gen->buffer, "if (%s(%s))\n", condition, src.str->buffer);
+ condition = op == VKD3D_SHADER_CONDITIONAL_OP_NZ ? "bool" : "!bool";
+ vkd3d_string_buffer_printf(buffer, "if (%s(%s))\n", condition, src.str->buffer);
msl_src_cleanup(&src, &gen->string_buffers);
+}
+static void msl_discard(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
+{
+ /* Note that discard_fragment() in Metal 2.2 and earlier behaves like
+ * SPIR-V OpKill, while in Metal 2.3 and later it behaves like
+ * OpDemoteToHelperInvocationEXT. We assume we have at least Metal 3
+ * here. */
+ msl_print_indent(gen->buffer, gen->indent);
+ msl_print_condition(gen->buffer, gen, ins->flags, &ins->src[0]);
+ msl_print_indent(gen->buffer, gen->indent + 1);
+ vkd3d_string_buffer_printf(gen->buffer, "discard_fragment();\n");
+}
+
+static void msl_if(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
+{
+ msl_print_indent(gen->buffer, gen->indent);
+ msl_print_condition(gen->buffer, gen, ins->flags, &ins->src[0]);
msl_begin_block(gen);
}
@@ -719,6 +870,77 @@ static void msl_else(struct msl_generator *gen)
msl_begin_block(gen);
}
+static void msl_loop(struct msl_generator *gen)
+{
+ msl_print_indent(gen->buffer, gen->indent);
+ vkd3d_string_buffer_printf(gen->buffer, "for (;;)\n");
+ msl_begin_block(gen);
+}
+
+static void msl_break(struct msl_generator *gen)
+{
+ msl_print_indent(gen->buffer, gen->indent);
+ vkd3d_string_buffer_printf(gen->buffer, "break;\n");
+}
+
+static void msl_continue(struct msl_generator *gen)
+{
+ msl_print_indent(gen->buffer, gen->indent);
+ vkd3d_string_buffer_printf(gen->buffer, "continue;\n");
+}
+
+static void msl_switch(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
+{
+ struct msl_src src;
+
+ msl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0);
+
+ msl_print_indent(gen->buffer, gen->indent);
+ vkd3d_string_buffer_printf(gen->buffer, "switch (%s)\n", src.str->buffer);
+ msl_begin_block(gen);
+
+ msl_src_cleanup(&src, &gen->string_buffers);
+}
+
+static void msl_case(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
+{
+ struct msl_src src;
+
+ msl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0);
+
+ msl_print_indent(gen->buffer, gen->indent);
+ vkd3d_string_buffer_printf(gen->buffer, "case %s:\n", src.str->buffer);
+
+ msl_src_cleanup(&src, &gen->string_buffers);
+}
+
+static void msl_default(struct msl_generator *gen)
+{
+ msl_print_indent(gen->buffer, gen->indent);
+ vkd3d_string_buffer_printf(gen->buffer, "default:\n");
+}
+
+static void msl_print_texel_offset(struct vkd3d_string_buffer *buffer, struct msl_generator *gen,
+ unsigned int offset_size, const struct vkd3d_shader_texel_offset *offset)
+{
+ switch (offset_size)
+ {
+ case 1:
+ vkd3d_string_buffer_printf(buffer, "%d", offset->u);
+ break;
+ case 2:
+ vkd3d_string_buffer_printf(buffer, "int2(%d, %d)", offset->u, offset->v);
+ break;
+ default:
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Invalid texel offset size %u.", offset_size);
+ /* fall through */
+ case 3:
+ vkd3d_string_buffer_printf(buffer, "int3(%d, %d, %d)", offset->u, offset->v, offset->w);
+ break;
+ }
+}
+
static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
{
const struct msl_resource_type_info *resource_type_info;
@@ -726,9 +948,10 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct
const struct vkd3d_shader_descriptor_info1 *descriptor;
const struct vkd3d_shader_descriptor_binding *binding;
enum vkd3d_shader_resource_type resource_type;
+ uint32_t coord_mask, write_mask_size;
struct vkd3d_string_buffer *read;
- enum vkd3d_data_type data_type;
- uint32_t coord_mask;
+ enum vsir_data_type data_type;
+ unsigned int srv_binding;
struct msl_dst dst;
if (vkd3d_shader_instruction_has_texel_offset(ins))
@@ -754,47 +977,65 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct
"Internal compiler error: Undeclared resource descriptor %u.", resource_id);
resource_space = 0;
resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D;
- data_type = VKD3D_DATA_FLOAT;
+ data_type = VSIR_DATA_F32;
}
- if ((resource_type_info = msl_get_resource_type_info(resource_type)))
- {
- coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->read_coord_size);
- }
- else
+ if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_CUBE
+ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY
+ || (ins->opcode != VSIR_OP_LD2DMS
+ && (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS
+ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY)))
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED,
+ "Texel fetches from resource type %#x are not supported.", resource_type);
+
+ if (!(resource_type_info = msl_get_resource_type_info(resource_type)))
{
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
"Internal compiler error: Unhandled resource type %#x.", resource_type);
- coord_mask = vkd3d_write_mask_from_component_count(2);
+ resource_type_info = msl_get_resource_type_info(VKD3D_SHADER_RESOURCE_TEXTURE_2D);
}
+ coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size);
- if (!(binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type)))
+ if ((binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type)))
+ {
+ srv_binding = binding->binding;
+ }
+ else
{
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND,
- "Cannot finding binding for SRV register %u index %u space %u.",
+ "No descriptor binding specified for SRV %u (index %u, space %u).",
resource_id, resource_idx, resource_space);
- return;
+ srv_binding = 0;
}
msl_dst_init(&dst, gen, ins, &ins->dst[0]);
read = vkd3d_string_buffer_get(&gen->string_buffers);
- vkd3d_string_buffer_printf(read, "as_type<uint4>(");
- msl_print_srv_name(read, gen, binding->binding, resource_type_info, data_type);
+ vkd3d_string_buffer_printf(read, "as_type<");
+ msl_print_resource_datatype(gen, read, ins->dst[0].reg.data_type);
+ write_mask_size = vkd3d_popcount(ins->dst[0].write_mask);
+ if (write_mask_size != 1)
+ vkd3d_string_buffer_printf(read, "%u", write_mask_size);
+ vkd3d_string_buffer_printf(read, ">(");
+ msl_print_srv_name(read, gen, srv_binding, resource_type_info, data_type, false);
vkd3d_string_buffer_printf(read, ".read(");
- msl_print_src_with_type(read, gen, &ins->src[0], coord_mask, VKD3D_DATA_UINT);
+ msl_print_src_with_type(read, gen, &ins->src[0], coord_mask, VSIR_DATA_U32);
if (resource_type_info->array)
{
vkd3d_string_buffer_printf(read, ", ");
- msl_print_src_with_type(read, gen, &ins->src[0], coord_mask + 1, VKD3D_DATA_UINT);
+ msl_print_src_with_type(read, gen, &ins->src[0], coord_mask + 1, VSIR_DATA_U32);
}
- if (resource_type_info->lod)
+ if (resource_type != VKD3D_SHADER_RESOURCE_BUFFER)
{
vkd3d_string_buffer_printf(read, ", ");
- msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VKD3D_DATA_UINT);
+ if (ins->opcode != VSIR_OP_LD2DMS)
+ msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VSIR_DATA_U32);
+ else
+ msl_print_src_with_type(read, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, VSIR_DATA_U32);
}
- vkd3d_string_buffer_printf(read, "))");
+ vkd3d_string_buffer_printf(read, ")");
msl_print_swizzle(read, ins->src[1].swizzle, ins->dst[0].write_mask);
+ vkd3d_string_buffer_printf(read, ")");
msl_print_assignment(gen, &dst, "%s", read->buffer);
@@ -802,6 +1043,313 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct
msl_dst_cleanup(&dst, &gen->string_buffers);
}
+static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
+{
+ bool bias, compare, comparison_sampler, dynamic_offset, gather, grad, lod, lod_zero, offset;
+ const struct msl_resource_type_info *resource_type_info;
+ const struct vkd3d_shader_src_param *resource, *sampler;
+ unsigned int resource_id, resource_idx, resource_space;
+ const struct vkd3d_shader_descriptor_binding *binding;
+ unsigned int sampler_id, sampler_idx, sampler_space;
+ const struct vkd3d_shader_descriptor_info1 *d;
+ enum vkd3d_shader_resource_type resource_type;
+ unsigned int srv_binding, sampler_binding;
+ uint32_t coord_mask, write_mask_size;
+ struct vkd3d_string_buffer *sample;
+ enum vsir_data_type data_type;
+ unsigned int component_idx;
+ struct msl_dst dst;
+
+ bias = ins->opcode == VSIR_OP_SAMPLE_B;
+ compare = ins->opcode == VSIR_OP_GATHER4_C || ins->opcode == VSIR_OP_SAMPLE_C
+ || ins->opcode == VSIR_OP_SAMPLE_C_LZ;
+ dynamic_offset = ins->opcode == VSIR_OP_GATHER4_PO;
+ gather = ins->opcode == VSIR_OP_GATHER4 || ins->opcode == VSIR_OP_GATHER4_C
+ || ins->opcode == VSIR_OP_GATHER4_PO;
+ grad = ins->opcode == VSIR_OP_SAMPLE_GRAD;
+ lod = ins->opcode == VSIR_OP_SAMPLE_LOD;
+ lod_zero = ins->opcode == VSIR_OP_SAMPLE_C_LZ;
+ offset = dynamic_offset || vkd3d_shader_instruction_has_texel_offset(ins);
+
+ resource = &ins->src[1 + dynamic_offset];
+ sampler = &ins->src[2 + dynamic_offset];
+
+ if (resource->reg.idx[0].rel_addr || resource->reg.idx[1].rel_addr
+ || sampler->reg.idx[0].rel_addr || sampler->reg.idx[1].rel_addr)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED,
+ "Descriptor indexing is not supported.");
+
+ resource_id = resource->reg.idx[0].offset;
+ resource_idx = resource->reg.idx[1].offset;
+ if ((d = vkd3d_shader_find_descriptor(&gen->program->descriptors,
+ VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_id)))
+ {
+ resource_space = d->register_space;
+ resource_type = d->resource_type;
+ data_type = d->resource_data_type;
+ }
+ else
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Undeclared resource descriptor %u.", resource_id);
+ resource_space = 0;
+ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D;
+ data_type = VSIR_DATA_F32;
+ }
+
+ if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER
+ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS
+ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED,
+ "Sampling resource type %#x is not supported.", resource_type);
+
+ if ((resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_1D || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY)
+ && (bias || grad || lod || lod_zero))
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED,
+ "Resource type %#x does not support mipmapping.", resource_type);
+
+ if ((resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_1D || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY
+ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_3D) && gather)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED,
+ "Resource type %#x does not support gather operations.", resource_type);
+
+ if (!(resource_type_info = msl_get_resource_type_info(resource_type)))
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled resource type %#x.", resource_type);
+ resource_type_info = msl_get_resource_type_info(VKD3D_SHADER_RESOURCE_TEXTURE_2D);
+ }
+ coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size);
+
+ if ((binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type)))
+ {
+ srv_binding = binding->binding;
+ }
+ else
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND,
+ "No descriptor binding specified for SRV %u (index %u, space %u).",
+ resource_id, resource_idx, resource_space);
+ srv_binding = 0;
+ }
+
+ sampler_id = sampler->reg.idx[0].offset;
+ sampler_idx = sampler->reg.idx[1].offset;
+ if ((d = vkd3d_shader_find_descriptor(&gen->program->descriptors,
+ VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_id)))
+ {
+ sampler_space = d->register_space;
+ comparison_sampler = d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE;
+
+ if (compare)
+ {
+ if (!comparison_sampler)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Sampler %u is not a comparison sampler.", sampler_id);
+ }
+ else
+ {
+ if (comparison_sampler)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Sampler %u is a comparison sampler.", sampler_id);
+ }
+ }
+ else
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Undeclared sampler descriptor %u.", sampler_id);
+ sampler_space = 0;
+ }
+
+ if ((binding = msl_get_sampler_binding(gen, sampler_space, sampler_idx)))
+ {
+ sampler_binding = binding->binding;
+ }
+ else
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND,
+ "No descriptor binding specified for sampler %u (index %u, space %u).",
+ sampler_id, sampler_idx, sampler_space);
+ sampler_binding = 0;
+ }
+
+ msl_dst_init(&dst, gen, ins, &ins->dst[0]);
+ sample = vkd3d_string_buffer_get(&gen->string_buffers);
+
+ vkd3d_string_buffer_printf(sample, "as_type<");
+ msl_print_resource_datatype(gen, sample, ins->dst[0].reg.data_type);
+ write_mask_size = vkd3d_popcount(ins->dst[0].write_mask);
+ if (write_mask_size != 1)
+ vkd3d_string_buffer_printf(sample, "%u", write_mask_size);
+ vkd3d_string_buffer_printf(sample, ">(");
+ msl_print_srv_name(sample, gen, srv_binding, resource_type_info, data_type, compare);
+ if (gather && compare)
+ vkd3d_string_buffer_printf(sample, ".gather_compare(");
+ else if (gather)
+ vkd3d_string_buffer_printf(sample, ".gather(");
+ else if (compare)
+ vkd3d_string_buffer_printf(sample, ".sample_compare(");
+ else
+ vkd3d_string_buffer_printf(sample, ".sample(");
+ msl_print_sampler_name(sample, sampler_binding);
+ vkd3d_string_buffer_printf(sample, ", ");
+ msl_print_src_with_type(sample, gen, &ins->src[0], coord_mask, ins->src[0].reg.data_type);
+ if (resource_type_info->array)
+ {
+ vkd3d_string_buffer_printf(sample, ", uint(");
+ msl_print_src_with_type(sample, gen, &ins->src[0], coord_mask + 1, ins->src[0].reg.data_type);
+ vkd3d_string_buffer_printf(sample, ")");
+ }
+ if (compare)
+ {
+ if (!resource_type_info->comparison)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED,
+ "Comparison samplers are not supported with resource type %#x.", resource_type);
+ vkd3d_string_buffer_printf(sample, ", ");
+ msl_print_src_with_type(sample, gen, &ins->src[3], VKD3DSP_WRITEMASK_0, ins->src[3].reg.data_type);
+ }
+ if (grad)
+ {
+ vkd3d_string_buffer_printf(sample, ", gradient%s(", resource_type_info->type_suffix);
+ msl_print_src_with_type(sample, gen, &ins->src[3], coord_mask, ins->src[3].reg.data_type);
+ vkd3d_string_buffer_printf(sample, ", ");
+ msl_print_src_with_type(sample, gen, &ins->src[4], coord_mask, ins->src[4].reg.data_type);
+ vkd3d_string_buffer_printf(sample, ")");
+ }
+ if (lod_zero)
+ {
+ vkd3d_string_buffer_printf(sample, ", level(0.0f)");
+ }
+ else if (lod)
+ {
+ vkd3d_string_buffer_printf(sample, ", level(");
+ msl_print_src_with_type(sample, gen, &ins->src[3], VKD3DSP_WRITEMASK_0, ins->src[3].reg.data_type);
+ vkd3d_string_buffer_printf(sample, ")");
+ }
+ if (bias)
+ {
+ vkd3d_string_buffer_printf(sample, ", bias(");
+ msl_print_src_with_type(sample, gen, &ins->src[3], VKD3DSP_WRITEMASK_0, ins->src[3].reg.data_type);
+ vkd3d_string_buffer_printf(sample, ")");
+ }
+ if (offset)
+ {
+ if (!resource_type_info->offset)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED,
+ "Texel sample offsets are not supported with resource type %#x.", resource_type);
+ vkd3d_string_buffer_printf(sample, ", ");
+ if (dynamic_offset)
+ msl_print_src_with_type(sample, gen, &ins->src[1], coord_mask, ins->src[1].reg.data_type);
+ else
+ msl_print_texel_offset(sample, gen, resource_type_info->coord_size, &ins->texel_offset);
+ }
+ if (gather && !compare && (component_idx = vsir_swizzle_get_component(sampler->swizzle, 0)))
+ {
+ if (!offset && resource_type_info->offset)
+ vkd3d_string_buffer_printf(sample, ", int2(0)");
+ vkd3d_string_buffer_printf(sample, ", component::%c", "xyzw"[component_idx]);
+ }
+ vkd3d_string_buffer_printf(sample, ")");
+ if (!compare || gather)
+ msl_print_swizzle(sample, resource->swizzle, ins->dst[0].write_mask);
+ vkd3d_string_buffer_printf(sample, ")");
+
+ msl_print_assignment(gen, &dst, "%s", sample->buffer);
+
+ vkd3d_string_buffer_release(&gen->string_buffers, sample);
+ msl_dst_cleanup(&dst, &gen->string_buffers);
+}
+
+static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
+{
+ const struct msl_resource_type_info *resource_type_info;
+ const struct vkd3d_shader_descriptor_binding *binding;
+ const struct vkd3d_shader_descriptor_info1 *d;
+ enum vkd3d_shader_resource_type resource_type;
+ unsigned int uav_id, uav_idx, uav_space;
+ struct vkd3d_string_buffer *image_data;
+ enum vsir_data_type data_type;
+ unsigned int uav_binding;
+ uint32_t coord_mask;
+
+ if (ins->dst[0].reg.idx[0].rel_addr || ins->dst[0].reg.idx[1].rel_addr)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED,
+ "Descriptor indexing is not supported.");
+
+ uav_id = ins->dst[0].reg.idx[0].offset;
+ uav_idx = ins->dst[0].reg.idx[1].offset;
+ if ((d = vkd3d_shader_find_descriptor(&gen->program->descriptors,
+ VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, uav_id)))
+ {
+ uav_space = d->register_space;
+ resource_type = d->resource_type;
+ data_type = d->resource_data_type;
+ }
+ else
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Undeclared UAV descriptor %u.", uav_id);
+ uav_space = 0;
+ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D;
+ data_type = VSIR_DATA_F32;
+ }
+
+ if (!(resource_type_info = msl_get_resource_type_info(resource_type)))
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled resource type %#x.", resource_type);
+ resource_type_info = msl_get_resource_type_info(VKD3D_SHADER_RESOURCE_TEXTURE_2D);
+ }
+ coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size);
+
+ if ((binding = msl_get_uav_binding(gen, uav_space, uav_idx, resource_type)))
+ {
+ uav_binding = binding->binding;
+ }
+ else
+ {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND,
+ "No descriptor binding specified for UAV %u (index %u, space %u).",
+ uav_id, uav_idx, uav_space);
+ uav_binding = 0;
+ }
+
+ image_data = vkd3d_string_buffer_get(&gen->string_buffers);
+
+ if (ins->src[1].reg.dimension == VSIR_DIMENSION_SCALAR)
+ {
+ switch (data_type)
+ {
+ case VSIR_DATA_U32:
+ vkd3d_string_buffer_printf(image_data, "uint4(");
+ break;
+ case VSIR_DATA_I32:
+ vkd3d_string_buffer_printf(image_data, "int4(");
+ break;
+ default:
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled data type %#x.", data_type);
+ /* fall through */
+ case VSIR_DATA_F32:
+ case VSIR_DATA_SNORM:
+ case VSIR_DATA_UNORM:
+ vkd3d_string_buffer_printf(image_data, "float4(");
+ break;
+ }
+ }
+ msl_print_src_with_type(image_data, gen, &ins->src[1], VKD3DSP_WRITEMASK_ALL, data_type);
+ if (ins->src[1].reg.dimension == VSIR_DIMENSION_SCALAR)
+ vkd3d_string_buffer_printf(image_data, ", 0, 0, 0)");
+
+ msl_print_indent(gen->buffer, gen->indent);
+ msl_print_uav_name(gen->buffer, gen, uav_binding, resource_type_info, data_type);
+ vkd3d_string_buffer_printf(gen->buffer, ".write(%s, ", image_data->buffer);
+ msl_print_src_with_type(gen->buffer, gen, &ins->src[0], coord_mask, VSIR_DATA_U32);
+ vkd3d_string_buffer_printf(gen->buffer, ");\n");
+
+ vkd3d_string_buffer_release(&gen->string_buffers, image_data);
+}
+
static void msl_unary_op(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *op)
{
struct msl_src src;
@@ -863,128 +1411,209 @@ static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruc
vkd3d_string_buffer_printf(gen->buffer, "return;\n");
}
+static void msl_dcl_indexable_temp(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
+{
+ const char *type = ins->declaration.indexable_temp.component_count == 4 ? "vkd3d_vec4" : "vkd3d_scalar";
+ msl_print_indent(gen->buffer, gen->indent);
+ vkd3d_string_buffer_printf(gen->buffer, "%s x%u[%u];\n", type,
+ ins->declaration.indexable_temp.register_idx,
+ ins->declaration.indexable_temp.register_size);
+}
+
static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins)
{
gen->location = ins->location;
switch (ins->opcode)
{
- case VKD3DSIH_ADD:
+ case VSIR_OP_ADD:
+ case VSIR_OP_IADD:
msl_binop(gen, ins, "+");
break;
- case VKD3DSIH_AND:
+ case VSIR_OP_AND:
msl_binop(gen, ins, "&");
break;
- case VKD3DSIH_NOP:
+ case VSIR_OP_BREAK:
+ msl_break(gen);
+ break;
+ case VSIR_OP_CASE:
+ msl_case(gen, ins);
+ break;
+ case VSIR_OP_CONTINUE:
+ msl_continue(gen);
+ break;
+ case VSIR_OP_DCL_INDEXABLE_TEMP:
+ msl_dcl_indexable_temp(gen, ins);
+ break;
+ case VSIR_OP_NOP:
break;
- case VKD3DSIH_DIV:
+ case VSIR_OP_DEFAULT:
+ msl_default(gen);
+ break;
+ case VSIR_OP_DISCARD:
+ msl_discard(gen, ins);
+ break;
+ case VSIR_OP_DIV:
msl_binop(gen, ins, "/");
break;
- case VKD3DSIH_DP2:
+ case VSIR_OP_DP2:
msl_dot(gen, ins, vkd3d_write_mask_from_component_count(2));
break;
- case VKD3DSIH_DP3:
+ case VSIR_OP_DP3:
msl_dot(gen, ins, vkd3d_write_mask_from_component_count(3));
break;
- case VKD3DSIH_DP4:
+ case VSIR_OP_DP4:
msl_dot(gen, ins, VKD3DSP_WRITEMASK_ALL);
break;
- case VKD3DSIH_ELSE:
+ case VSIR_OP_DSX:
+ case VSIR_OP_DSX_COARSE:
+ case VSIR_OP_DSX_FINE:
+ /* dfdx() and dfdy() are specified to return "a high precision
+ * partial derivative", which would seem to correspond to
+ * DSX_FINE/DSY_FINE. As of MSL 3.2, coarse/fast variants don't
+ * appear to be available. */
+ msl_intrinsic(gen, ins, "dfdx");
+ break;
+ case VSIR_OP_DSY:
+ case VSIR_OP_DSY_COARSE:
+ case VSIR_OP_DSY_FINE:
+ msl_intrinsic(gen, ins, "dfdy");
+ break;
+ case VSIR_OP_ELSE:
msl_else(gen);
break;
- case VKD3DSIH_ENDIF:
+ case VSIR_OP_ENDIF:
+ case VSIR_OP_ENDLOOP:
+ case VSIR_OP_ENDSWITCH:
msl_end_block(gen);
break;
- case VKD3DSIH_IEQ:
+ case VSIR_OP_EQO:
+ case VSIR_OP_IEQ:
msl_relop(gen, ins, "==");
break;
- case VKD3DSIH_EXP:
+ case VSIR_OP_EXP:
msl_intrinsic(gen, ins, "exp2");
break;
- case VKD3DSIH_FRC:
+ case VSIR_OP_FRC:
msl_intrinsic(gen, ins, "fract");
break;
- case VKD3DSIH_FTOI:
+ case VSIR_OP_FTOI:
msl_cast(gen, ins, "int");
break;
- case VKD3DSIH_FTOU:
+ case VSIR_OP_FTOU:
msl_cast(gen, ins, "uint");
break;
- case VKD3DSIH_GEO:
+ case VSIR_OP_GATHER4:
+ case VSIR_OP_GATHER4_C:
+ case VSIR_OP_GATHER4_PO:
+ case VSIR_OP_SAMPLE:
+ case VSIR_OP_SAMPLE_B:
+ case VSIR_OP_SAMPLE_C:
+ case VSIR_OP_SAMPLE_C_LZ:
+ case VSIR_OP_SAMPLE_GRAD:
+ case VSIR_OP_SAMPLE_LOD:
+ msl_sample(gen, ins);
+ break;
+ case VSIR_OP_GEO:
+ case VSIR_OP_IGE:
msl_relop(gen, ins, ">=");
break;
- case VKD3DSIH_IF:
+ case VSIR_OP_IF:
msl_if(gen, ins);
break;
- case VKD3DSIH_ISHL:
+ case VSIR_OP_ISHL:
msl_binop(gen, ins, "<<");
break;
- case VKD3DSIH_ISHR:
- case VKD3DSIH_USHR:
+ case VSIR_OP_ISHR:
+ case VSIR_OP_USHR:
msl_binop(gen, ins, ">>");
break;
- case VKD3DSIH_LTO:
+ case VSIR_OP_ILT:
+ case VSIR_OP_LTO:
+ case VSIR_OP_ULT:
msl_relop(gen, ins, "<");
break;
- case VKD3DSIH_MAD:
+ case VSIR_OP_MAD:
msl_intrinsic(gen, ins, "fma");
break;
- case VKD3DSIH_MAX:
+ case VSIR_OP_IMAX:
+ case VSIR_OP_MAX:
+ case VSIR_OP_UMAX:
msl_intrinsic(gen, ins, "max");
break;
- case VKD3DSIH_MIN:
+ case VSIR_OP_MIN:
+ case VSIR_OP_UMIN:
msl_intrinsic(gen, ins, "min");
break;
- case VKD3DSIH_INE:
- case VKD3DSIH_NEU:
+ case VSIR_OP_IMUL_LOW:
+ msl_binop(gen, ins, "*");
+ break;
+ case VSIR_OP_INE:
+ case VSIR_OP_NEU:
msl_relop(gen, ins, "!=");
break;
- case VKD3DSIH_ITOF:
- case VKD3DSIH_UTOF:
+ case VSIR_OP_INEG:
+ msl_unary_op(gen, ins, "-");
+ break;
+ case VSIR_OP_ITOF:
+ case VSIR_OP_UTOF:
msl_cast(gen, ins, "float");
break;
- case VKD3DSIH_LD:
+ case VSIR_OP_LD:
+ case VSIR_OP_LD2DMS:
msl_ld(gen, ins);
break;
- case VKD3DSIH_LOG:
+ case VSIR_OP_LOG:
msl_intrinsic(gen, ins, "log2");
break;
- case VKD3DSIH_MOV:
+ case VSIR_OP_LOOP:
+ msl_loop(gen);
+ break;
+ case VSIR_OP_MOV:
msl_mov(gen, ins);
break;
- case VKD3DSIH_MOVC:
+ case VSIR_OP_MOVC:
msl_movc(gen, ins);
break;
- case VKD3DSIH_MUL:
+ case VSIR_OP_MUL:
msl_binop(gen, ins, "*");
break;
- case VKD3DSIH_NOT:
+ case VSIR_OP_NOT:
msl_unary_op(gen, ins, "~");
break;
- case VKD3DSIH_OR:
+ case VSIR_OP_OR:
msl_binop(gen, ins, "|");
break;
- case VKD3DSIH_RET:
+ case VSIR_OP_RET:
msl_ret(gen, ins);
break;
- case VKD3DSIH_ROUND_NE:
+ case VSIR_OP_ROUND_NE:
msl_intrinsic(gen, ins, "rint");
break;
- case VKD3DSIH_ROUND_NI:
+ case VSIR_OP_ROUND_NI:
msl_intrinsic(gen, ins, "floor");
break;
- case VKD3DSIH_ROUND_PI:
+ case VSIR_OP_ROUND_PI:
msl_intrinsic(gen, ins, "ceil");
break;
- case VKD3DSIH_ROUND_Z:
+ case VSIR_OP_ROUND_Z:
msl_intrinsic(gen, ins, "trunc");
break;
- case VKD3DSIH_RSQ:
+ case VSIR_OP_RSQ:
msl_intrinsic(gen, ins, "rsqrt");
break;
- case VKD3DSIH_SQRT:
+ case VSIR_OP_SQRT:
msl_intrinsic(gen, ins, "sqrt");
break;
+ case VSIR_OP_STORE_UAV_TYPED:
+ msl_store_uav_typed(gen, ins);
+ break;
+ case VSIR_OP_SWITCH:
+ msl_switch(gen, ins);
+ break;
+ case VSIR_OP_XOR:
+ msl_binop(gen, ins, "^");
+ break;
default:
msl_unhandled(gen, ins);
break;
@@ -996,6 +1625,7 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen)
const struct shader_signature *signature = &gen->program->input_signature;
enum vkd3d_shader_type type = gen->program->shader_version.type;
struct vkd3d_string_buffer *buffer = gen->buffer;
+ bool locations[MAX_IO_REG_COUNT] = {0};
const struct signature_element *e;
unsigned int i;
@@ -1008,21 +1638,60 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen)
if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED)
continue;
- if (e->sysval_semantic)
+ if (e->target_location >= ARRAY_SIZE(locations))
{
- if (e->sysval_semantic == VKD3D_SHADER_SV_IS_FRONT_FACE)
- {
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled input target location %u.", e->target_location);
+ continue;
+ }
+
+ if (locations[e->target_location])
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled duplicate input target location %u.", e->target_location);
+ locations[e->target_location] = true;
+
+ switch (e->sysval_semantic)
+ {
+ case VKD3D_SHADER_SV_NONE:
+ break;
+
+ case VKD3D_SHADER_SV_POSITION:
if (type != VKD3D_SHADER_TYPE_PIXEL)
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
- "Internal compiler error: Unhandled SV_IS_FRONT_FACE in shader type #%x.", type);
+ "Internal compiler error: Unhandled SV_POSITION in shader type #%x.", type);
+ msl_print_indent(gen->buffer, 1);
+ vkd3d_string_buffer_printf(buffer, "float4 position [[position]];\n");
+ continue;
+ case VKD3D_SHADER_SV_VERTEX_ID:
+ if (type != VKD3D_SHADER_TYPE_VERTEX)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled SV_VERTEX_ID in shader type #%x.", type);
+ gen->read_vertex_id = true;
+ continue;
+
+ case VKD3D_SHADER_SV_IS_FRONT_FACE:
+ if (type != VKD3D_SHADER_TYPE_PIXEL)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled SV_IS_FRONT_FACE in shader type #%x.", type);
msl_print_indent(gen->buffer, 1);
vkd3d_string_buffer_printf(buffer, "bool is_front_face [[front_facing]];\n");
continue;
- }
- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
- "Internal compiler error: Unhandled system value %#x.", e->sysval_semantic);
- continue;
+
+ case VKD3D_SHADER_SV_SAMPLE_INDEX:
+ if (type != VKD3D_SHADER_TYPE_PIXEL)
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled SV_SAMPLE_INDEX in shader type #%x.", type);
+ msl_print_indent(gen->buffer, 1);
+ vkd3d_string_buffer_printf(buffer, "uint sample_index [[sample_id]];\n");
+ continue;
+
+ default:
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled system value %#x.", e->sysval_semantic);
+ msl_print_indent(gen->buffer, 1);
+ vkd3d_string_buffer_printf(buffer, "<unhandled sysval %#x>;\n", e->sysval_semantic);
+ continue;
}
if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE)
@@ -1059,15 +1728,15 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen)
break;
}
- vkd3d_string_buffer_printf(buffer, "shader_in_%u ", i);
+ vkd3d_string_buffer_printf(buffer, "shader_in_%u [[", i);
switch (type)
{
case VKD3D_SHADER_TYPE_VERTEX:
- vkd3d_string_buffer_printf(gen->buffer, "[[attribute(%u)]]", e->target_location);
+ vkd3d_string_buffer_printf(gen->buffer, "attribute(%u)", e->target_location);
break;
case VKD3D_SHADER_TYPE_PIXEL:
- vkd3d_string_buffer_printf(gen->buffer, "[[user(locn%u)]]", e->target_location);
+ vkd3d_string_buffer_printf(gen->buffer, "user(locn%u)", e->target_location);
break;
default:
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
@@ -1081,13 +1750,16 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen)
case VKD3DSIM_LINEAR:
case VKD3DSIM_NONE:
break;
+ case VKD3DSIM_CONSTANT:
+ vkd3d_string_buffer_printf(gen->buffer, ", flat");
+ break;
default:
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
"Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode);
break;
}
- vkd3d_string_buffer_printf(buffer, ";\n");
+ vkd3d_string_buffer_printf(buffer, "]];\n");
}
vkd3d_string_buffer_printf(buffer, "};\n\n");
@@ -1129,6 +1801,7 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen)
const struct shader_signature *signature = &gen->program->output_signature;
enum vkd3d_shader_type type = gen->program->shader_version.type;
struct vkd3d_string_buffer *buffer = gen->buffer;
+ bool locations[MAX_IO_REG_COUNT] = {0};
const struct signature_element *e;
unsigned int i;
@@ -1138,28 +1811,26 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen)
{
e = &signature->elements[i];
- if (e->sysval_semantic == VKD3D_SHADER_SV_DEPTH)
- {
- gen->write_depth = true;
- msl_print_indent(gen->buffer, 1);
- vkd3d_string_buffer_printf(buffer, "float shader_out_depth [[depth(any)]];\n");
+ if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED
+ || e->sysval_semantic == VKD3D_SHADER_SV_DEPTH)
continue;
- }
- if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED)
- continue;
-
- if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE)
+ if (e->target_location >= ARRAY_SIZE(locations))
{
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
- "Internal compiler error: Unhandled minimum precision %#x.", e->min_precision);
+ "Internal compiler error: Unhandled input target location %u.", e->target_location);
continue;
}
- if (e->interpolation_mode != VKD3DSIM_NONE)
+ if (locations[e->target_location])
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled duplicate input target location %u.", e->target_location);
+ locations[e->target_location] = true;
+
+ if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE)
{
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
- "Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode);
+ "Internal compiler error: Unhandled minimum precision %#x.", e->min_precision);
continue;
}
@@ -1209,6 +1880,18 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen)
vkd3d_string_buffer_printf(buffer, ";\n");
}
+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_DEPTHOUT))
+ {
+ msl_print_indent(gen->buffer, 1);
+ vkd3d_string_buffer_printf(buffer, "float shader_out_depth [[depth(any)]];\n");
+ }
+
+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK))
+ {
+ msl_print_indent(gen->buffer, 1);
+ vkd3d_string_buffer_printf(buffer, "uint shader_out_mask [[sample_mask]];\n");
+ }
+
vkd3d_string_buffer_printf(buffer, "};\n\n");
}
@@ -1227,23 +1910,45 @@ static void msl_generate_entrypoint_prologue(struct msl_generator *gen)
continue;
vkd3d_string_buffer_printf(buffer, " %s_in[%u]", gen->prefix, e->register_index);
- if (e->sysval_semantic == VKD3D_SHADER_SV_NONE)
- {
- msl_print_register_datatype(buffer, gen, vkd3d_data_type_from_component_type(e->component_type));
- msl_print_write_mask(buffer, e->mask);
- vkd3d_string_buffer_printf(buffer, " = input.shader_in_%u", i);
- msl_print_write_mask(buffer, e->mask);
- }
- else if (e->sysval_semantic == VKD3D_SHADER_SV_IS_FRONT_FACE)
- {
- vkd3d_string_buffer_printf(buffer, ".u = uint4(input.is_front_face ? 0xffffffffu : 0u, 0, 0, 0)");
- }
- else
+ switch (e->sysval_semantic)
{
- vkd3d_string_buffer_printf(buffer, " = <unhandled sysval %#x>", e->sysval_semantic);
- msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
- "Internal compiler error: Unhandled system value %#x input.", e->sysval_semantic);
+ case VKD3D_SHADER_SV_NONE:
+ msl_print_register_datatype(buffer, gen, vsir_data_type_from_component_type(e->component_type));
+ msl_print_write_mask(buffer, e->mask);
+ vkd3d_string_buffer_printf(buffer, " = input.shader_in_%u", i);
+ break;
+
+ case VKD3D_SHADER_SV_POSITION:
+ msl_print_register_datatype(buffer, gen, VSIR_DATA_F32);
+ msl_print_write_mask(buffer, e->mask);
+ vkd3d_string_buffer_printf(buffer, " = float4(input.position.xyz, 1.0f / input.position.w)");
+ break;
+
+ case VKD3D_SHADER_SV_VERTEX_ID:
+ msl_print_register_datatype(buffer, gen, VSIR_DATA_U32);
+ msl_print_write_mask(buffer, e->mask);
+ vkd3d_string_buffer_printf(buffer, " = uint4(vertex_id, 0u, 0u, 0u)");
+ break;
+
+ case VKD3D_SHADER_SV_IS_FRONT_FACE:
+ msl_print_register_datatype(buffer, gen, VSIR_DATA_U32);
+ msl_print_write_mask(buffer, e->mask);
+ vkd3d_string_buffer_printf(buffer, " = uint4(input.is_front_face ? 0xffffffffu : 0u, 0, 0, 0)");
+ break;
+
+ case VKD3D_SHADER_SV_SAMPLE_INDEX:
+ msl_print_register_datatype(buffer, gen, VSIR_DATA_U32);
+ msl_print_write_mask(buffer, e->mask);
+ vkd3d_string_buffer_printf(buffer, " = uint4(input.sample_index, 0u, 0u, 0u)");
+ break;
+
+ default:
+ vkd3d_string_buffer_printf(buffer, " = <unhandled sysval %#x>", e->sysval_semantic);
+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
+ "Internal compiler error: Unhandled system value %#x input.", e->sysval_semantic);
+ break;
}
+ msl_print_write_mask(buffer, e->mask);
vkd3d_string_buffer_printf(buffer, ";\n");
}
}
@@ -1259,12 +1964,6 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen)
{
e = &signature->elements[i];
- if (e->sysval_semantic == VKD3D_SHADER_SV_DEPTH)
- {
- vkd3d_string_buffer_printf(buffer, " output.shader_out_depth = shader_out_depth;\n");
- continue;
- }
-
if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED)
continue;
@@ -1276,9 +1975,11 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen)
vkd3d_string_buffer_printf(buffer, " output.shader_out_%u", i);
msl_print_write_mask(buffer, e->mask);
vkd3d_string_buffer_printf(buffer, " = %s_out[%u]", gen->prefix, e->register_index);
- msl_print_register_datatype(buffer, gen, vkd3d_data_type_from_component_type(e->component_type));
+ msl_print_register_datatype(buffer, gen, vsir_data_type_from_component_type(e->component_type));
msl_print_write_mask(buffer, e->mask);
break;
+ case VKD3D_SHADER_SV_DEPTH:
+ continue;
default:
vkd3d_string_buffer_printf(buffer, " <unhandled sysval %#x>", e->sysval_semantic);
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
@@ -1286,6 +1987,9 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen)
}
vkd3d_string_buffer_printf(buffer, ";\n");
}
+
+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK))
+ vkd3d_string_buffer_printf(gen->buffer, " output.shader_out_mask = o_mask.u;\n");
}
static void msl_generate_entrypoint(struct msl_generator *gen)
@@ -1298,6 +2002,8 @@ static void msl_generate_entrypoint(struct msl_generator *gen)
vkd3d_string_buffer_printf(gen->buffer, "vertex ");
break;
case VKD3D_SHADER_TYPE_PIXEL:
+ if (gen->program->global_flags & VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL)
+ vkd3d_string_buffer_printf(gen->buffer, "[[early_fragment_tests]]\n");
vkd3d_string_buffer_printf(gen->buffer, "fragment ");
break;
default:
@@ -1316,25 +2022,35 @@ static void msl_generate_entrypoint(struct msl_generator *gen)
"constant descriptor *descriptors [[buffer(0)]],\n");
}
+ if (gen->read_vertex_id)
+ {
+ msl_print_indent(gen->buffer, 2);
+ vkd3d_string_buffer_printf(gen->buffer, "uint vertex_id [[vertex_id]],\n");
+ }
+
msl_print_indent(gen->buffer, 2);
vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_in input [[stage_in]])\n{\n", gen->prefix);
/* TODO: declare #maximum_register + 1 */
- vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_in[%u];\n", gen->prefix, 32);
- vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_out[%u];\n", gen->prefix, 32);
+ vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_in[%u];\n", gen->prefix, MAX_IO_REG_COUNT);
+ vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_out[%u];\n", gen->prefix, MAX_IO_REG_COUNT);
vkd3d_string_buffer_printf(gen->buffer, " vkd3d_%s_out output;\n", gen->prefix);
-
- if (gen->write_depth)
- vkd3d_string_buffer_printf(gen->buffer, " float shader_out_depth;\n");
+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK))
+ vkd3d_string_buffer_printf(gen->buffer, " vkd3d_scalar o_mask;\n");
+ vkd3d_string_buffer_printf(gen->buffer, "\n");
msl_generate_entrypoint_prologue(gen);
vkd3d_string_buffer_printf(gen->buffer, " %s_main(%s_in, %s_out", gen->prefix, gen->prefix, gen->prefix);
- if (gen->write_depth)
- vkd3d_string_buffer_printf(gen->buffer, ", shader_out_depth");
+ if (gen->read_vertex_id)
+ vkd3d_string_buffer_printf(gen->buffer, ", vertex_id");
+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_DEPTHOUT))
+ vkd3d_string_buffer_printf(gen->buffer, ", output.shader_out_depth");
+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK))
+ vkd3d_string_buffer_printf(gen->buffer, ", o_mask");
if (gen->program->descriptors.descriptor_count)
vkd3d_string_buffer_printf(gen->buffer, ", descriptors");
- vkd3d_string_buffer_printf(gen->buffer, ");\n");
+ vkd3d_string_buffer_printf(gen->buffer, ");\n\n");
msl_generate_entrypoint_epilogue(gen);
@@ -1343,8 +2059,8 @@ static void msl_generate_entrypoint(struct msl_generator *gen)
static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader_code *out)
{
- const struct vkd3d_shader_instruction_array *instructions = &gen->program->instructions;
- unsigned int i;
+ struct vkd3d_shader_instruction *ins;
+ struct vsir_program_iterator it;
MESSAGE("Generating a MSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n");
@@ -1353,10 +2069,15 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader
vkd3d_string_buffer_printf(gen->buffer, "#include <metal_texture>\n\n");
vkd3d_string_buffer_printf(gen->buffer, "using namespace metal;\n\n");
- if (gen->program->global_flags)
+ if (gen->program->global_flags & ~(VKD3DSGF_REFACTORING_ALLOWED | VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL))
msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL,
"Internal compiler error: Unhandled global flags %#"PRIx64".", (uint64_t)gen->program->global_flags);
+ vkd3d_string_buffer_printf(gen->buffer, "union vkd3d_scalar\n{\n");
+ vkd3d_string_buffer_printf(gen->buffer, " uint u;\n");
+ vkd3d_string_buffer_printf(gen->buffer, " int i;\n");
+ vkd3d_string_buffer_printf(gen->buffer, " float f;\n};\n\n");
+
vkd3d_string_buffer_printf(gen->buffer, "union vkd3d_vec4\n{\n");
vkd3d_string_buffer_printf(gen->buffer, " uint4 u;\n");
vkd3d_string_buffer_printf(gen->buffer, " int4 i;\n");
@@ -1370,7 +2091,7 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader
" const device void *ptr;\n"
"\n"
" template<typename T>\n"
- " constant T &tex() constant\n"
+ " constant T &as() constant\n"
" {\n"
" return reinterpret_cast<constant T &>(this->ptr);\n"
" }\n"
@@ -1388,11 +2109,16 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader
msl_generate_output_struct_declarations(gen);
vkd3d_string_buffer_printf(gen->buffer,
- "void %s_main(thread vkd3d_vec4 *v, "
+ "static void %s_main(thread vkd3d_vec4 *v, "
"thread vkd3d_vec4 *o",
gen->prefix);
- if (gen->write_depth)
- vkd3d_string_buffer_printf(gen->buffer, ", thread float& o_depth");
+
+ if (gen->read_vertex_id)
+ vkd3d_string_buffer_printf(gen->buffer, ", uint vertex_id");
+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_DEPTHOUT))
+ vkd3d_string_buffer_printf(gen->buffer, ", thread float &o_depth");
+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK))
+ vkd3d_string_buffer_printf(gen->buffer, ", thread vkd3d_scalar &o_mask");
if (gen->program->descriptors.descriptor_count)
vkd3d_string_buffer_printf(gen->buffer, ", constant descriptor *descriptors");
vkd3d_string_buffer_printf(gen->buffer, ")\n{\n");
@@ -1405,9 +2131,10 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader
vkd3d_string_buffer_printf(gen->buffer, "vkd3d_vec4 r[%u];\n\n", gen->program->temp_count);
}
- for (i = 0; i < instructions->count; ++i)
+ it = vsir_program_iterator(&gen->program->instructions);
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- msl_handle_instruction(gen, &instructions->elements[i]);
+ msl_handle_instruction(gen, ins);
}
--gen->indent;
@@ -1469,6 +2196,9 @@ int msl_compile(struct vsir_program *program, uint64_t config_flags,
if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0)
return ret;
+ if ((ret = vsir_allocate_temp_registers(program, message_context)) < 0)
+ return ret;
+
VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6);
VKD3D_ASSERT(program->has_descriptor_info);
diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.h b/libs/vkd3d/libs/vkd3d-shader/preproc.h
index a98c8ae3df5..9217237d8d3 100644
--- a/libs/vkd3d/libs/vkd3d-shader/preproc.h
+++ b/libs/vkd3d/libs/vkd3d-shader/preproc.h
@@ -38,6 +38,7 @@ struct preproc_buffer
{
void *lexer_buffer;
struct vkd3d_shader_location location;
+ bool eof;
};
struct preproc_file
@@ -125,7 +126,6 @@ struct preproc_ctx
int lookahead_token;
bool last_was_newline;
- bool last_was_eof;
bool last_was_defined;
bool error;
diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l
index 4a8d0fddae1..5c56fba0229 100644
--- a/libs/vkd3d/libs/vkd3d-shader/preproc.l
+++ b/libs/vkd3d/libs/vkd3d-shader/preproc.l
@@ -20,6 +20,7 @@
%{
+#include "preproc.h"
#include "preproc.tab.h"
#undef ERROR /* defined in wingdi.h */
@@ -71,8 +72,8 @@ INT_SUFFIX [uUlL]{0,2}
%%
-<INITIAL>"//" {yy_push_state(CXX_COMMENT, yyscanner);}
-<INITIAL>"/*" {yy_push_state(C_COMMENT, yyscanner);}
+<INITIAL,INCLUDE,LINE>"//" {yy_push_state(CXX_COMMENT, yyscanner);}
+<INITIAL,INCLUDE,LINE>"/*" {yy_push_state(C_COMMENT, yyscanner);}
<CXX_COMMENT>\\{NEWLINE} {}
<CXX_COMMENT>\n {
yy_pop_state(yyscanner);
@@ -80,7 +81,11 @@ INT_SUFFIX [uUlL]{0,2}
return T_NEWLINE;
}
<C_COMMENT>"*/" {yy_pop_state(yyscanner);}
-<C_COMMENT,CXX_COMMENT><<EOF>> {yy_pop_state(yyscanner);}
+<C_COMMENT,CXX_COMMENT><<EOF>> {
+ yy_pop_state(yyscanner);
+ BEGIN(INITIAL);
+ yyterminate();
+ }
<C_COMMENT,CXX_COMMENT>. {}
<C_COMMENT>\n {}
@@ -196,6 +201,10 @@ INT_SUFFIX [uUlL]{0,2}
BEGIN(INITIAL);
return T_NEWLINE;
}
+<INITIAL,INCLUDE,ERROR,LINE><<EOF>> {
+ BEGIN(INITIAL);
+ yyterminate();
+ }
<INITIAL,INCLUDE,LINE>{WS}+ {}
<INITIAL>[-()\[\]{},+!*/<>&|^?:] {return yytext[0];}
@@ -250,8 +259,19 @@ static bool should_concat(struct preproc_ctx *ctx)
return !macro || macro->arg_count;
}
+static struct preproc_buffer *preproc_get_top_buffer(struct preproc_ctx *ctx)
+{
+ if (ctx->expansion_count)
+ return &ctx->expansion_stack[ctx->expansion_count - 1].buffer;
+ if (ctx->file_count)
+ return &ctx->file_stack[ctx->file_count - 1].buffer;
+ return NULL;
+}
+
static void preproc_pop_buffer(struct preproc_ctx *ctx)
{
+ struct preproc_buffer *buffer;
+
if (ctx->expansion_count)
{
struct preproc_expansion *exp = &ctx->expansion_stack[ctx->expansion_count - 1];
@@ -290,10 +310,8 @@ static void preproc_pop_buffer(struct preproc_ctx *ctx)
TRACE("File stack size is now %zu.\n", ctx->file_count);
}
- if (ctx->expansion_count)
- yy_switch_to_buffer(ctx->expansion_stack[ctx->expansion_count - 1].buffer.lexer_buffer, ctx->scanner);
- else if (ctx->file_count)
- yy_switch_to_buffer(ctx->file_stack[ctx->file_count - 1].buffer.lexer_buffer, ctx->scanner);
+ if ((buffer = preproc_get_top_buffer(ctx)))
+ yy_switch_to_buffer(buffer->lexer_buffer, ctx->scanner);
}
static int return_token(int token, YYSTYPE *lval, const char *text)
@@ -347,6 +365,7 @@ static bool preproc_push_expansion(struct preproc_ctx *ctx,
exp->text = text;
exp->buffer.lexer_buffer = yy_scan_bytes(text->text.buffer, text->text.content_size, ctx->scanner);
exp->buffer.location = text->location;
+ exp->buffer.eof = false;
exp->macro = macro;
exp->arg_values = arg_values;
TRACE("Expansion stack size is now %zu.\n", ctx->expansion_count);
@@ -407,18 +426,17 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
}
else
{
- if (ctx->last_was_eof)
+ if (preproc_get_top_buffer(ctx)->eof)
{
preproc_pop_buffer(ctx);
if (!ctx->file_count)
return 0;
}
- ctx->last_was_eof = false;
VKD3D_ASSERT(ctx->file_count);
if (!(token = preproc_lexer_lex(lval, lloc, scanner)))
{
- ctx->last_was_eof = true;
+ preproc_get_top_buffer(ctx)->eof = true;
/* If we have reached the end of an included file, inject a newline. */
if (ctx->expansion_count)
@@ -781,6 +799,7 @@ bool preproc_push_include(struct preproc_ctx *ctx, char *filename, const struct
file->buffer.location.source_name = file->filename;
file->buffer.location.line = 1;
file->buffer.location.column = 1;
+ file->buffer.eof = false;
TRACE("File stack size is now %zu.\n", ctx->file_count);
ctx->last_was_newline = true;
return true;
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index 1f967c22406..a4990d982bc 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -847,57 +847,6 @@ static void vkd3d_spirv_dump(const struct vkd3d_shader_code *spirv, enum vkd3d_s
vkd3d_shader_message_context_cleanup(&message_context);
}
-enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval,
- unsigned int index)
-{
- switch (sysval)
- {
- case VKD3D_SHADER_SV_COVERAGE:
- case VKD3D_SHADER_SV_DEPTH:
- case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL:
- case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL:
- case VKD3D_SHADER_SV_NONE:
- case VKD3D_SHADER_SV_STENCIL_REF:
- case VKD3D_SHADER_SV_TARGET:
- return VKD3D_SIV_NONE;
- case VKD3D_SHADER_SV_POSITION:
- return VKD3D_SIV_POSITION;
- case VKD3D_SHADER_SV_CLIP_DISTANCE:
- return VKD3D_SIV_CLIP_DISTANCE;
- case VKD3D_SHADER_SV_CULL_DISTANCE:
- return VKD3D_SIV_CULL_DISTANCE;
- case VKD3D_SHADER_SV_INSTANCE_ID:
- return VKD3D_SIV_INSTANCE_ID;
- case VKD3D_SHADER_SV_IS_FRONT_FACE:
- return VKD3D_SIV_IS_FRONT_FACE;
- case VKD3D_SHADER_SV_PRIMITIVE_ID:
- return VKD3D_SIV_PRIMITIVE_ID;
- case VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX:
- return VKD3D_SIV_RENDER_TARGET_ARRAY_INDEX;
- case VKD3D_SHADER_SV_SAMPLE_INDEX:
- return VKD3D_SIV_SAMPLE_INDEX;
- case VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE:
- return VKD3D_SIV_QUAD_U0_TESS_FACTOR + index;
- case VKD3D_SHADER_SV_TESS_FACTOR_QUADINT:
- return VKD3D_SIV_QUAD_U_INNER_TESS_FACTOR + index;
- case VKD3D_SHADER_SV_TESS_FACTOR_TRIEDGE:
- return VKD3D_SIV_TRIANGLE_U_TESS_FACTOR + index;
- case VKD3D_SHADER_SV_TESS_FACTOR_TRIINT:
- return VKD3D_SIV_TRIANGLE_INNER_TESS_FACTOR;
- case VKD3D_SHADER_SV_TESS_FACTOR_LINEDET:
- return VKD3D_SIV_LINE_DETAIL_TESS_FACTOR;
- case VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN:
- return VKD3D_SIV_LINE_DENSITY_TESS_FACTOR;
- case VKD3D_SHADER_SV_VERTEX_ID:
- return VKD3D_SIV_VERTEX_ID;
- case VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX:
- return VKD3D_SIV_VIEWPORT_ARRAY_INDEX;
- default:
- FIXME("Unhandled sysval %#x, index %u.\n", sysval, index);
- return VKD3D_SIV_NONE;
- }
-}
-
struct vkd3d_spirv_stream
{
uint32_t *words;
@@ -1033,6 +982,7 @@ struct vkd3d_spirv_builder
SpvExecutionModel execution_model;
uint32_t current_id;
+ uint32_t source_name_id;
uint32_t main_function_id;
struct rb_tree declarations;
uint32_t type_sampler_id;
@@ -1602,6 +1552,34 @@ static void vkd3d_spirv_build_op_name(struct vkd3d_spirv_builder *builder,
vkd3d_spirv_build_string(stream, name, name_size);
}
+static uint32_t vkd3d_spirv_build_op_string(struct vkd3d_spirv_builder *builder, const char *s)
+{
+ struct vkd3d_spirv_stream *stream = &builder->debug_stream;
+ uint32_t result_id = vkd3d_spirv_alloc_id(builder);
+ unsigned int size;
+
+ size = vkd3d_spirv_string_word_count(s);
+ vkd3d_spirv_build_word(stream, vkd3d_spirv_opcode_word(SpvOpString, 2 + size));
+ vkd3d_spirv_build_word(stream, result_id);
+ vkd3d_spirv_build_string(stream, s, size);
+
+ return result_id;
+}
+
+static void vkd3d_spirv_build_op_source(struct vkd3d_spirv_builder *builder, const char *source_name)
+{
+ struct vkd3d_spirv_stream *stream = &builder->debug_stream;
+
+ builder->source_name_id = vkd3d_spirv_build_op_string(builder, source_name ? source_name : "<anonymous>");
+ vkd3d_spirv_build_op3(stream, SpvOpSource, 0, 0, builder->source_name_id);
+}
+
+static void vkd3d_spirv_build_op_line(struct vkd3d_spirv_builder *builder, const struct vkd3d_shader_location *location)
+{
+ vkd3d_spirv_build_op3(&builder->function_stream, SpvOpLine,
+ builder->source_name_id, location->line, location->column);
+}
+
static void vkd3d_spirv_build_op_member_name(struct vkd3d_spirv_builder *builder,
uint32_t type_id, uint32_t member, const char *fmt, ...)
{
@@ -2513,18 +2491,6 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_fabs(struct vkd3d_spirv_builder
return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450FAbs, result_type, operand);
}
-static uint32_t vkd3d_spirv_build_op_glsl_std450_sin(struct vkd3d_spirv_builder *builder,
- uint32_t result_type, uint32_t operand)
-{
- return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450Sin, result_type, operand);
-}
-
-static uint32_t vkd3d_spirv_build_op_glsl_std450_cos(struct vkd3d_spirv_builder *builder,
- uint32_t result_type, uint32_t operand)
-{
- return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450Cos, result_type, operand);
-}
-
static uint32_t vkd3d_spirv_build_op_glsl_std450_max(struct vkd3d_spirv_builder *builder,
uint32_t result_type, uint32_t x, uint32_t y)
{
@@ -2608,7 +2574,7 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder,
}
static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder *builder,
- enum vkd3d_data_type data_type, unsigned int component_count)
+ enum vsir_data_type data_type, unsigned int component_count)
{
enum vkd3d_shader_component_type component_type;
@@ -2616,7 +2582,8 @@ static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder
return vkd3d_spirv_get_type_id(builder, component_type, component_count);
}
-static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, const char *entry_point)
+static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder,
+ const char *entry_point, const char *source_name)
{
vkd3d_spirv_stream_init(&builder->debug_stream);
vkd3d_spirv_stream_init(&builder->annotation_stream);
@@ -2631,6 +2598,7 @@ static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, const
rb_init(&builder->declarations, vkd3d_spirv_declaration_compare);
+ vkd3d_spirv_build_op_source(builder, source_name);
builder->main_function_id = vkd3d_spirv_alloc_id(builder);
vkd3d_spirv_build_op_name(builder, builder->main_function_id, "%s", entry_point);
}
@@ -3050,7 +3018,7 @@ struct vkd3d_hull_shader_variables
struct ssa_register_info
{
- enum vkd3d_data_type data_type;
+ enum vsir_data_type data_type;
uint8_t write_mask;
uint32_t id;
};
@@ -3058,7 +3026,7 @@ struct ssa_register_info
struct spirv_compiler
{
struct vkd3d_spirv_builder spirv_builder;
- const struct vsir_program *program;
+ struct vsir_program *program;
struct vkd3d_shader_message_context *message_context;
struct vkd3d_shader_location location;
@@ -3140,17 +3108,17 @@ struct spirv_compiler
static bool is_in_default_phase(const struct spirv_compiler *compiler)
{
- return compiler->phase == VKD3DSIH_INVALID;
+ return compiler->phase == VSIR_OP_INVALID;
}
static bool is_in_control_point_phase(const struct spirv_compiler *compiler)
{
- return compiler->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE;
+ return compiler->phase == VSIR_OP_HS_CONTROL_POINT_PHASE;
}
static bool is_in_fork_or_join_phase(const struct spirv_compiler *compiler)
{
- return compiler->phase == VKD3DSIH_HS_FORK_PHASE || compiler->phase == VKD3DSIH_HS_JOIN_PHASE;
+ return compiler->phase == VSIR_OP_HS_FORK_PHASE || compiler->phase == VSIR_OP_HS_JOIN_PHASE;
}
static void spirv_compiler_emit_initial_declarations(struct spirv_compiler *compiler);
@@ -3188,7 +3156,7 @@ static void spirv_compiler_destroy(struct spirv_compiler *compiler)
vkd3d_free(compiler);
}
-static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *program,
+static struct spirv_compiler *spirv_compiler_create(struct vsir_program *program,
const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_message_context *message_context, uint64_t config_flags)
{
@@ -3224,7 +3192,8 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p
compiler->spirv_target_info = target_info;
}
- vkd3d_spirv_builder_init(&compiler->spirv_builder, spirv_compiler_get_entry_point_name(compiler));
+ vkd3d_spirv_builder_init(&compiler->spirv_builder,
+ spirv_compiler_get_entry_point_name(compiler), compile_info->source_name);
compiler->formatting = VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT
| VKD3D_SHADER_COMPILE_OPTION_FORMATTING_HEADER;
@@ -3332,7 +3301,7 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p
else if (compiler->shader_type != VKD3D_SHADER_TYPE_GEOMETRY)
compiler->emit_point_size = compiler->xfb_info && compiler->xfb_info->element_count;
- compiler->phase = VKD3DSIH_INVALID;
+ compiler->phase = VSIR_OP_INVALID;
vkd3d_string_buffer_cache_init(&compiler->string_buffers);
@@ -3559,8 +3528,12 @@ static struct vkd3d_shader_descriptor_binding spirv_compiler_get_descriptor_bind
goto done;
}
- resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER
- ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE;
+ if (resource_type == VKD3D_SHADER_RESOURCE_NONE)
+ resource_type_flag = 0;
+ else if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER)
+ resource_type_flag = VKD3D_SHADER_BINDING_FLAG_BUFFER;
+ else
+ resource_type_flag = VKD3D_SHADER_BINDING_FLAG_IMAGE;
if (is_uav_counter)
{
@@ -3604,7 +3577,7 @@ static struct vkd3d_shader_descriptor_binding spirv_compiler_get_descriptor_bind
{
const struct vkd3d_shader_resource_binding *current = &shader_interface->bindings[i];
- if (!(current->flags & resource_type_flag))
+ if ((current->flags & resource_type_flag) != resource_type_flag)
continue;
if (!spirv_compiler_check_shader_visibility(compiler, current->shader_visibility))
@@ -4018,7 +3991,7 @@ static uint32_t spirv_compiler_alloc_spec_constant_id(struct spirv_compiler *com
static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compiler,
enum vkd3d_shader_parameter_name name, uint32_t spec_id,
- enum vkd3d_data_type type, unsigned int component_count)
+ enum vsir_data_type type, unsigned int component_count)
{
uint32_t scalar_type_id, vector_type_id, id, default_value, components[4];
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
@@ -4057,7 +4030,7 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile
static uint32_t spirv_compiler_get_spec_constant(struct spirv_compiler *compiler,
enum vkd3d_shader_parameter_name name, uint32_t spec_id,
- enum vkd3d_data_type type, unsigned int component_count)
+ enum vsir_data_type type, unsigned int component_count)
{
unsigned int i;
@@ -4071,7 +4044,7 @@ static uint32_t spirv_compiler_get_spec_constant(struct spirv_compiler *compiler
}
static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compiler,
- const struct vkd3d_shader_parameter1 *parameter, enum vkd3d_data_type type, unsigned int component_count)
+ const struct vkd3d_shader_parameter1 *parameter, enum vsir_data_type type, unsigned int component_count)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
unsigned int index = parameter - compiler->program->parameters;
@@ -4087,18 +4060,18 @@ static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compi
static const struct
{
- enum vkd3d_data_type type;
+ enum vsir_data_type type;
unsigned int component_count;
}
parameter_data_type_map[] =
{
- [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32] = {VKD3D_DATA_FLOAT, 1},
- [VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32] = {VKD3D_DATA_UINT, 1},
- [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4] = {VKD3D_DATA_FLOAT, 4},
+ [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32] = {VSIR_DATA_F32, 1},
+ [VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32] = {VSIR_DATA_U32, 1},
+ [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4] = {VSIR_DATA_F32, 4},
};
static uint32_t spirv_compiler_emit_shader_parameter(struct spirv_compiler *compiler,
- enum vkd3d_shader_parameter_name name, enum vkd3d_data_type type, unsigned int component_count)
+ enum vkd3d_shader_parameter_name name, enum vsir_data_type type, unsigned int component_count)
{
const struct vkd3d_shader_parameter1 *parameter;
@@ -4239,7 +4212,7 @@ static bool spirv_compiler_get_register_info(struct spirv_compiler *compiler,
if (!(entry = rb_get(&compiler->symbol_table, &reg_symbol)))
{
spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE,
- "Unrecognized register (%s).\n", debug_vkd3d_symbol(&reg_symbol));
+ "Unrecognized register (%s).", debug_vkd3d_symbol(&reg_symbol));
memset(register_info, 0, sizeof(*register_info));
return false;
}
@@ -4512,7 +4485,7 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil
}
static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler,
- enum vkd3d_shader_conditional_op condition, enum vkd3d_data_type data_type,
+ enum vkd3d_shader_conditional_op condition, enum vsir_data_type data_type,
unsigned int component_count, uint32_t val_id)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
@@ -4524,7 +4497,7 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler,
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count);
op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual;
return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id,
- data_type == VKD3D_DATA_UINT64
+ data_type == VSIR_DATA_U64
? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count)
: spirv_compiler_get_constant_uint_vector(compiler, 0, component_count));
}
@@ -4578,70 +4551,6 @@ static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compil
return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id);
}
-/* Based on the implementation in the OpenGL Mathematics library. */
-static uint32_t half_to_float(uint16_t value)
-{
- uint32_t s = (value & 0x8000u) << 16;
- uint32_t e = (value >> 10) & 0x1fu;
- uint32_t m = value & 0x3ffu;
-
- if (!e)
- {
- if (!m)
- {
- /* Plus or minus zero */
- return s;
- }
- else
- {
- /* Denormalized number -- renormalize it */
-
- while (!(m & 0x400u))
- {
- m <<= 1;
- --e;
- }
-
- ++e;
- m &= ~0x400u;
- }
- }
- else if (e == 31u)
- {
- /* Positive or negative infinity for zero 'm'.
- * Nan for non-zero 'm' -- preserve sign and significand bits */
- return s | 0x7f800000u | (m << 13);
- }
-
- /* Normalized number */
- e += 127u - 15u;
- m <<= 13;
-
- /* Assemble s, e and m. */
- return s | (e << 23) | m;
-}
-
-static uint32_t convert_raw_constant32(enum vkd3d_data_type data_type, unsigned int uint_value)
-{
- int16_t i;
-
- /* TODO: native 16-bit support. */
- if (data_type != VKD3D_DATA_UINT16 && data_type != VKD3D_DATA_HALF)
- return uint_value;
-
- if (data_type == VKD3D_DATA_HALF)
- return half_to_float(uint_value);
-
- /* Values in DXIL have no signedness, so it is ambiguous whether 16-bit constants should or
- * should not be sign-extended when 16-bit execution is not supported. The AMD RX 580 Windows
- * driver has no 16-bit support, and sign-extends all 16-bit constant ints to 32 bits. These
- * results differ from SM 5. The RX 6750 XT supports 16-bit execution, so constants are not
- * extended, and results match SM 5. It seems best to replicate the sign-extension, and if
- * execution is 16-bit, the values will be truncated. */
- i = uint_value;
- return (int32_t)i;
-}
-
static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compiler,
const struct vkd3d_shader_register *reg, uint32_t swizzle, uint32_t write_mask)
{
@@ -4654,15 +4563,14 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile
if (reg->dimension == VSIR_DIMENSION_SCALAR)
{
for (i = 0; i < component_count; ++i)
- values[i] = convert_raw_constant32(reg->data_type, reg->u.immconst_u32[0]);
+ values[i] = reg->u.immconst_u32[0];
}
else
{
for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
- values[j++] = convert_raw_constant32(reg->data_type,
- reg->u.immconst_u32[vsir_swizzle_get_component(swizzle, i)]);
+ values[j++] = reg->u.immconst_u32[vsir_swizzle_get_component(swizzle, i)];
}
}
@@ -4758,8 +4666,8 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler,
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id);
}
- val_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ,
- VKD3D_DATA_UINT, 1, val_id);
+ val_id = spirv_compiler_emit_int_to_bool(compiler,
+ VKD3D_SHADER_CONDITIONAL_OP_NZ, VSIR_DATA_U32, 1, val_id);
}
else
{
@@ -4806,22 +4714,15 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil
switch (icb->data_type)
{
- case VKD3D_DATA_HALF:
- case VKD3D_DATA_UINT16:
- /* Scalar only. */
- for (i = 0; i < element_count; ++i)
- elements[i] = vkd3d_spirv_get_op_constant(builder, elem_type_id,
- convert_raw_constant32(icb->data_type, icb->data[i]));
- break;
- case VKD3D_DATA_FLOAT:
- case VKD3D_DATA_INT:
- case VKD3D_DATA_UINT:
+ case VSIR_DATA_F32:
+ case VSIR_DATA_I32:
+ case VSIR_DATA_U32:
for (i = 0; i < element_count; ++i)
elements[i] = spirv_compiler_get_constant(compiler, component_type, component_count,
&icb->data[component_count * i]);
break;
- case VKD3D_DATA_DOUBLE:
- case VKD3D_DATA_UINT64:
+ case VSIR_DATA_F64:
+ case VSIR_DATA_U64:
{
uint64_t *data = (uint64_t *)icb->data;
for (i = 0; i < element_count; ++i)
@@ -4913,8 +4814,8 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler,
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count);
val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id);
}
- val_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ,
- VKD3D_DATA_UINT, component_count, val_id);
+ val_id = spirv_compiler_emit_int_to_bool(compiler,
+ VKD3D_SHADER_CONDITIONAL_OP_NZ, VSIR_DATA_U32, component_count, val_id);
}
else
{
@@ -5008,7 +4909,7 @@ static uint32_t spirv_compiler_emit_load_src_with_type(struct spirv_compiler *co
{
struct vkd3d_shader_src_param src_param = *src;
- src_param.reg.data_type = vkd3d_data_type_from_component_type(component_type);
+ src_param.reg.data_type = vsir_data_type_from_component_type(component_type);
return spirv_compiler_emit_load_src(compiler, &src_param, write_mask);
}
@@ -5134,7 +5035,7 @@ static uint32_t spirv_compiler_emit_sat(struct spirv_compiler *compiler,
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
uint32_t type_id, zero_id, one_id;
- if (reg->data_type == VKD3D_DATA_DOUBLE)
+ if (reg->data_type == VSIR_DATA_F64)
{
zero_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count);
one_id = spirv_compiler_get_constant_double_vector(compiler, 1.0, component_count);
@@ -5188,7 +5089,7 @@ static void spirv_compiler_emit_store_dst_swizzled(struct spirv_compiler *compil
/* XXX: The register data type could be fixed by the shader parser. For SM5
* shaders the data types are stored in instructions modifiers.
*/
- typed_dst.reg.data_type = vkd3d_data_type_from_component_type(component_type);
+ typed_dst.reg.data_type = vsir_data_type_from_component_type(component_type);
spirv_compiler_emit_store_dst(compiler, &typed_dst, val_id);
}
@@ -5616,7 +5517,7 @@ static uint32_t spirv_compiler_get_invocation_id(struct spirv_compiler *compiler
VKD3D_ASSERT(compiler->shader_type == VKD3D_SHADER_TYPE_HULL);
- vsir_register_init(&r, VKD3DSPR_OUTPOINTID, VKD3D_DATA_FLOAT, 0);
+ vsir_register_init(&r, VKD3DSPR_OUTPOINTID, VSIR_DATA_F32, 0);
return spirv_compiler_get_register_id(compiler, &r);
}
@@ -5641,13 +5542,13 @@ static void spirv_compiler_emit_shader_phase_name(struct spirv_compiler *compile
switch (compiler->phase)
{
- case VKD3DSIH_HS_CONTROL_POINT_PHASE:
+ case VSIR_OP_HS_CONTROL_POINT_PHASE:
name = "control";
break;
- case VKD3DSIH_HS_FORK_PHASE:
+ case VSIR_OP_HS_FORK_PHASE:
name = "fork";
break;
- case VKD3DSIH_HS_JOIN_PHASE:
+ case VSIR_OP_HS_JOIN_PHASE:
name = "join";
break;
default:
@@ -5775,6 +5676,48 @@ static unsigned int shader_signature_next_location(const struct shader_signature
return max_row;
}
+static const struct vkd3d_symbol *spirv_compiler_emit_io_register(struct spirv_compiler *compiler,
+ const struct vkd3d_shader_dst_param *dst)
+{
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ const struct vkd3d_shader_register *reg = &dst->reg;
+ const struct vkd3d_spirv_builtin *builtin;
+ struct vkd3d_symbol reg_symbol;
+ SpvStorageClass storage_class;
+ uint32_t write_mask, id;
+ struct rb_entry *entry;
+
+ VKD3D_ASSERT(!reg->idx_count || !reg->idx[0].rel_addr);
+ VKD3D_ASSERT(reg->idx_count < 2);
+
+ if (reg->type == VKD3DSPR_RASTOUT && reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE)
+ {
+ builtin = &vkd3d_output_point_size_builtin;
+ storage_class = SpvStorageClassOutput;
+ }
+ else if (!(builtin = get_spirv_builtin_for_register(reg->type, &storage_class)))
+ {
+ FIXME("Unhandled register %#x.\n", reg->type);
+ return NULL;
+ }
+
+ /* vPrim may be declared in multiple hull shader phases. */
+ vkd3d_symbol_make_register(&reg_symbol, reg);
+ if ((entry = rb_get(&compiler->symbol_table, &reg_symbol)))
+ return RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry);
+
+ id = spirv_compiler_emit_builtin_variable(compiler, builtin, storage_class, 0);
+ spirv_compiler_emit_register_execution_mode(compiler, reg->type);
+ spirv_compiler_emit_register_debug_name(builder, id, reg);
+
+ write_mask = vkd3d_write_mask_from_component_count(builtin->component_count);
+ vkd3d_symbol_set_register_info(&reg_symbol, id,
+ storage_class, builtin->component_type, write_mask);
+ reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size;
+
+ return spirv_compiler_put_symbol(compiler, &reg_symbol);
+}
+
static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
enum vkd3d_shader_register_type reg_type, unsigned int element_idx)
{
@@ -5783,6 +5726,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
const struct signature_element *signature_element;
const struct shader_signature *shader_signature;
enum vkd3d_shader_component_type component_type;
+ enum vkd3d_shader_register_type sysval_reg_type;
const struct vkd3d_spirv_builtin *builtin;
enum vkd3d_shader_sysval_semantic sysval;
uint32_t write_mask, reg_write_mask;
@@ -5807,6 +5751,22 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
if (!signature_element->used_mask)
return;
+ sysval_reg_type = vsir_register_type_from_sysval_input(signature_element->sysval_semantic);
+ if (sysval_reg_type != VKD3DSPR_INPUT)
+ {
+ struct vkd3d_shader_dst_param dst;
+ const struct vkd3d_symbol *symbol;
+
+ vsir_dst_param_init(&dst, sysval_reg_type, VSIR_DATA_F32, 0);
+ symbol = spirv_compiler_emit_io_register(compiler, &dst);
+
+ vkd3d_symbol_make_io(&reg_symbol, reg_type, element_idx);
+ reg_symbol.id = symbol->id;
+ reg_symbol.info.reg = symbol->info.reg;
+ spirv_compiler_put_symbol(compiler, &reg_symbol);
+ return;
+ }
+
builtin = get_spirv_builtin_for_sysval(compiler, sysval);
array_sizes[0] = signature_element->register_count;
@@ -5823,15 +5783,15 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
{
component_type = builtin->component_type;
input_component_count = builtin->component_count;
- component_idx = 0;
}
else
{
component_type = signature_element->component_type;
input_component_count = vsir_write_mask_component_count(signature_element->mask);
- component_idx = vsir_write_mask_get_component_idx(signature_element->mask);
}
+ component_idx = vsir_write_mask_get_component_idx(write_mask);
+
if (needs_private_io_variable(builtin))
{
use_private_var = true;
@@ -5839,7 +5799,6 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
}
else
{
- component_idx = vsir_write_mask_get_component_idx(write_mask);
reg_write_mask = write_mask >> component_idx;
}
@@ -5905,7 +5864,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
{
struct vkd3d_shader_register dst_reg;
- vsir_register_init(&dst_reg, reg_type, VKD3D_DATA_FLOAT, 1);
+ vsir_register_init(&dst_reg, reg_type, VSIR_DATA_F32, 1);
dst_reg.idx[0].offset = element_idx;
type_id = vkd3d_spirv_get_type_id(builder, component_type, input_component_count);
@@ -5925,49 +5884,8 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler,
vkd3d_write_mask_from_component_count(input_component_count),
VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_SHADER_NO_SWIZZLE, signature_element->mask >> component_idx);
- spirv_compiler_emit_store_reg(compiler, &dst_reg, signature_element->mask, val_id);
- }
-}
-
-static void spirv_compiler_emit_io_register(struct spirv_compiler *compiler,
- const struct vkd3d_shader_dst_param *dst)
-{
- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- const struct vkd3d_shader_register *reg = &dst->reg;
- const struct vkd3d_spirv_builtin *builtin;
- struct vkd3d_symbol reg_symbol;
- SpvStorageClass storage_class;
- uint32_t write_mask, id;
- struct rb_entry *entry;
-
- VKD3D_ASSERT(!reg->idx_count || !reg->idx[0].rel_addr);
- VKD3D_ASSERT(reg->idx_count < 2);
-
- if (reg->type == VKD3DSPR_RASTOUT && reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE)
- {
- builtin = &vkd3d_output_point_size_builtin;
- storage_class = SpvStorageClassOutput;
- }
- else if (!(builtin = get_spirv_builtin_for_register(reg->type, &storage_class)))
- {
- FIXME("Unhandled register %#x.\n", reg->type);
- return;
+ spirv_compiler_emit_store_reg(compiler, &dst_reg, signature_element->mask >> component_idx, val_id);
}
-
- /* vPrim may be declared in multiple hull shader phases. */
- vkd3d_symbol_make_register(&reg_symbol, reg);
- if ((entry = rb_get(&compiler->symbol_table, &reg_symbol)))
- return;
-
- id = spirv_compiler_emit_builtin_variable(compiler, builtin, storage_class, 0);
-
- write_mask = vkd3d_write_mask_from_component_count(builtin->component_count);
- vkd3d_symbol_set_register_info(&reg_symbol, id,
- storage_class, builtin->component_type, write_mask);
- reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size;
- spirv_compiler_put_symbol(compiler, &reg_symbol);
- spirv_compiler_emit_register_execution_mode(compiler, reg->type);
- spirv_compiler_emit_register_debug_name(builder, id, reg);
}
static unsigned int get_shader_output_swizzle(const struct spirv_compiler *compiler,
@@ -6607,7 +6525,7 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil
* scope is specified, e.g. DXIL alloca. */
storage_class = temp->has_function_scope ? SpvStorageClassFunction : SpvStorageClassPrivate;
- vsir_register_init(&reg, VKD3DSPR_IDXTEMP, VKD3D_DATA_FLOAT, 1);
+ vsir_register_init(&reg, VKD3DSPR_IDXTEMP, VSIR_DATA_F32, 1);
reg.idx[0].offset = temp->register_idx;
/* Alignment is supported only in the Kernel execution model and is an optimisation only. */
@@ -6847,7 +6765,7 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler,
struct vkd3d_symbol reg_symbol;
unsigned int size;
- vsir_register_init(&reg, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3);
+ vsir_register_init(&reg, VKD3DSPR_CONSTBUFFER, VSIR_DATA_F32, 3);
reg.idx[0].offset = descriptor->register_id;
reg.idx[1].offset = range->first;
reg.idx[2].offset = range->last;
@@ -6907,7 +6825,7 @@ static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compi
vkd3d_spirv_build_op_name(builder, icb_id, "icb");
/* Set an index count of 2 so vkd3d_symbol_make_register() uses idx[0] as a buffer id. */
- vsir_register_init(&reg, VKD3DSPR_IMMCONSTBUFFER, VKD3D_DATA_FLOAT, 2);
+ vsir_register_init(&reg, VKD3DSPR_IMMCONSTBUFFER, VSIR_DATA_F32, 2);
reg.idx[0].offset = icb->register_idx;
vkd3d_symbol_make_register(&reg_symbol, &reg);
vkd3d_symbol_set_register_info(&reg_symbol, icb_id, SpvStorageClassPrivate,
@@ -6926,7 +6844,7 @@ static void spirv_compiler_emit_sampler_declaration(struct spirv_compiler *compi
struct vkd3d_symbol reg_symbol;
uint32_t type_id, var_id;
- vsir_register_init(&reg, VKD3DSPR_SAMPLER, VKD3D_DATA_FLOAT, 1);
+ vsir_register_init(&reg, VKD3DSPR_SAMPLER, VSIR_DATA_F32, 1);
reg.idx[0].offset = descriptor->register_id;
vkd3d_symbol_make_sampler(&reg_symbol, &reg);
@@ -7107,7 +7025,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp
struct vkd3d_symbol resource_symbol;
struct vkd3d_shader_register reg;
- vsir_register_init(&reg, is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VKD3D_DATA_FLOAT, 1);
+ vsir_register_init(&reg, is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VSIR_DATA_F32, 1);
reg.idx[0].offset = descriptor->register_id;
if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS && sample_count == 1)
@@ -7510,7 +7428,7 @@ static void spirv_compiler_enter_shader_phase(struct spirv_compiler *compiler,
compiler->phase = instruction->opcode;
spirv_compiler_emit_shader_phase_name(compiler, function_id, NULL);
- phase = (instruction->opcode == VKD3DSIH_HS_CONTROL_POINT_PHASE)
+ phase = (instruction->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE)
? &compiler->control_point_phase : &compiler->patch_constant_phase;
phase->function_id = function_id;
/* The insertion location must be set after the label is emitted. */
@@ -7524,7 +7442,7 @@ static void spirv_compiler_initialise_block(struct spirv_compiler *compiler)
/* Insertion locations must point immediately after the function's initial label. */
if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL)
{
- struct vkd3d_shader_phase *phase = (compiler->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE)
+ struct vkd3d_shader_phase *phase = (compiler->phase == VSIR_OP_HS_CONTROL_POINT_PHASE)
? &compiler->control_point_phase : &compiler->patch_constant_phase;
if (!phase->function_location)
phase->function_location = vkd3d_spirv_stream_current_location(&builder->function_stream);
@@ -7626,35 +7544,40 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru
}
alu_ops[] =
{
- {VKD3DSIH_ADD, SpvOpFAdd},
- {VKD3DSIH_AND, SpvOpBitwiseAnd},
- {VKD3DSIH_BFREV, SpvOpBitReverse},
- {VKD3DSIH_COUNTBITS, SpvOpBitCount},
- {VKD3DSIH_DADD, SpvOpFAdd},
- {VKD3DSIH_DDIV, SpvOpFDiv},
- {VKD3DSIH_DIV, SpvOpFDiv},
- {VKD3DSIH_DMUL, SpvOpFMul},
- {VKD3DSIH_DTOI, SpvOpConvertFToS},
- {VKD3DSIH_DTOU, SpvOpConvertFToU},
- {VKD3DSIH_FREM, SpvOpFRem},
- {VKD3DSIH_FTOD, SpvOpFConvert},
- {VKD3DSIH_IADD, SpvOpIAdd},
- {VKD3DSIH_INEG, SpvOpSNegate},
- {VKD3DSIH_ISHL, SpvOpShiftLeftLogical},
- {VKD3DSIH_ISHR, SpvOpShiftRightArithmetic},
- {VKD3DSIH_ISINF, SpvOpIsInf},
- {VKD3DSIH_ISNAN, SpvOpIsNan},
- {VKD3DSIH_ITOD, SpvOpConvertSToF},
- {VKD3DSIH_ITOF, SpvOpConvertSToF},
- {VKD3DSIH_ITOI, SpvOpSConvert},
- {VKD3DSIH_MUL, SpvOpFMul},
- {VKD3DSIH_NOT, SpvOpNot},
- {VKD3DSIH_OR, SpvOpBitwiseOr},
- {VKD3DSIH_USHR, SpvOpShiftRightLogical},
- {VKD3DSIH_UTOD, SpvOpConvertUToF},
- {VKD3DSIH_UTOF, SpvOpConvertUToF},
- {VKD3DSIH_UTOU, SpvOpUConvert},
- {VKD3DSIH_XOR, SpvOpBitwiseXor},
+ {VSIR_OP_ADD, SpvOpFAdd},
+ {VSIR_OP_AND, SpvOpBitwiseAnd},
+ {VSIR_OP_BFREV, SpvOpBitReverse},
+ {VSIR_OP_COUNTBITS, SpvOpBitCount},
+ {VSIR_OP_DADD, SpvOpFAdd},
+ {VSIR_OP_DDIV, SpvOpFDiv},
+ {VSIR_OP_DIV, SpvOpFDiv},
+ {VSIR_OP_DMUL, SpvOpFMul},
+ {VSIR_OP_DTOI, SpvOpConvertFToS},
+ {VSIR_OP_DTOU, SpvOpConvertFToU},
+ {VSIR_OP_FREM, SpvOpFRem},
+ {VSIR_OP_FTOD, SpvOpFConvert},
+ {VSIR_OP_IADD, SpvOpIAdd},
+ {VSIR_OP_IDIV, SpvOpSDiv},
+ {VSIR_OP_IMUL_LOW, SpvOpIMul},
+ {VSIR_OP_INEG, SpvOpSNegate},
+ {VSIR_OP_IREM, SpvOpSRem},
+ {VSIR_OP_ISHL, SpvOpShiftLeftLogical},
+ {VSIR_OP_ISHR, SpvOpShiftRightArithmetic},
+ {VSIR_OP_ISINF, SpvOpIsInf},
+ {VSIR_OP_ISNAN, SpvOpIsNan},
+ {VSIR_OP_ITOD, SpvOpConvertSToF},
+ {VSIR_OP_ITOF, SpvOpConvertSToF},
+ {VSIR_OP_ITOI, SpvOpSConvert},
+ {VSIR_OP_MUL, SpvOpFMul},
+ {VSIR_OP_NOT, SpvOpNot},
+ {VSIR_OP_OR, SpvOpBitwiseOr},
+ {VSIR_OP_UDIV_SIMPLE, SpvOpUDiv},
+ {VSIR_OP_UREM, SpvOpUMod},
+ {VSIR_OP_USHR, SpvOpShiftRightLogical},
+ {VSIR_OP_UTOD, SpvOpConvertUToF},
+ {VSIR_OP_UTOF, SpvOpConvertUToF},
+ {VSIR_OP_UTOU, SpvOpUConvert},
+ {VSIR_OP_XOR, SpvOpBitwiseXor},
};
unsigned int i;
@@ -7671,11 +7594,11 @@ static SpvOp spirv_compiler_map_logical_instruction(const struct vkd3d_shader_in
{
switch (instruction->opcode)
{
- case VKD3DSIH_AND:
+ case VSIR_OP_AND:
return SpvOpLogicalAnd;
- case VKD3DSIH_OR:
+ case VSIR_OP_OR:
return SpvOpLogicalOr;
- case VKD3DSIH_XOR:
+ case VSIR_OP_XOR:
return SpvOpLogicalNotEqual;
default:
return SpvOpMax;
@@ -7689,25 +7612,25 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler,
const struct vkd3d_shader_src_param *src = instruction->src;
uint32_t val_id;
- VKD3D_ASSERT(src->reg.data_type == VKD3D_DATA_BOOL && dst->reg.data_type != VKD3D_DATA_BOOL);
+ VKD3D_ASSERT(src->reg.data_type == VSIR_DATA_BOOL && dst->reg.data_type != VSIR_DATA_BOOL);
val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask);
- if (dst->reg.data_type == VKD3D_DATA_HALF || dst->reg.data_type == VKD3D_DATA_FLOAT)
+ if (dst->reg.data_type == VSIR_DATA_F16 || dst->reg.data_type == VSIR_DATA_F32)
{
- val_id = spirv_compiler_emit_bool_to_float(compiler, 1, val_id, instruction->opcode == VKD3DSIH_ITOF);
+ val_id = spirv_compiler_emit_bool_to_float(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOF);
}
- else if (dst->reg.data_type == VKD3D_DATA_DOUBLE)
+ else if (dst->reg.data_type == VSIR_DATA_F64)
{
/* ITOD is not supported. Frontends which emit bool casts must use ITOF for double. */
- val_id = spirv_compiler_emit_bool_to_double(compiler, 1, val_id, instruction->opcode == VKD3DSIH_ITOF);
+ val_id = spirv_compiler_emit_bool_to_double(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOF);
}
- else if (dst->reg.data_type == VKD3D_DATA_UINT16 || dst->reg.data_type == VKD3D_DATA_UINT)
+ else if (dst->reg.data_type == VSIR_DATA_U16 || dst->reg.data_type == VSIR_DATA_U32)
{
- val_id = spirv_compiler_emit_bool_to_int(compiler, 1, val_id, instruction->opcode == VKD3DSIH_ITOI);
+ val_id = spirv_compiler_emit_bool_to_int(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOI);
}
- else if (dst->reg.data_type == VKD3D_DATA_UINT64)
+ else if (dst->reg.data_type == VSIR_DATA_U64)
{
- val_id = spirv_compiler_emit_bool_to_int64(compiler, 1, val_id, instruction->opcode == VKD3DSIH_ITOI);
+ val_id = spirv_compiler_emit_bool_to_int64(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOI);
}
else
{
@@ -7722,15 +7645,16 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler,
static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
+ uint32_t src_ids[SPIRV_MAX_SRC_COUNT], condition_id = 0, uint_max_id = 0;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_dst_param *dst = instruction->dst;
const struct vkd3d_shader_src_param *src = instruction->src;
- uint32_t src_ids[SPIRV_MAX_SRC_COUNT];
+ unsigned int i, component_count;
uint32_t type_id, val_id;
SpvOp op = SpvOpMax;
- unsigned int i;
+ bool check_zero;
- if (src->reg.data_type == VKD3D_DATA_UINT64 && instruction->opcode == VKD3DSIH_COUNTBITS)
+ if (src->reg.data_type == VSIR_DATA_U64 && instruction->opcode == VSIR_OP_COUNTBITS)
{
/* At least some drivers support this anyway, but if validation is enabled it will fail. */
FIXME("Unsupported 64-bit source for bit count.\n");
@@ -7739,15 +7663,15 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil
return VKD3D_ERROR_INVALID_SHADER;
}
- if (src->reg.data_type == VKD3D_DATA_BOOL)
+ if (src->reg.data_type == VSIR_DATA_BOOL)
{
- if (dst->reg.data_type == VKD3D_DATA_BOOL)
+ if (dst->reg.data_type == VSIR_DATA_BOOL)
{
/* VSIR supports logic ops AND/OR/XOR on bool values. */
op = spirv_compiler_map_logical_instruction(instruction);
}
- else if (instruction->opcode == VKD3DSIH_ITOF || instruction->opcode == VKD3DSIH_UTOF
- || instruction->opcode == VKD3DSIH_ITOI || instruction->opcode == VKD3DSIH_UTOU)
+ else if (instruction->opcode == VSIR_OP_ITOF || instruction->opcode == VSIR_OP_UTOF
+ || instruction->opcode == VSIR_OP_ITOI || instruction->opcode == VSIR_OP_UTOU)
{
/* VSIR supports cast from bool to signed/unsigned integer types and floating point types,
* where bool is treated as a 1-bit integer and a signed 'true' value converts to -1. */
@@ -7762,20 +7686,50 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil
if (op == SpvOpMax)
{
- ERR("Unexpected instruction %#x.\n", instruction->opcode);
spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_HANDLER,
- "Encountered invalid/unhandled instruction handler %#x.", instruction->opcode);
+ "Encountered invalid/unhandled instruction \"%s\" (%#x).",
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
return VKD3D_ERROR_INVALID_SHADER;
}
+ /* SPIR-V doesn't mandate a behaviour when a denominator is zero,
+ * so we have an explicit check. */
+ switch (instruction->opcode)
+ {
+ case VSIR_OP_IDIV:
+ case VSIR_OP_IREM:
+ case VSIR_OP_UDIV_SIMPLE:
+ case VSIR_OP_UREM:
+ check_zero = true;
+ break;
+
+ default:
+ check_zero = false;
+ break;
+ }
+
VKD3D_ASSERT(instruction->dst_count == 1);
VKD3D_ASSERT(instruction->src_count <= SPIRV_MAX_SRC_COUNT);
+ if (check_zero)
+ VKD3D_ASSERT(instruction->src_count == 2);
+ component_count = vsir_write_mask_component_count(dst[0].write_mask);
type_id = spirv_compiler_get_type_id_for_dst(compiler, dst);
for (i = 0; i < instruction->src_count; ++i)
src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], dst->write_mask);
+ if (check_zero)
+ {
+ condition_id = spirv_compiler_emit_int_to_bool(compiler,
+ VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src_ids[1]);
+
+ if (dst[0].reg.data_type == VSIR_DATA_U64)
+ uint_max_id = spirv_compiler_get_constant_uint64_vector(compiler, UINT64_MAX, component_count);
+ else
+ uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count);
+ }
+
/* The SPIR-V specification states, "The resulting value is undefined if
* Shift is greater than or equal to the bit width of the components of
* Base." Direct3D applies only the lowest 5 bits of the shift.
@@ -7783,8 +7737,8 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil
* Microsoft fxc will compile immediate constants larger than 5 bits.
* Fixing up the constants would be more elegant, but the simplest way is
* to let this handle constants too. */
- if (!(instruction->flags & VKD3DSI_SHIFT_UNMASKED) && (instruction->opcode == VKD3DSIH_ISHL
- || instruction->opcode == VKD3DSIH_ISHR || instruction->opcode == VKD3DSIH_USHR))
+ if (!(instruction->flags & VKD3DSI_SHIFT_UNMASKED) && (instruction->opcode == VSIR_OP_ISHL
+ || instruction->opcode == VSIR_OP_ISHR || instruction->opcode == VSIR_OP_USHR))
{
uint32_t mask_id = spirv_compiler_get_constant_vector(compiler,
VKD3D_SHADER_COMPONENT_UINT, vsir_write_mask_component_count(dst->write_mask), 0x1f);
@@ -7796,6 +7750,9 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil
if (instruction->flags & VKD3DSI_PRECISE_XYZW)
vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0);
+ if (check_zero)
+ val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id);
+
spirv_compiler_emit_store_dst(compiler, dst, val_id);
return VKD3D_OK;
}
@@ -7827,36 +7784,38 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction(
}
glsl_insts[] =
{
- {VKD3DSIH_ABS, GLSLstd450FAbs},
- {VKD3DSIH_ACOS, GLSLstd450Acos},
- {VKD3DSIH_ASIN, GLSLstd450Asin},
- {VKD3DSIH_ATAN, GLSLstd450Atan},
- {VKD3DSIH_DFMA, GLSLstd450Fma},
- {VKD3DSIH_DMAX, GLSLstd450NMax},
- {VKD3DSIH_DMIN, GLSLstd450NMin},
- {VKD3DSIH_EXP, GLSLstd450Exp2},
- {VKD3DSIH_FIRSTBIT_HI, GLSLstd450FindUMsb},
- {VKD3DSIH_FIRSTBIT_LO, GLSLstd450FindILsb},
- {VKD3DSIH_FIRSTBIT_SHI, GLSLstd450FindSMsb},
- {VKD3DSIH_FRC, GLSLstd450Fract},
- {VKD3DSIH_HCOS, GLSLstd450Cosh},
- {VKD3DSIH_HSIN, GLSLstd450Sinh},
- {VKD3DSIH_HTAN, GLSLstd450Tanh},
- {VKD3DSIH_IMAX, GLSLstd450SMax},
- {VKD3DSIH_IMIN, GLSLstd450SMin},
- {VKD3DSIH_LOG, GLSLstd450Log2},
- {VKD3DSIH_MAD, GLSLstd450Fma},
- {VKD3DSIH_MAX, GLSLstd450NMax},
- {VKD3DSIH_MIN, GLSLstd450NMin},
- {VKD3DSIH_ROUND_NE, GLSLstd450RoundEven},
- {VKD3DSIH_ROUND_NI, GLSLstd450Floor},
- {VKD3DSIH_ROUND_PI, GLSLstd450Ceil},
- {VKD3DSIH_ROUND_Z, GLSLstd450Trunc},
- {VKD3DSIH_RSQ, GLSLstd450InverseSqrt},
- {VKD3DSIH_SQRT, GLSLstd450Sqrt},
- {VKD3DSIH_TAN, GLSLstd450Tan},
- {VKD3DSIH_UMAX, GLSLstd450UMax},
- {VKD3DSIH_UMIN, GLSLstd450UMin},
+ {VSIR_OP_ABS, GLSLstd450FAbs},
+ {VSIR_OP_ACOS, GLSLstd450Acos},
+ {VSIR_OP_ASIN, GLSLstd450Asin},
+ {VSIR_OP_ATAN, GLSLstd450Atan},
+ {VSIR_OP_COS, GLSLstd450Cos},
+ {VSIR_OP_DFMA, GLSLstd450Fma},
+ {VSIR_OP_DMAX, GLSLstd450NMax},
+ {VSIR_OP_DMIN, GLSLstd450NMin},
+ {VSIR_OP_EXP, GLSLstd450Exp2},
+ {VSIR_OP_FIRSTBIT_HI, GLSLstd450FindUMsb},
+ {VSIR_OP_FIRSTBIT_LO, GLSLstd450FindILsb},
+ {VSIR_OP_FIRSTBIT_SHI, GLSLstd450FindSMsb},
+ {VSIR_OP_FRC, GLSLstd450Fract},
+ {VSIR_OP_HCOS, GLSLstd450Cosh},
+ {VSIR_OP_HSIN, GLSLstd450Sinh},
+ {VSIR_OP_HTAN, GLSLstd450Tanh},
+ {VSIR_OP_IMAX, GLSLstd450SMax},
+ {VSIR_OP_IMIN, GLSLstd450SMin},
+ {VSIR_OP_LOG, GLSLstd450Log2},
+ {VSIR_OP_MAD, GLSLstd450Fma},
+ {VSIR_OP_MAX, GLSLstd450NMax},
+ {VSIR_OP_MIN, GLSLstd450NMin},
+ {VSIR_OP_ROUND_NE, GLSLstd450RoundEven},
+ {VSIR_OP_ROUND_NI, GLSLstd450Floor},
+ {VSIR_OP_ROUND_PI, GLSLstd450Ceil},
+ {VSIR_OP_ROUND_Z, GLSLstd450Trunc},
+ {VSIR_OP_RSQ, GLSLstd450InverseSqrt},
+ {VSIR_OP_SIN, GLSLstd450Sin},
+ {VSIR_OP_SQRT, GLSLstd450Sqrt},
+ {VSIR_OP_TAN, GLSLstd450Tan},
+ {VSIR_OP_UMAX, GLSLstd450UMax},
+ {VSIR_OP_UMIN, GLSLstd450UMin},
};
unsigned int i;
@@ -7880,20 +7839,22 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp
unsigned int i, component_count;
enum GLSLstd450 glsl_inst;
- if (src[0].reg.data_type == VKD3D_DATA_UINT64 && (instruction->opcode == VKD3DSIH_FIRSTBIT_HI
- || instruction->opcode == VKD3DSIH_FIRSTBIT_LO || instruction->opcode == VKD3DSIH_FIRSTBIT_SHI))
+ if (src[0].reg.data_type == VSIR_DATA_U64 && (instruction->opcode == VSIR_OP_FIRSTBIT_HI
+ || instruction->opcode == VSIR_OP_FIRSTBIT_LO || instruction->opcode == VSIR_OP_FIRSTBIT_SHI))
{
/* At least some drivers support this anyway, but if validation is enabled it will fail. */
- FIXME("Unsupported 64-bit source for handler %#x.\n", instruction->opcode);
spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED,
- "64-bit source for handler %#x is not supported.", instruction->opcode);
+ "64-bit source for instruction \"%s\" (%#x) is not supported.",
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
return;
}
glsl_inst = spirv_compiler_map_ext_glsl_instruction(instruction);
if (glsl_inst == GLSLstd450Bad)
{
- ERR("Unexpected instruction %#x.\n", instruction->opcode);
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED,
+ "Unhandled instruction \"%s\" (%#x).",
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
return;
}
@@ -7910,8 +7871,8 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp
val_id = vkd3d_spirv_build_op_ext_inst(builder, type_id,
instr_set_id, glsl_inst, src_id, instruction->src_count);
- if (instruction->opcode == VKD3DSIH_FIRSTBIT_HI
- || instruction->opcode == VKD3DSIH_FIRSTBIT_SHI)
+ if (instruction->opcode == VSIR_OP_FIRSTBIT_HI
+ || instruction->opcode == VSIR_OP_FIRSTBIT_SHI)
{
/* In D3D bits are numbered from the most significant bit. */
component_count = vsir_write_mask_component_count(dst->write_mask);
@@ -7948,7 +7909,8 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler,
|| dst_reg_info.write_mask != src_reg_info.write_mask)
goto general_implementation;
- if (vkd3d_swizzle_is_equal(dst_reg_info.write_mask, src->swizzle, src_reg_info.write_mask))
+ if (dst_reg_info.write_mask == dst->write_mask
+ && vkd3d_swizzle_is_equal(dst_reg_info.write_mask, src->swizzle, src_reg_info.write_mask))
{
dst_id = spirv_compiler_get_register_id(compiler, &dst->reg);
src_id = spirv_compiler_get_register_id(compiler, &src->reg);
@@ -8017,9 +7979,9 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler,
component_count = vsir_write_mask_component_count(dst->write_mask);
type_id = spirv_compiler_get_type_id_for_dst(compiler, dst);
- if (src[0].reg.data_type != VKD3D_DATA_BOOL)
+ if (src[0].reg.data_type != VSIR_DATA_BOOL)
{
- if (instruction->opcode == VKD3DSIH_CMP)
+ if (instruction->opcode == VSIR_OP_CMP)
condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpFOrdGreaterThanEqual,
vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), condition_id,
spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count));
@@ -8073,9 +8035,9 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler,
component_count = vsir_write_mask_component_count(dst->write_mask);
component_type = vkd3d_component_type_from_data_type(dst->reg.data_type);
- if (instruction->opcode == VKD3DSIH_DP4)
+ if (instruction->opcode == VSIR_OP_DP4)
write_mask = VKD3DSP_WRITEMASK_ALL;
- else if (instruction->opcode == VKD3DSIH_DP3)
+ else if (instruction->opcode == VSIR_OP_DP3)
write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_2;
else
write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1;
@@ -8112,7 +8074,7 @@ static void spirv_compiler_emit_rcp(struct spirv_compiler *compiler,
type_id = spirv_compiler_get_type_id_for_dst(compiler, dst);
src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask);
- if (src->reg.data_type == VKD3D_DATA_DOUBLE)
+ if (src->reg.data_type == VSIR_DATA_F64)
div_id = spirv_compiler_get_constant_double_vector(compiler, 1.0, component_count);
else
div_id = spirv_compiler_get_constant_float_vector(compiler, 1.0f, component_count);
@@ -8120,65 +8082,6 @@ static void spirv_compiler_emit_rcp(struct spirv_compiler *compiler,
spirv_compiler_emit_store_dst(compiler, dst, val_id);
}
-static void spirv_compiler_emit_sincos(struct spirv_compiler *compiler,
- const struct vkd3d_shader_instruction *instruction)
-{
- const struct vkd3d_shader_dst_param *dst_sin = &instruction->dst[0];
- const struct vkd3d_shader_dst_param *dst_cos = &instruction->dst[1];
- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- const struct vkd3d_shader_src_param *src = instruction->src;
- uint32_t type_id, src_id, sin_id = 0, cos_id = 0;
-
- if (dst_sin->reg.type != VKD3DSPR_NULL)
- {
- type_id = spirv_compiler_get_type_id_for_dst(compiler, dst_sin);
- src_id = spirv_compiler_emit_load_src(compiler, src, dst_sin->write_mask);
-
- sin_id = vkd3d_spirv_build_op_glsl_std450_sin(builder, type_id, src_id);
- }
-
- if (dst_cos->reg.type != VKD3DSPR_NULL)
- {
- if (dst_sin->reg.type == VKD3DSPR_NULL || dst_cos->write_mask != dst_sin->write_mask)
- {
- type_id = spirv_compiler_get_type_id_for_dst(compiler, dst_cos);
- src_id = spirv_compiler_emit_load_src(compiler, src, dst_cos->write_mask);
- }
-
- cos_id = vkd3d_spirv_build_op_glsl_std450_cos(builder, type_id, src_id);
- }
-
- if (sin_id)
- spirv_compiler_emit_store_dst(compiler, dst_sin, sin_id);
-
- if (cos_id)
- spirv_compiler_emit_store_dst(compiler, dst_cos, cos_id);
-}
-
-static void spirv_compiler_emit_imul(struct spirv_compiler *compiler,
- const struct vkd3d_shader_instruction *instruction)
-{
- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- const struct vkd3d_shader_dst_param *dst = instruction->dst;
- const struct vkd3d_shader_src_param *src = instruction->src;
- uint32_t type_id, val_id, src0_id, src1_id;
-
- if (dst[0].reg.type != VKD3DSPR_NULL)
- FIXME("Extended multiplies not implemented.\n"); /* SpvOpSMulExtended/SpvOpUMulExtended */
-
- if (dst[1].reg.type == VKD3DSPR_NULL)
- return;
-
- type_id = spirv_compiler_get_type_id_for_dst(compiler, &dst[1]);
-
- src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst[1].write_mask);
- src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[1].write_mask);
-
- val_id = vkd3d_spirv_build_op_imul(builder, type_id, src0_id, src1_id);
-
- spirv_compiler_emit_store_dst(compiler, &dst[1], val_id);
-}
-
static void spirv_compiler_emit_imad(struct spirv_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
@@ -8200,67 +8103,6 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler,
spirv_compiler_emit_store_dst(compiler, dst, val_id);
}
-static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler,
- const struct vkd3d_shader_instruction *instruction)
-{
- uint32_t type_id, val_id, src0_id, src1_id, condition_id, uint_max_id;
- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- const struct vkd3d_shader_dst_param *dst = instruction->dst;
- const struct vkd3d_shader_src_param *src = instruction->src;
- unsigned int component_count = 0;
- SpvOp div_op, mod_op;
-
- div_op = instruction->opcode == VKD3DSIH_IDIV ? SpvOpSDiv : SpvOpUDiv;
- mod_op = instruction->opcode == VKD3DSIH_IDIV ? SpvOpSRem : SpvOpUMod;
-
- if (dst[0].reg.type != VKD3DSPR_NULL)
- {
- component_count = vsir_write_mask_component_count(dst[0].write_mask);
- type_id = spirv_compiler_get_type_id_for_dst(compiler, &dst[0]);
-
- src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst[0].write_mask);
- src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[0].write_mask);
-
- condition_id = spirv_compiler_emit_int_to_bool(compiler,
- VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src1_id);
- if (dst[0].reg.data_type == VKD3D_DATA_UINT64)
- uint_max_id = spirv_compiler_get_constant_uint64_vector(compiler, UINT64_MAX, component_count);
- else
- uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, 0xffffffff, component_count);
-
- val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, div_op, type_id, src0_id, src1_id);
- /* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */
- val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id);
-
- spirv_compiler_emit_store_dst(compiler, &dst[0], val_id);
- }
-
- if (dst[1].reg.type != VKD3DSPR_NULL)
- {
- if (!component_count || dst[0].write_mask != dst[1].write_mask)
- {
- component_count = vsir_write_mask_component_count(dst[1].write_mask);
- type_id = spirv_compiler_get_type_id_for_dst(compiler, &dst[1]);
-
- src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst[1].write_mask);
- src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[1].write_mask);
-
- condition_id = spirv_compiler_emit_int_to_bool(compiler,
- VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src1_id);
- if (dst[1].reg.data_type == VKD3D_DATA_UINT64)
- uint_max_id = spirv_compiler_get_constant_uint64_vector(compiler, UINT64_MAX, component_count);
- else
- uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, 0xffffffff, component_count);
- }
-
- val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, mod_op, type_id, src0_id, src1_id);
- /* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */
- val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id);
-
- spirv_compiler_emit_store_dst(compiler, &dst[1], val_id);
- }
-}
-
static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
@@ -8282,7 +8124,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler,
component_count = vsir_write_mask_component_count(dst->write_mask);
- if (src->reg.data_type == VKD3D_DATA_DOUBLE)
+ if (src->reg.data_type == VSIR_DATA_F64)
{
write_mask = vkd3d_write_mask_from_component_count(component_count);
int_min_id = spirv_compiler_get_constant_double_vector(compiler, -2147483648.0, component_count);
@@ -8338,7 +8180,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler,
component_count = vsir_write_mask_component_count(dst->write_mask);
- if (src->reg.data_type == VKD3D_DATA_DOUBLE)
+ if (src->reg.data_type == VSIR_DATA_F64)
{
write_mask = vkd3d_write_mask_from_component_count(component_count);
zero_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count);
@@ -8407,17 +8249,19 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp
component_type = vkd3d_component_type_from_data_type(dst->reg.data_type);
type_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
- size = (src[src_count - 1].reg.data_type == VKD3D_DATA_UINT64) ? 0x40 : 0x20;
+ size = (src[src_count - 1].reg.data_type == VSIR_DATA_U64) ? 0x40 : 0x20;
mask_id = spirv_compiler_get_constant_uint(compiler, size - 1);
size_id = spirv_compiler_get_constant_uint(compiler, size);
switch (instruction->opcode)
{
- case VKD3DSIH_BFI: op = SpvOpBitFieldInsert; break;
- case VKD3DSIH_IBFE: op = SpvOpBitFieldSExtract; break;
- case VKD3DSIH_UBFE: op = SpvOpBitFieldUExtract; break;
+ case VSIR_OP_BFI: op = SpvOpBitFieldInsert; break;
+ case VSIR_OP_IBFE: op = SpvOpBitFieldSExtract; break;
+ case VSIR_OP_UBFE: op = SpvOpBitFieldUExtract; break;
default:
- ERR("Unexpected instruction %#x.\n", instruction->opcode);
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED,
+ "Unhandled instruction \"%s\" (%#x).",
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
return;
}
@@ -8531,26 +8375,28 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co
switch (instruction->opcode)
{
- case VKD3DSIH_DEQO:
- case VKD3DSIH_EQO: op = SpvOpFOrdEqual; break;
- case VKD3DSIH_EQU: op = SpvOpFUnordEqual; break;
- case VKD3DSIH_DGEO:
- case VKD3DSIH_GEO: op = SpvOpFOrdGreaterThanEqual; break;
- case VKD3DSIH_GEU: op = SpvOpFUnordGreaterThanEqual; break;
- case VKD3DSIH_IEQ: op = SpvOpIEqual; break;
- case VKD3DSIH_IGE: op = SpvOpSGreaterThanEqual; break;
- case VKD3DSIH_ILT: op = SpvOpSLessThan; break;
- case VKD3DSIH_INE: op = SpvOpINotEqual; break;
- case VKD3DSIH_DLT:
- case VKD3DSIH_LTO: op = SpvOpFOrdLessThan; break;
- case VKD3DSIH_LTU: op = SpvOpFUnordLessThan; break;
- case VKD3DSIH_NEO: op = SpvOpFOrdNotEqual; break;
- case VKD3DSIH_DNE:
- case VKD3DSIH_NEU: op = SpvOpFUnordNotEqual; break;
- case VKD3DSIH_UGE: op = SpvOpUGreaterThanEqual; break;
- case VKD3DSIH_ULT: op = SpvOpULessThan; break;
+ case VSIR_OP_DEQO:
+ case VSIR_OP_EQO: op = SpvOpFOrdEqual; break;
+ case VSIR_OP_EQU: op = SpvOpFUnordEqual; break;
+ case VSIR_OP_DGEO:
+ case VSIR_OP_GEO: op = SpvOpFOrdGreaterThanEqual; break;
+ case VSIR_OP_GEU: op = SpvOpFUnordGreaterThanEqual; break;
+ case VSIR_OP_IEQ: op = SpvOpIEqual; break;
+ case VSIR_OP_IGE: op = SpvOpSGreaterThanEqual; break;
+ case VSIR_OP_ILT: op = SpvOpSLessThan; break;
+ case VSIR_OP_INE: op = SpvOpINotEqual; break;
+ case VSIR_OP_DLT:
+ case VSIR_OP_LTO: op = SpvOpFOrdLessThan; break;
+ case VSIR_OP_LTU: op = SpvOpFUnordLessThan; break;
+ case VSIR_OP_NEO: op = SpvOpFOrdNotEqual; break;
+ case VSIR_OP_DNE:
+ case VSIR_OP_NEU: op = SpvOpFUnordNotEqual; break;
+ case VSIR_OP_UGE: op = SpvOpUGreaterThanEqual; break;
+ case VSIR_OP_ULT: op = SpvOpULessThan; break;
default:
- ERR("Unexpected instruction %#x.\n", instruction->opcode);
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED,
+ "Unhandled instruction \"%s\" (%#x).",
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
return;
}
@@ -8558,10 +8404,10 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co
switch (instruction->opcode)
{
- case VKD3DSIH_DEQO:
- case VKD3DSIH_DGEO:
- case VKD3DSIH_DLT:
- case VKD3DSIH_DNE:
+ case VSIR_OP_DEQO:
+ case VSIR_OP_DGEO:
+ case VSIR_OP_DLT:
+ case VSIR_OP_DNE:
write_mask = vkd3d_write_mask_from_component_count(component_count);
break;
@@ -8576,7 +8422,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co
result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
op, type_id, src0_id, src1_id);
- if (dst->reg.data_type != VKD3D_DATA_BOOL)
+ if (dst->reg.data_type != VSIR_DATA_BOOL)
result_id = spirv_compiler_emit_bool_to_int(compiler, component_count, result_id, true);
spirv_compiler_emit_store_reg(compiler, &dst->reg, dst->write_mask, result_id);
}
@@ -8596,7 +8442,7 @@ static void spirv_compiler_emit_orderedness_instruction(struct spirv_compiler *c
src0_id = vkd3d_spirv_build_op_is_nan(builder, type_id, src0_id);
src1_id = vkd3d_spirv_build_op_is_nan(builder, type_id, src1_id);
val_id = vkd3d_spirv_build_op_logical_or(builder, type_id, src0_id, src1_id);
- if (instruction->opcode == VKD3DSIH_ORD)
+ if (instruction->opcode == VSIR_OP_ORD)
val_id = vkd3d_spirv_build_op_logical_not(builder, type_id, val_id);
spirv_compiler_emit_store_dst(compiler, dst, val_id);
}
@@ -8613,8 +8459,8 @@ static void spirv_compiler_emit_float_comparison_instruction(struct spirv_compil
switch (instruction->opcode)
{
- case VKD3DSIH_SLT: op = SpvOpFOrdLessThan; break;
- case VKD3DSIH_SGE: op = SpvOpFOrdGreaterThanEqual; break;
+ case VSIR_OP_SLT: op = SpvOpFOrdLessThan; break;
+ case VSIR_OP_SGE: op = SpvOpFOrdGreaterThanEqual; break;
default:
vkd3d_unreachable();
}
@@ -8757,7 +8603,7 @@ static void spirv_compiler_emit_discard(struct spirv_compiler *compiler,
* a mismatch between the VSIR structure and the SPIR-V one, which would cause problems if
* structurisation is necessary. Therefore we emit it as a function call. */
condition_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0);
- if (src->reg.data_type != VKD3D_DATA_BOOL)
+ if (src->reg.data_type != VSIR_DATA_BOOL)
condition_id = spirv_compiler_emit_int_to_bool(compiler,
instruction->flags, src->reg.data_type, 1, condition_id);
else if (instruction->flags & VKD3D_SHADER_CONDITIONAL_OP_Z)
@@ -8830,7 +8676,7 @@ static void spirv_compiler_emit_branch(struct spirv_compiler *compiler,
if (instruction->src_count == 3)
spirv_compiler_emit_merge(compiler, src[1].reg.idx[0].offset, src[2].reg.idx[0].offset);
else
- ERR("Invalid branch with %u sources.\n", instruction->src_count);
+ ERR("Invalid branch with %zu sources.\n", instruction->src_count);
}
vkd3d_spirv_build_op_branch(builder, spirv_compiler_get_label_id(compiler, src[0].reg.idx[0].offset));
return;
@@ -8844,7 +8690,7 @@ static void spirv_compiler_emit_branch(struct spirv_compiler *compiler,
}
condition_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0);
- if (src[0].reg.data_type != VKD3D_DATA_BOOL)
+ if (src[0].reg.data_type != VSIR_DATA_BOOL)
condition_id = spirv_compiler_emit_int_to_bool(compiler,
VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, 1, condition_id);
/* Emit the merge immediately before the branch instruction. */
@@ -8852,7 +8698,7 @@ static void spirv_compiler_emit_branch(struct spirv_compiler *compiler,
spirv_compiler_emit_merge(compiler, src[3].reg.idx[0].offset,
(instruction->src_count > 4) ? src[4].reg.idx[0].offset : 0);
else
- ERR("Invalid branch with %u sources.\n", instruction->src_count);
+ ERR("Invalid branch with %zu sources.\n", instruction->src_count);
vkd3d_spirv_build_op_branch_conditional(builder, condition_id,
spirv_compiler_get_label_id(compiler, src[1].reg.idx[0].offset),
spirv_compiler_get_label_id(compiler, src[2].reg.idx[0].offset));
@@ -8917,12 +8763,12 @@ static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compile
}
deriv_instructions[] =
{
- {VKD3DSIH_DSX, SpvOpDPdx},
- {VKD3DSIH_DSX_COARSE, SpvOpDPdxCoarse, true},
- {VKD3DSIH_DSX_FINE, SpvOpDPdxFine, true},
- {VKD3DSIH_DSY, SpvOpDPdy},
- {VKD3DSIH_DSY_COARSE, SpvOpDPdyCoarse, true},
- {VKD3DSIH_DSY_FINE, SpvOpDPdyFine, true},
+ {VSIR_OP_DSX, SpvOpDPdx},
+ {VSIR_OP_DSX_COARSE, SpvOpDPdxCoarse, true},
+ {VSIR_OP_DSX_FINE, SpvOpDPdxFine, true},
+ {VSIR_OP_DSY, SpvOpDPdy},
+ {VSIR_OP_DSY_COARSE, SpvOpDPdyCoarse, true},
+ {VSIR_OP_DSY_FINE, SpvOpDPdyFine, true},
};
info = NULL;
@@ -8936,7 +8782,9 @@ static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compile
}
if (!info)
{
- ERR("Unexpected instruction %#x.\n", instruction->opcode);
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED,
+ "Unhandled instruction \"%s\" (%#x).",
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
return;
}
@@ -9147,7 +8995,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler,
uint32_t coordinate_mask;
bool multisample;
- multisample = instruction->opcode == VKD3DSIH_LD2DMS;
+ multisample = instruction->opcode == VSIR_OP_LD2DMS;
spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE);
@@ -9228,16 +9076,16 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler,
switch (instruction->opcode)
{
- case VKD3DSIH_SAMPLE:
+ case VSIR_OP_SAMPLE:
op = SpvOpImageSampleImplicitLod;
break;
- case VKD3DSIH_SAMPLE_B:
+ case VSIR_OP_SAMPLE_B:
op = SpvOpImageSampleImplicitLod;
operands_mask |= SpvImageOperandsBiasMask;
image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler,
&src[3], VKD3DSP_WRITEMASK_0);
break;
- case VKD3DSIH_SAMPLE_GRAD:
+ case VSIR_OP_SAMPLE_GRAD:
op = SpvOpImageSampleExplicitLod;
operands_mask |= SpvImageOperandsGradMask;
component_count = image.resource_type_info->coordinate_component_count - image.resource_type_info->arrayed;
@@ -9247,14 +9095,16 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler,
image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler,
&src[4], coordinate_mask);
break;
- case VKD3DSIH_SAMPLE_LOD:
+ case VSIR_OP_SAMPLE_LOD:
op = SpvOpImageSampleExplicitLod;
operands_mask |= SpvImageOperandsLodMask;
image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler,
&src[3], VKD3DSP_WRITEMASK_0);
break;
default:
- ERR("Unexpected instruction %#x.\n", instruction->opcode);
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED,
+ "Unhandled instruction \"%s\" (%#x).",
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
return;
}
@@ -9288,7 +9138,7 @@ static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler,
uint32_t image_operands[2];
SpvOp op;
- if (instruction->opcode == VKD3DSIH_SAMPLE_C_LZ)
+ if (instruction->opcode == VSIR_OP_SAMPLE_C_LZ)
{
op = SpvOpImageSampleDrefExplicitLod;
operands_mask |= SpvImageOperandsLodMask;
@@ -9338,12 +9188,12 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler,
uint32_t coordinate_mask;
bool extended_offset;
- if (instruction->opcode == VKD3DSIH_GATHER4_C
- || instruction->opcode == VKD3DSIH_GATHER4_PO_C)
+ if (instruction->opcode == VSIR_OP_GATHER4_C
+ || instruction->opcode == VSIR_OP_GATHER4_PO_C)
image_flags |= VKD3D_IMAGE_FLAG_DEPTH;
- extended_offset = instruction->opcode == VKD3DSIH_GATHER4_PO
- || instruction->opcode == VKD3DSIH_GATHER4_PO_C;
+ extended_offset = instruction->opcode == VSIR_OP_GATHER4_PO
+ || instruction->opcode == VSIR_OP_GATHER4_PO_C;
addr = &src[0];
offset = extended_offset ? &src[1] : NULL;
@@ -9597,7 +9447,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler *
&src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0);
data = &src[instruction->src_count - 1];
- VKD3D_ASSERT(data->reg.data_type == VKD3D_DATA_UINT);
+ VKD3D_ASSERT(data->reg.data_type == VSIR_DATA_U32);
val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask);
component_count = vsir_write_mask_component_count(dst->write_mask);
@@ -9625,7 +9475,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler *
type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0);
data = &src[instruction->src_count - 1];
- VKD3D_ASSERT(data->reg.data_type == VKD3D_DATA_UINT);
+ VKD3D_ASSERT(data->reg.data_type == VSIR_DATA_U32);
val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask);
component_count = vsir_write_mask_component_count(dst->write_mask);
@@ -9668,7 +9518,7 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler,
type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0);
data = src[instruction->src_count - 1];
- data.reg.data_type = VKD3D_DATA_UINT;
+ data.reg.data_type = VSIR_DATA_U32;
val_id = spirv_compiler_emit_load_src(compiler, &data, dst->write_mask);
component_count = vsir_write_mask_component_count(dst->write_mask);
@@ -9801,7 +9651,7 @@ static void spirv_compiler_emit_uav_counter_instruction(struct spirv_compiler *c
uint32_t operands[3];
SpvOp op;
- op = instruction->opcode == VKD3DSIH_IMM_ATOMIC_ALLOC
+ op = instruction->opcode == VSIR_OP_IMM_ATOMIC_ALLOC
? SpvOpAtomicIIncrement : SpvOpAtomicIDecrement;
resource_symbol = spirv_compiler_find_resource(compiler, &src->reg);
@@ -9872,25 +9722,25 @@ static SpvOp spirv_compiler_map_atomic_instruction(const struct vkd3d_shader_ins
}
atomic_ops[] =
{
- {VKD3DSIH_ATOMIC_AND, SpvOpAtomicAnd},
- {VKD3DSIH_ATOMIC_CMP_STORE, SpvOpAtomicCompareExchange},
- {VKD3DSIH_ATOMIC_IADD, SpvOpAtomicIAdd},
- {VKD3DSIH_ATOMIC_IMAX, SpvOpAtomicSMax},
- {VKD3DSIH_ATOMIC_IMIN, SpvOpAtomicSMin},
- {VKD3DSIH_ATOMIC_OR, SpvOpAtomicOr},
- {VKD3DSIH_ATOMIC_UMAX, SpvOpAtomicUMax},
- {VKD3DSIH_ATOMIC_UMIN, SpvOpAtomicUMin},
- {VKD3DSIH_ATOMIC_XOR, SpvOpAtomicXor},
- {VKD3DSIH_IMM_ATOMIC_AND, SpvOpAtomicAnd},
- {VKD3DSIH_IMM_ATOMIC_CMP_EXCH, SpvOpAtomicCompareExchange},
- {VKD3DSIH_IMM_ATOMIC_EXCH, SpvOpAtomicExchange},
- {VKD3DSIH_IMM_ATOMIC_IADD, SpvOpAtomicIAdd},
- {VKD3DSIH_IMM_ATOMIC_IMAX, SpvOpAtomicSMax},
- {VKD3DSIH_IMM_ATOMIC_IMIN, SpvOpAtomicSMin},
- {VKD3DSIH_IMM_ATOMIC_OR, SpvOpAtomicOr},
- {VKD3DSIH_IMM_ATOMIC_UMAX, SpvOpAtomicUMax},
- {VKD3DSIH_IMM_ATOMIC_UMIN, SpvOpAtomicUMin},
- {VKD3DSIH_IMM_ATOMIC_XOR, SpvOpAtomicXor},
+ {VSIR_OP_ATOMIC_AND, SpvOpAtomicAnd},
+ {VSIR_OP_ATOMIC_CMP_STORE, SpvOpAtomicCompareExchange},
+ {VSIR_OP_ATOMIC_IADD, SpvOpAtomicIAdd},
+ {VSIR_OP_ATOMIC_IMAX, SpvOpAtomicSMax},
+ {VSIR_OP_ATOMIC_IMIN, SpvOpAtomicSMin},
+ {VSIR_OP_ATOMIC_OR, SpvOpAtomicOr},
+ {VSIR_OP_ATOMIC_UMAX, SpvOpAtomicUMax},
+ {VSIR_OP_ATOMIC_UMIN, SpvOpAtomicUMin},
+ {VSIR_OP_ATOMIC_XOR, SpvOpAtomicXor},
+ {VSIR_OP_IMM_ATOMIC_AND, SpvOpAtomicAnd},
+ {VSIR_OP_IMM_ATOMIC_CMP_EXCH, SpvOpAtomicCompareExchange},
+ {VSIR_OP_IMM_ATOMIC_EXCH, SpvOpAtomicExchange},
+ {VSIR_OP_IMM_ATOMIC_IADD, SpvOpAtomicIAdd},
+ {VSIR_OP_IMM_ATOMIC_IMAX, SpvOpAtomicSMax},
+ {VSIR_OP_IMM_ATOMIC_IMIN, SpvOpAtomicSMin},
+ {VSIR_OP_IMM_ATOMIC_OR, SpvOpAtomicOr},
+ {VSIR_OP_IMM_ATOMIC_UMAX, SpvOpAtomicUMax},
+ {VSIR_OP_IMM_ATOMIC_UMIN, SpvOpAtomicUMin},
+ {VSIR_OP_IMM_ATOMIC_XOR, SpvOpAtomicXor},
};
unsigned int i;
@@ -9905,7 +9755,7 @@ static SpvOp spirv_compiler_map_atomic_instruction(const struct vkd3d_shader_ins
static bool is_imm_atomic_instruction(enum vkd3d_shader_opcode opcode)
{
- return VKD3DSIH_IMM_ATOMIC_ALLOC <= opcode && opcode <= VKD3DSIH_IMM_ATOMIC_XOR;
+ return VSIR_OP_IMM_ATOMIC_ALLOC <= opcode && opcode <= VSIR_OP_IMM_ATOMIC_XOR;
}
static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compiler,
@@ -9935,7 +9785,9 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil
op = spirv_compiler_map_atomic_instruction(instruction);
if (op == SpvOpMax)
{
- ERR("Unexpected instruction %#x.\n", instruction->opcode);
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED,
+ "Unhandled instruction \"%s\" (%#x).",
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
return;
}
@@ -10014,9 +9866,9 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil
if (instruction->flags & VKD3DARF_VOLATILE)
{
- WARN("Ignoring 'volatile' attribute.\n");
spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_IGNORING_FLAG,
- "Ignoring the 'volatile' attribute flag for atomic instruction %#x.", instruction->opcode);
+ "Ignoring the 'volatile' attribute flag for atomic instruction \"%s\" (%#x).",
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
}
memory_semantic = (instruction->flags & VKD3DARF_SEQ_CST)
@@ -10094,16 +9946,20 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler,
static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
+ enum vkd3d_shader_component_type component_type = VKD3D_SHADER_COMPONENT_UINT;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_dst_param *dst = instruction->dst;
const struct vkd3d_shader_src_param *src = instruction->src;
uint32_t type_id, lod_id, val_id, miplevel_count_id;
- enum vkd3d_shader_component_type component_type;
uint32_t constituents[VKD3D_VEC4_SIZE];
unsigned int i, size_component_count;
struct vkd3d_shader_image image;
bool supports_mipmaps;
+ if (instruction->flags & ~(VKD3DSI_RESINFO_UINT | VKD3DSI_PRECISE_XYZW))
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, "Unhandled resinfo flags %#x.\n",
+ instruction->flags & ~(VKD3DSI_RESINFO_UINT | VKD3DSI_PRECISE_XYZW));
+
vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery);
spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE);
@@ -10135,22 +9991,13 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler,
val_id = vkd3d_spirv_build_op_composite_construct(builder,
type_id, constituents, i + 2);
- component_type = VKD3D_SHADER_COMPONENT_FLOAT;
-
- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE);
- if (instruction->flags == VKD3DSI_RESINFO_UINT)
- {
- /* SSA registers must match the specified result type. */
- if (!register_is_ssa(&dst->reg))
- val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id);
- else
- component_type = VKD3D_SHADER_COMPONENT_UINT;
- }
- else
+ if (!(instruction->flags & VKD3DSI_RESINFO_UINT))
{
- if (instruction->flags)
- FIXME("Unhandled flags %#x.\n", instruction->flags);
+ component_type = VKD3D_SHADER_COMPONENT_FLOAT;
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE);
val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id);
+ if (instruction->flags & VKD3DSI_PRECISE_XYZW)
+ vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0);
}
val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL,
component_type, src[1].swizzle, dst->write_mask);
@@ -10168,7 +10015,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co
if (src->reg.type == VKD3DSPR_RASTERIZER)
{
val_id = spirv_compiler_emit_shader_parameter(compiler,
- VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT, VKD3D_DATA_UINT, 1);
+ VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT, VSIR_DATA_U32, 1);
}
else
{
@@ -10185,6 +10032,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co
static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
+ enum vkd3d_shader_component_type component_type = VKD3D_SHADER_COMPONENT_UINT;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_dst_param *dst = instruction->dst;
const struct vkd3d_shader_src_param *src = instruction->src;
@@ -10192,6 +10040,10 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler,
uint32_t type_id, val_id;
unsigned int i;
+ if (instruction->flags & ~(VKD3DSI_SAMPLE_INFO_UINT | VKD3DSI_PRECISE_XYZW))
+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, "Unhandled sample info flags %#x.\n",
+ instruction->flags & ~(VKD3DSI_SAMPLE_INFO_UINT | VKD3DSI_PRECISE_XYZW));
+
val_id = spirv_compiler_emit_query_sample_count(compiler, src);
constituents[0] = val_id;
@@ -10200,20 +10052,16 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler,
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE);
val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, VKD3D_VEC4_SIZE);
- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE);
- if (instruction->flags == VKD3DSI_SAMPLE_INFO_UINT)
- {
- val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id);
- }
- else
+ if (!(instruction->flags & VKD3DSI_SAMPLE_INFO_UINT))
{
- if (instruction->flags)
- FIXME("Unhandled flags %#x.\n", instruction->flags);
+ component_type = VKD3D_SHADER_COMPONENT_FLOAT;
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE);
val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id);
+ if (instruction->flags & VKD3DSI_PRECISE_XYZW)
+ vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0);
}
-
val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL,
- VKD3D_SHADER_COMPONENT_FLOAT, src->swizzle, dst->write_mask);
+ component_type, src->swizzle, dst->write_mask);
spirv_compiler_emit_store_dst(compiler, dst, val_id);
}
@@ -10340,13 +10188,13 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler,
src_ids[src_count++] = register_info.id;
- if (instruction->opcode == VKD3DSIH_EVAL_CENTROID)
+ if (instruction->opcode == VSIR_OP_EVAL_CENTROID)
{
op = GLSLstd450InterpolateAtCentroid;
}
else
{
- VKD3D_ASSERT(instruction->opcode == VKD3DSIH_EVAL_SAMPLE_INDEX);
+ VKD3D_ASSERT(instruction->opcode == VSIR_OP_EVAL_SAMPLE_INDEX);
op = GLSLstd450InterpolateAtSample;
src_ids[src_count++] = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0);
}
@@ -10428,7 +10276,7 @@ static void spirv_compiler_emit_emit_stream(struct spirv_compiler *compiler,
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
unsigned int stream_idx;
- if (instruction->opcode == VKD3DSIH_EMIT_STREAM)
+ if (instruction->opcode == VSIR_OP_EMIT_STREAM)
stream_idx = instruction->src[0].reg.idx[0].offset;
else
stream_idx = 0;
@@ -10449,7 +10297,7 @@ static void spirv_compiler_emit_cut_stream(struct spirv_compiler *compiler,
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
unsigned int stream_idx;
- if (instruction->opcode == VKD3DSIH_CUT_STREAM)
+ if (instruction->opcode == VSIR_OP_CUT_STREAM)
stream_idx = instruction->src[0].reg.idx[0].offset;
else
stream_idx = 0;
@@ -10467,11 +10315,11 @@ static uint32_t map_quad_read_across_direction(enum vkd3d_shader_opcode opcode)
{
switch (opcode)
{
- case VKD3DSIH_QUAD_READ_ACROSS_X:
+ case VSIR_OP_QUAD_READ_ACROSS_X:
return 0;
- case VKD3DSIH_QUAD_READ_ACROSS_Y:
+ case VSIR_OP_QUAD_READ_ACROSS_Y:
return 1;
- case VKD3DSIH_QUAD_READ_ACROSS_D:
+ case VSIR_OP_QUAD_READ_ACROSS_D:
return 2;
default:
vkd3d_unreachable();
@@ -10488,7 +10336,7 @@ static void spirv_compiler_emit_quad_read_across(struct spirv_compiler *compiler
type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type,
vsir_write_mask_component_count(dst->write_mask));
- direction_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, VKD3D_DATA_UINT, 1);
+ direction_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, VSIR_DATA_U32, 1);
val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask);
direction_id = map_quad_read_across_direction(instruction->opcode);
direction_id = vkd3d_spirv_get_op_constant(builder, direction_type_id, direction_id);
@@ -10526,11 +10374,11 @@ static SpvOp map_wave_bool_op(enum vkd3d_shader_opcode opcode)
{
switch (opcode)
{
- case VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL:
+ case VSIR_OP_WAVE_ACTIVE_ALL_EQUAL:
return SpvOpGroupNonUniformAllEqual;
- case VKD3DSIH_WAVE_ALL_TRUE:
+ case VSIR_OP_WAVE_ALL_TRUE:
return SpvOpGroupNonUniformAll;
- case VKD3DSIH_WAVE_ANY_TRUE:
+ case VSIR_OP_WAVE_ANY_TRUE:
return SpvOpGroupNonUniformAny;
default:
vkd3d_unreachable();
@@ -10584,27 +10432,27 @@ static SpvOp map_wave_alu_op(enum vkd3d_shader_opcode opcode, bool is_float)
{
switch (opcode)
{
- case VKD3DSIH_WAVE_ACTIVE_BIT_AND:
+ case VSIR_OP_WAVE_ACTIVE_BIT_AND:
return SpvOpGroupNonUniformBitwiseAnd;
- case VKD3DSIH_WAVE_ACTIVE_BIT_OR:
+ case VSIR_OP_WAVE_ACTIVE_BIT_OR:
return SpvOpGroupNonUniformBitwiseOr;
- case VKD3DSIH_WAVE_ACTIVE_BIT_XOR:
+ case VSIR_OP_WAVE_ACTIVE_BIT_XOR:
return SpvOpGroupNonUniformBitwiseXor;
- case VKD3DSIH_WAVE_OP_ADD:
+ case VSIR_OP_WAVE_OP_ADD:
return is_float ? SpvOpGroupNonUniformFAdd : SpvOpGroupNonUniformIAdd;
- case VKD3DSIH_WAVE_OP_IMAX:
+ case VSIR_OP_WAVE_OP_IMAX:
return SpvOpGroupNonUniformSMax;
- case VKD3DSIH_WAVE_OP_IMIN:
+ case VSIR_OP_WAVE_OP_IMIN:
return SpvOpGroupNonUniformSMin;
- case VKD3DSIH_WAVE_OP_MAX:
+ case VSIR_OP_WAVE_OP_MAX:
return SpvOpGroupNonUniformFMax;
- case VKD3DSIH_WAVE_OP_MIN:
+ case VSIR_OP_WAVE_OP_MIN:
return SpvOpGroupNonUniformFMin;
- case VKD3DSIH_WAVE_OP_MUL:
+ case VSIR_OP_WAVE_OP_MUL:
return is_float ? SpvOpGroupNonUniformFMul : SpvOpGroupNonUniformIMul;
- case VKD3DSIH_WAVE_OP_UMAX:
+ case VSIR_OP_WAVE_OP_UMAX:
return SpvOpGroupNonUniformUMax;
- case VKD3DSIH_WAVE_OP_UMIN:
+ case VSIR_OP_WAVE_OP_UMIN:
return SpvOpGroupNonUniformUMin;
default:
vkd3d_unreachable();
@@ -10643,7 +10491,7 @@ static void spirv_compiler_emit_wave_bit_count(struct spirv_compiler *compiler,
SpvGroupOperation group_op;
uint32_t type_id, val_id;
- group_op = (instruction->opcode == VKD3DSIH_WAVE_PREFIX_BIT_COUNT) ? SpvGroupOperationExclusiveScan
+ group_op = (instruction->opcode == VSIR_OP_WAVE_PREFIX_BIT_COUNT) ? SpvGroupOperationExclusiveScan
: SpvGroupOperationReduce;
val_id = spirv_compiler_emit_group_nonuniform_ballot(compiler, instruction->src);
@@ -10728,372 +10576,379 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
int ret = VKD3D_OK;
compiler->location = instruction->location;
+ /* radeonsi from Mesa 20.3.5 seems to get confused by OpLine instructions
+ * before OpFunction, seemingly causing it to fail to find the entry
+ * point. As far as I can tell that's not prohibited, and the validation
+ * layers don't seem to mind either, but perhaps it's best avoided.
+ * Notably, radv from the same Mesa version doesn't mind either.
+ *
+ * This is an issue for hull shaders in particular, because we don't go
+ * through vkd3d_spirv_builder_begin_main_function() before getting here
+ * in that case. */
+ if (!compiler->strip_debug && compiler->spirv_builder.function_stream.word_count)
+ vkd3d_spirv_build_op_line(&compiler->spirv_builder, &instruction->location);
switch (instruction->opcode)
{
- case VKD3DSIH_DCL_INDEXABLE_TEMP:
+ case VSIR_OP_DCL_INDEXABLE_TEMP:
spirv_compiler_emit_dcl_indexable_temp(compiler, instruction);
break;
- case VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER:
+ case VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER:
spirv_compiler_emit_dcl_immediate_constant_buffer(compiler, instruction);
break;
- case VKD3DSIH_DCL_TGSM_RAW:
+ case VSIR_OP_DCL_TGSM_RAW:
spirv_compiler_emit_dcl_tgsm_raw(compiler, instruction);
break;
- case VKD3DSIH_DCL_TGSM_STRUCTURED:
+ case VSIR_OP_DCL_TGSM_STRUCTURED:
spirv_compiler_emit_dcl_tgsm_structured(compiler, instruction);
break;
- case VKD3DSIH_DCL_STREAM:
+ case VSIR_OP_DCL_STREAM:
spirv_compiler_emit_dcl_stream(compiler, instruction);
break;
- case VKD3DSIH_DCL_VERTICES_OUT:
+ case VSIR_OP_DCL_VERTICES_OUT:
spirv_compiler_emit_output_vertex_count(compiler, instruction);
break;
- case VKD3DSIH_DCL_INPUT_PRIMITIVE:
+ case VSIR_OP_DCL_INPUT_PRIMITIVE:
spirv_compiler_emit_dcl_input_primitive(compiler, instruction);
break;
- case VKD3DSIH_DCL_OUTPUT_TOPOLOGY:
+ case VSIR_OP_DCL_OUTPUT_TOPOLOGY:
spirv_compiler_emit_dcl_output_topology(compiler, instruction);
break;
- case VKD3DSIH_DCL_GS_INSTANCES:
+ case VSIR_OP_DCL_GS_INSTANCES:
spirv_compiler_emit_dcl_gs_instances(compiler, instruction);
break;
- case VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT:
+ case VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT:
spirv_compiler_emit_output_vertex_count(compiler, instruction);
break;
- case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE:
+ case VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE:
spirv_compiler_emit_tessellator_output_primitive(compiler,
instruction->declaration.tessellator_output_primitive);
break;
- case VKD3DSIH_DCL_TESSELLATOR_PARTITIONING:
+ case VSIR_OP_DCL_TESSELLATOR_PARTITIONING:
spirv_compiler_emit_tessellator_partitioning(compiler,
instruction->declaration.tessellator_partitioning);
break;
- case VKD3DSIH_HS_CONTROL_POINT_PHASE:
- case VKD3DSIH_HS_FORK_PHASE:
- case VKD3DSIH_HS_JOIN_PHASE:
+ case VSIR_OP_HS_CONTROL_POINT_PHASE:
+ case VSIR_OP_HS_FORK_PHASE:
+ case VSIR_OP_HS_JOIN_PHASE:
spirv_compiler_enter_shader_phase(compiler, instruction);
break;
- case VKD3DSIH_DMOV:
- case VKD3DSIH_MOV:
+ case VSIR_OP_DMOV:
+ case VSIR_OP_MOV:
spirv_compiler_emit_mov(compiler, instruction);
break;
- case VKD3DSIH_DMOVC:
- case VKD3DSIH_MOVC:
- case VKD3DSIH_CMP:
+ case VSIR_OP_DMOVC:
+ case VSIR_OP_MOVC:
+ case VSIR_OP_CMP:
spirv_compiler_emit_movc(compiler, instruction);
break;
- case VKD3DSIH_SWAPC:
+ case VSIR_OP_SWAPC:
spirv_compiler_emit_swapc(compiler, instruction);
break;
- case VKD3DSIH_ADD:
- case VKD3DSIH_AND:
- case VKD3DSIH_BFREV:
- case VKD3DSIH_COUNTBITS:
- case VKD3DSIH_DADD:
- case VKD3DSIH_DDIV:
- case VKD3DSIH_DIV:
- case VKD3DSIH_DMUL:
- case VKD3DSIH_FREM:
- case VKD3DSIH_FTOD:
- case VKD3DSIH_IADD:
- case VKD3DSIH_INEG:
- case VKD3DSIH_ISHL:
- case VKD3DSIH_ISHR:
- case VKD3DSIH_ISINF:
- case VKD3DSIH_ISNAN:
- case VKD3DSIH_ITOD:
- case VKD3DSIH_ITOF:
- case VKD3DSIH_ITOI:
- case VKD3DSIH_MUL:
- case VKD3DSIH_NOT:
- case VKD3DSIH_OR:
- case VKD3DSIH_USHR:
- case VKD3DSIH_UTOD:
- case VKD3DSIH_UTOF:
- case VKD3DSIH_UTOU:
- case VKD3DSIH_XOR:
+ case VSIR_OP_ADD:
+ case VSIR_OP_AND:
+ case VSIR_OP_BFREV:
+ case VSIR_OP_COUNTBITS:
+ case VSIR_OP_DADD:
+ case VSIR_OP_DDIV:
+ case VSIR_OP_DIV:
+ case VSIR_OP_DMUL:
+ case VSIR_OP_FREM:
+ case VSIR_OP_FTOD:
+ case VSIR_OP_IADD:
+ case VSIR_OP_IDIV:
+ case VSIR_OP_IMUL_LOW:
+ case VSIR_OP_INEG:
+ case VSIR_OP_IREM:
+ case VSIR_OP_ISHL:
+ case VSIR_OP_ISHR:
+ case VSIR_OP_ISINF:
+ case VSIR_OP_ISNAN:
+ case VSIR_OP_ITOD:
+ case VSIR_OP_ITOF:
+ case VSIR_OP_ITOI:
+ case VSIR_OP_MUL:
+ case VSIR_OP_NOT:
+ case VSIR_OP_OR:
+ case VSIR_OP_UDIV_SIMPLE:
+ case VSIR_OP_UREM:
+ case VSIR_OP_USHR:
+ case VSIR_OP_UTOD:
+ case VSIR_OP_UTOF:
+ case VSIR_OP_UTOU:
+ case VSIR_OP_XOR:
ret = spirv_compiler_emit_alu_instruction(compiler, instruction);
break;
- case VKD3DSIH_ISFINITE:
+ case VSIR_OP_ISFINITE:
spirv_compiler_emit_isfinite(compiler, instruction);
break;
- case VKD3DSIH_ABS:
- case VKD3DSIH_ACOS:
- case VKD3DSIH_ASIN:
- case VKD3DSIH_ATAN:
- case VKD3DSIH_HCOS:
- case VKD3DSIH_HSIN:
- case VKD3DSIH_HTAN:
- case VKD3DSIH_DFMA:
- case VKD3DSIH_DMAX:
- case VKD3DSIH_DMIN:
- case VKD3DSIH_EXP:
- case VKD3DSIH_FIRSTBIT_HI:
- case VKD3DSIH_FIRSTBIT_LO:
- case VKD3DSIH_FIRSTBIT_SHI:
- case VKD3DSIH_FRC:
- case VKD3DSIH_IMAX:
- case VKD3DSIH_IMIN:
- case VKD3DSIH_LOG:
- case VKD3DSIH_MAD:
- case VKD3DSIH_MAX:
- case VKD3DSIH_MIN:
- case VKD3DSIH_ROUND_NE:
- case VKD3DSIH_ROUND_NI:
- case VKD3DSIH_ROUND_PI:
- case VKD3DSIH_ROUND_Z:
- case VKD3DSIH_RSQ:
- case VKD3DSIH_SQRT:
- case VKD3DSIH_TAN:
- case VKD3DSIH_UMAX:
- case VKD3DSIH_UMIN:
+ case VSIR_OP_ABS:
+ case VSIR_OP_ACOS:
+ case VSIR_OP_ASIN:
+ case VSIR_OP_ATAN:
+ case VSIR_OP_COS:
+ case VSIR_OP_HCOS:
+ case VSIR_OP_HSIN:
+ case VSIR_OP_HTAN:
+ case VSIR_OP_DFMA:
+ case VSIR_OP_DMAX:
+ case VSIR_OP_DMIN:
+ case VSIR_OP_EXP:
+ case VSIR_OP_FIRSTBIT_HI:
+ case VSIR_OP_FIRSTBIT_LO:
+ case VSIR_OP_FIRSTBIT_SHI:
+ case VSIR_OP_FRC:
+ case VSIR_OP_IMAX:
+ case VSIR_OP_IMIN:
+ case VSIR_OP_LOG:
+ case VSIR_OP_MAD:
+ case VSIR_OP_MAX:
+ case VSIR_OP_MIN:
+ case VSIR_OP_ROUND_NE:
+ case VSIR_OP_ROUND_NI:
+ case VSIR_OP_ROUND_PI:
+ case VSIR_OP_ROUND_Z:
+ case VSIR_OP_RSQ:
+ case VSIR_OP_SIN:
+ case VSIR_OP_SQRT:
+ case VSIR_OP_TAN:
+ case VSIR_OP_UMAX:
+ case VSIR_OP_UMIN:
spirv_compiler_emit_ext_glsl_instruction(compiler, instruction);
break;
- case VKD3DSIH_DP4:
- case VKD3DSIH_DP3:
- case VKD3DSIH_DP2:
+ case VSIR_OP_DP4:
+ case VSIR_OP_DP3:
+ case VSIR_OP_DP2:
spirv_compiler_emit_dot(compiler, instruction);
break;
- case VKD3DSIH_DRCP:
- case VKD3DSIH_RCP:
+ case VSIR_OP_DRCP:
+ case VSIR_OP_RCP:
spirv_compiler_emit_rcp(compiler, instruction);
break;
- case VKD3DSIH_SINCOS:
- spirv_compiler_emit_sincos(compiler, instruction);
- break;
- case VKD3DSIH_IMUL:
- case VKD3DSIH_UMUL:
- spirv_compiler_emit_imul(compiler, instruction);
- break;
- case VKD3DSIH_IMAD:
+ case VSIR_OP_IMAD:
spirv_compiler_emit_imad(compiler, instruction);
break;
- case VKD3DSIH_IDIV:
- case VKD3DSIH_UDIV:
- spirv_compiler_emit_int_div(compiler, instruction);
- break;
- case VKD3DSIH_DTOI:
- case VKD3DSIH_FTOI:
+ case VSIR_OP_DTOI:
+ case VSIR_OP_FTOI:
spirv_compiler_emit_ftoi(compiler, instruction);
break;
- case VKD3DSIH_DTOU:
- case VKD3DSIH_FTOU:
+ case VSIR_OP_DTOU:
+ case VSIR_OP_FTOU:
spirv_compiler_emit_ftou(compiler, instruction);
break;
- case VKD3DSIH_DTOF:
+ case VSIR_OP_DTOF:
spirv_compiler_emit_dtof(compiler, instruction);
break;
- case VKD3DSIH_DEQO:
- case VKD3DSIH_DGEO:
- case VKD3DSIH_DLT:
- case VKD3DSIH_DNE:
- case VKD3DSIH_EQO:
- case VKD3DSIH_EQU:
- case VKD3DSIH_GEO:
- case VKD3DSIH_GEU:
- case VKD3DSIH_IEQ:
- case VKD3DSIH_IGE:
- case VKD3DSIH_ILT:
- case VKD3DSIH_INE:
- case VKD3DSIH_LTO:
- case VKD3DSIH_LTU:
- case VKD3DSIH_NEO:
- case VKD3DSIH_NEU:
- case VKD3DSIH_UGE:
- case VKD3DSIH_ULT:
+ case VSIR_OP_DEQO:
+ case VSIR_OP_DGEO:
+ case VSIR_OP_DLT:
+ case VSIR_OP_DNE:
+ case VSIR_OP_EQO:
+ case VSIR_OP_EQU:
+ case VSIR_OP_GEO:
+ case VSIR_OP_GEU:
+ case VSIR_OP_IEQ:
+ case VSIR_OP_IGE:
+ case VSIR_OP_ILT:
+ case VSIR_OP_INE:
+ case VSIR_OP_LTO:
+ case VSIR_OP_LTU:
+ case VSIR_OP_NEO:
+ case VSIR_OP_NEU:
+ case VSIR_OP_UGE:
+ case VSIR_OP_ULT:
spirv_compiler_emit_comparison_instruction(compiler, instruction);
break;
- case VKD3DSIH_ORD:
- case VKD3DSIH_UNO:
+ case VSIR_OP_ORD:
+ case VSIR_OP_UNO:
spirv_compiler_emit_orderedness_instruction(compiler, instruction);
break;
- case VKD3DSIH_SLT:
- case VKD3DSIH_SGE:
+ case VSIR_OP_SLT:
+ case VSIR_OP_SGE:
spirv_compiler_emit_float_comparison_instruction(compiler, instruction);
break;
- case VKD3DSIH_BFI:
- case VKD3DSIH_IBFE:
- case VKD3DSIH_UBFE:
+ case VSIR_OP_BFI:
+ case VSIR_OP_IBFE:
+ case VSIR_OP_UBFE:
spirv_compiler_emit_bitfield_instruction(compiler, instruction);
break;
- case VKD3DSIH_F16TOF32:
+ case VSIR_OP_F16TOF32:
spirv_compiler_emit_f16tof32(compiler, instruction);
break;
- case VKD3DSIH_F32TOF16:
+ case VSIR_OP_F32TOF16:
spirv_compiler_emit_f32tof16(compiler, instruction);
break;
- case VKD3DSIH_RET:
+ case VSIR_OP_RET:
spirv_compiler_emit_return(compiler, instruction);
break;
- case VKD3DSIH_RETP:
+ case VSIR_OP_RETP:
spirv_compiler_emit_retc(compiler, instruction);
break;
- case VKD3DSIH_DISCARD:
+ case VSIR_OP_DISCARD:
spirv_compiler_emit_discard(compiler, instruction);
break;
- case VKD3DSIH_LABEL:
+ case VSIR_OP_LABEL:
spirv_compiler_emit_label(compiler, instruction);
break;
- case VKD3DSIH_BRANCH:
+ case VSIR_OP_BRANCH:
spirv_compiler_emit_branch(compiler, instruction);
break;
- case VKD3DSIH_SWITCH_MONOLITHIC:
+ case VSIR_OP_SWITCH_MONOLITHIC:
spirv_compiler_emit_switch(compiler, instruction);
break;
- case VKD3DSIH_DSX:
- case VKD3DSIH_DSX_COARSE:
- case VKD3DSIH_DSX_FINE:
- case VKD3DSIH_DSY:
- case VKD3DSIH_DSY_COARSE:
- case VKD3DSIH_DSY_FINE:
+ case VSIR_OP_DSX:
+ case VSIR_OP_DSX_COARSE:
+ case VSIR_OP_DSX_FINE:
+ case VSIR_OP_DSY:
+ case VSIR_OP_DSY_COARSE:
+ case VSIR_OP_DSY_FINE:
spirv_compiler_emit_deriv_instruction(compiler, instruction);
break;
- case VKD3DSIH_LD2DMS:
- case VKD3DSIH_LD:
+ case VSIR_OP_LD2DMS:
+ case VSIR_OP_LD:
spirv_compiler_emit_ld(compiler, instruction);
break;
- case VKD3DSIH_LOD:
+ case VSIR_OP_LOD:
spirv_compiler_emit_lod(compiler, instruction);
break;
- case VKD3DSIH_SAMPLE:
- case VKD3DSIH_SAMPLE_B:
- case VKD3DSIH_SAMPLE_GRAD:
- case VKD3DSIH_SAMPLE_LOD:
+ case VSIR_OP_SAMPLE:
+ case VSIR_OP_SAMPLE_B:
+ case VSIR_OP_SAMPLE_GRAD:
+ case VSIR_OP_SAMPLE_LOD:
spirv_compiler_emit_sample(compiler, instruction);
break;
- case VKD3DSIH_SAMPLE_C:
- case VKD3DSIH_SAMPLE_C_LZ:
+ case VSIR_OP_SAMPLE_C:
+ case VSIR_OP_SAMPLE_C_LZ:
spirv_compiler_emit_sample_c(compiler, instruction);
break;
- case VKD3DSIH_GATHER4:
- case VKD3DSIH_GATHER4_C:
- case VKD3DSIH_GATHER4_PO:
- case VKD3DSIH_GATHER4_PO_C:
+ case VSIR_OP_GATHER4:
+ case VSIR_OP_GATHER4_C:
+ case VSIR_OP_GATHER4_PO:
+ case VSIR_OP_GATHER4_PO_C:
spirv_compiler_emit_gather4(compiler, instruction);
break;
- case VKD3DSIH_LD_RAW:
- case VKD3DSIH_LD_STRUCTURED:
+ case VSIR_OP_LD_RAW:
+ case VSIR_OP_LD_STRUCTURED:
spirv_compiler_emit_ld_raw_structured(compiler, instruction);
break;
- case VKD3DSIH_STORE_RAW:
- case VKD3DSIH_STORE_STRUCTURED:
+ case VSIR_OP_STORE_RAW:
+ case VSIR_OP_STORE_STRUCTURED:
spirv_compiler_emit_store_raw_structured(compiler, instruction);
break;
- case VKD3DSIH_LD_UAV_TYPED:
+ case VSIR_OP_LD_UAV_TYPED:
spirv_compiler_emit_ld_uav_typed(compiler, instruction);
break;
- case VKD3DSIH_STORE_UAV_TYPED:
+ case VSIR_OP_STORE_UAV_TYPED:
spirv_compiler_emit_store_uav_typed(compiler, instruction);
break;
- case VKD3DSIH_IMM_ATOMIC_ALLOC:
- case VKD3DSIH_IMM_ATOMIC_CONSUME:
+ case VSIR_OP_IMM_ATOMIC_ALLOC:
+ case VSIR_OP_IMM_ATOMIC_CONSUME:
spirv_compiler_emit_uav_counter_instruction(compiler, instruction);
break;
- case VKD3DSIH_ATOMIC_AND:
- case VKD3DSIH_ATOMIC_CMP_STORE:
- case VKD3DSIH_ATOMIC_IADD:
- case VKD3DSIH_ATOMIC_IMAX:
- case VKD3DSIH_ATOMIC_IMIN:
- case VKD3DSIH_ATOMIC_OR:
- case VKD3DSIH_ATOMIC_UMAX:
- case VKD3DSIH_ATOMIC_UMIN:
- case VKD3DSIH_ATOMIC_XOR:
- case VKD3DSIH_IMM_ATOMIC_AND:
- case VKD3DSIH_IMM_ATOMIC_CMP_EXCH:
- case VKD3DSIH_IMM_ATOMIC_EXCH:
- case VKD3DSIH_IMM_ATOMIC_IADD:
- case VKD3DSIH_IMM_ATOMIC_IMAX:
- case VKD3DSIH_IMM_ATOMIC_IMIN:
- case VKD3DSIH_IMM_ATOMIC_OR:
- case VKD3DSIH_IMM_ATOMIC_UMAX:
- case VKD3DSIH_IMM_ATOMIC_UMIN:
- case VKD3DSIH_IMM_ATOMIC_XOR:
+ case VSIR_OP_ATOMIC_AND:
+ case VSIR_OP_ATOMIC_CMP_STORE:
+ case VSIR_OP_ATOMIC_IADD:
+ case VSIR_OP_ATOMIC_IMAX:
+ case VSIR_OP_ATOMIC_IMIN:
+ case VSIR_OP_ATOMIC_OR:
+ case VSIR_OP_ATOMIC_UMAX:
+ case VSIR_OP_ATOMIC_UMIN:
+ case VSIR_OP_ATOMIC_XOR:
+ case VSIR_OP_IMM_ATOMIC_AND:
+ case VSIR_OP_IMM_ATOMIC_CMP_EXCH:
+ case VSIR_OP_IMM_ATOMIC_EXCH:
+ case VSIR_OP_IMM_ATOMIC_IADD:
+ case VSIR_OP_IMM_ATOMIC_IMAX:
+ case VSIR_OP_IMM_ATOMIC_IMIN:
+ case VSIR_OP_IMM_ATOMIC_OR:
+ case VSIR_OP_IMM_ATOMIC_UMAX:
+ case VSIR_OP_IMM_ATOMIC_UMIN:
+ case VSIR_OP_IMM_ATOMIC_XOR:
spirv_compiler_emit_atomic_instruction(compiler, instruction);
break;
- case VKD3DSIH_BUFINFO:
+ case VSIR_OP_BUFINFO:
spirv_compiler_emit_bufinfo(compiler, instruction);
break;
- case VKD3DSIH_RESINFO:
+ case VSIR_OP_RESINFO:
spirv_compiler_emit_resinfo(compiler, instruction);
break;
- case VKD3DSIH_SAMPLE_INFO:
+ case VSIR_OP_SAMPLE_INFO:
spirv_compiler_emit_sample_info(compiler, instruction);
break;
- case VKD3DSIH_SAMPLE_POS:
+ case VSIR_OP_SAMPLE_POS:
spirv_compiler_emit_sample_position(compiler, instruction);
break;
- case VKD3DSIH_EVAL_CENTROID:
- case VKD3DSIH_EVAL_SAMPLE_INDEX:
+ case VSIR_OP_EVAL_CENTROID:
+ case VSIR_OP_EVAL_SAMPLE_INDEX:
spirv_compiler_emit_eval_attrib(compiler, instruction);
break;
- case VKD3DSIH_SYNC:
+ case VSIR_OP_SYNC:
spirv_compiler_emit_sync(compiler, instruction);
break;
- case VKD3DSIH_EMIT:
- case VKD3DSIH_EMIT_STREAM:
+ case VSIR_OP_EMIT:
+ case VSIR_OP_EMIT_STREAM:
spirv_compiler_emit_emit_stream(compiler, instruction);
break;
- case VKD3DSIH_CUT:
- case VKD3DSIH_CUT_STREAM:
+ case VSIR_OP_CUT:
+ case VSIR_OP_CUT_STREAM:
spirv_compiler_emit_cut_stream(compiler, instruction);
break;
- case VKD3DSIH_QUAD_READ_ACROSS_D:
- case VKD3DSIH_QUAD_READ_ACROSS_X:
- case VKD3DSIH_QUAD_READ_ACROSS_Y:
+ case VSIR_OP_QUAD_READ_ACROSS_D:
+ case VSIR_OP_QUAD_READ_ACROSS_X:
+ case VSIR_OP_QUAD_READ_ACROSS_Y:
spirv_compiler_emit_quad_read_across(compiler, instruction);
break;
- case VKD3DSIH_QUAD_READ_LANE_AT:
+ case VSIR_OP_QUAD_READ_LANE_AT:
spirv_compiler_emit_quad_read_lane_at(compiler, instruction);
break;
- case VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL:
- case VKD3DSIH_WAVE_ALL_TRUE:
- case VKD3DSIH_WAVE_ANY_TRUE:
+ case VSIR_OP_WAVE_ACTIVE_ALL_EQUAL:
+ case VSIR_OP_WAVE_ALL_TRUE:
+ case VSIR_OP_WAVE_ANY_TRUE:
spirv_compiler_emit_wave_bool_op(compiler, instruction);
break;
- case VKD3DSIH_WAVE_ACTIVE_BALLOT:
+ case VSIR_OP_WAVE_ACTIVE_BALLOT:
spirv_compiler_emit_wave_active_ballot(compiler, instruction);
break;
- case VKD3DSIH_WAVE_ACTIVE_BIT_AND:
- case VKD3DSIH_WAVE_ACTIVE_BIT_OR:
- case VKD3DSIH_WAVE_ACTIVE_BIT_XOR:
- case VKD3DSIH_WAVE_OP_ADD:
- case VKD3DSIH_WAVE_OP_IMAX:
- case VKD3DSIH_WAVE_OP_IMIN:
- case VKD3DSIH_WAVE_OP_MAX:
- case VKD3DSIH_WAVE_OP_MIN:
- case VKD3DSIH_WAVE_OP_MUL:
- case VKD3DSIH_WAVE_OP_UMAX:
- case VKD3DSIH_WAVE_OP_UMIN:
+ case VSIR_OP_WAVE_ACTIVE_BIT_AND:
+ case VSIR_OP_WAVE_ACTIVE_BIT_OR:
+ case VSIR_OP_WAVE_ACTIVE_BIT_XOR:
+ case VSIR_OP_WAVE_OP_ADD:
+ case VSIR_OP_WAVE_OP_IMAX:
+ case VSIR_OP_WAVE_OP_IMIN:
+ case VSIR_OP_WAVE_OP_MAX:
+ case VSIR_OP_WAVE_OP_MIN:
+ case VSIR_OP_WAVE_OP_MUL:
+ case VSIR_OP_WAVE_OP_UMAX:
+ case VSIR_OP_WAVE_OP_UMIN:
spirv_compiler_emit_wave_alu_op(compiler, instruction);
break;
- case VKD3DSIH_WAVE_ALL_BIT_COUNT:
- case VKD3DSIH_WAVE_PREFIX_BIT_COUNT:
+ case VSIR_OP_WAVE_ALL_BIT_COUNT:
+ case VSIR_OP_WAVE_PREFIX_BIT_COUNT:
spirv_compiler_emit_wave_bit_count(compiler, instruction);
break;
- case VKD3DSIH_WAVE_IS_FIRST_LANE:
+ case VSIR_OP_WAVE_IS_FIRST_LANE:
spirv_compiler_emit_wave_is_first_lane(compiler, instruction);
break;
- case VKD3DSIH_WAVE_READ_LANE_AT:
+ case VSIR_OP_WAVE_READ_LANE_AT:
spirv_compiler_emit_wave_read_lane_at(compiler, instruction);
break;
- case VKD3DSIH_WAVE_READ_LANE_FIRST:
+ case VSIR_OP_WAVE_READ_LANE_FIRST:
spirv_compiler_emit_wave_read_lane_first(compiler, instruction);
break;
- case VKD3DSIH_DCL_HS_MAX_TESSFACTOR:
- case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT:
- case VKD3DSIH_DCL_RESOURCE_RAW:
- case VKD3DSIH_DCL_RESOURCE_STRUCTURED:
- case VKD3DSIH_DCL_UAV_RAW:
- case VKD3DSIH_DCL_UAV_STRUCTURED:
- case VKD3DSIH_HS_DECLS:
- case VKD3DSIH_NOP:
+ case VSIR_OP_DCL_HS_MAX_TESSFACTOR:
+ case VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT:
+ case VSIR_OP_DCL_RESOURCE_RAW:
+ case VSIR_OP_DCL_RESOURCE_STRUCTURED:
+ case VSIR_OP_DCL_UAV_RAW:
+ case VSIR_OP_DCL_UAV_STRUCTURED:
+ case VSIR_OP_HS_DECLS:
+ case VSIR_OP_NOP:
/* nothing to do */
break;
default:
- FIXME("Unhandled instruction %#x.\n", instruction->opcode);
spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_HANDLER,
- "Encountered invalid/unhandled instruction handler %#x.", instruction->opcode);
+ "Unhandled instruction \"%s\" (%#x).",
+ vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode);
break;
}
@@ -11127,14 +10982,14 @@ static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler)
if (compiler->program->has_point_size)
{
- vsir_dst_param_init(&dst, VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1);
+ vsir_dst_param_init(&dst, VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1);
dst.reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE;
spirv_compiler_emit_io_register(compiler, &dst);
}
if (compiler->program->has_point_coord)
{
- vsir_dst_param_init(&dst, VKD3DSPR_POINT_COORD, VKD3D_DATA_FLOAT, 0);
+ vsir_dst_param_init(&dst, VKD3DSPR_POINT_COORD, VSIR_DATA_F32, 0);
spirv_compiler_emit_io_register(compiler, &dst);
}
@@ -11145,7 +11000,7 @@ static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler)
if (bitmap_is_set(compiler->program->io_dcls, i)
|| (compiler->program->shader_version.type == VKD3D_SHADER_TYPE_HULL && i == VKD3DSPR_OUTPOINTID))
{
- vsir_dst_param_init(&dst, i, VKD3D_DATA_FLOAT, 0);
+ vsir_dst_param_init(&dst, i, VSIR_DATA_F32, 0);
spirv_compiler_emit_io_register(compiler, &dst);
}
}
@@ -11195,11 +11050,12 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info;
const struct vkd3d_shader_spirv_domain_shader_target_info *ds_info;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- const struct vsir_program *program = compiler->program;
- struct vkd3d_shader_instruction_array instructions;
+ struct vsir_program *program = compiler->program;
enum vkd3d_shader_spirv_environment environment;
+ struct vkd3d_shader_instruction *ins;
enum vkd3d_result result = VKD3D_OK;
unsigned int i, max_element_count;
+ struct vsir_program_iterator it;
max_element_count = max(program->output_signature.element_count, program->patch_constant_signature.element_count);
if (!(compiler->output_info = vkd3d_calloc(max_element_count, sizeof(*compiler->output_info))))
@@ -11247,8 +11103,6 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
if (program->block_count && !spirv_compiler_init_blocks(compiler, program->block_count))
return VKD3D_ERROR_OUT_OF_MEMORY;
- instructions = program->instructions;
-
compiler->use_vocp = program->use_vocp;
compiler->block_names = program->block_names;
compiler->block_name_count = program->block_name_count;
@@ -11263,9 +11117,10 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
if (compiler->shader_type != VKD3D_SHADER_TYPE_HULL)
spirv_compiler_emit_shader_signature_outputs(compiler);
- for (i = 0; i < instructions.count && result >= 0; ++i)
+ it = vsir_program_iterator(&program->instructions);
+ for (ins = vsir_program_iterator_head(&it); ins && result >= 0; ins = vsir_program_iterator_next(&it))
{
- result = spirv_compiler_handle_instruction(compiler, &instructions.elements[i]);
+ result = spirv_compiler_handle_instruction(compiler, ins);
}
if (result < 0)
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
index 29b03871e05..ea15c1a9ad5 100644
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
@@ -261,6 +261,7 @@ enum vkd3d_sm4_opcode
VKD3D_SM4_OP_DCL_INPUT_PS_SGV = 0x63,
VKD3D_SM4_OP_DCL_INPUT_PS_SIV = 0x64,
VKD3D_SM4_OP_DCL_OUTPUT = 0x65,
+ VKD3D_SM4_OP_DCL_OUTPUT_SGV = 0x66,
VKD3D_SM4_OP_DCL_OUTPUT_SIV = 0x67,
VKD3D_SM4_OP_DCL_TEMPS = 0x68,
VKD3D_SM4_OP_DCL_INDEXABLE_TEMP = 0x69,
@@ -654,7 +655,7 @@ struct sm4_index_range_array
struct vkd3d_sm4_lookup_tables
{
const struct vkd3d_sm4_opcode_info *opcode_info_from_sm4[VKD3D_SM4_OP_COUNT];
- const struct vkd3d_sm4_opcode_info *opcode_info_from_vsir[VKD3DSIH_COUNT];
+ const struct vkd3d_sm4_opcode_info *opcode_info_from_vsir[VSIR_OP_COUNT];
const struct vkd3d_sm4_register_type_info *register_type_info_from_sm4[VKD3D_SM4_REGISTER_TYPE_COUNT];
const struct vkd3d_sm4_register_type_info *register_type_info_from_vkd3d[VKD3DSPR_COUNT];
const struct vkd3d_sm4_stat_field_info *stat_field_from_sm4[VKD3D_SM4_OP_COUNT];
@@ -747,18 +748,18 @@ static const enum vkd3d_shader_resource_type resource_type_table[] =
/* VKD3D_SM4_RESOURCE_STRUCTURED_BUFFER */ VKD3D_SHADER_RESOURCE_BUFFER,
};
-static const enum vkd3d_data_type data_type_table[] =
-{
- /* 0 */ VKD3D_DATA_FLOAT,
- /* VKD3D_SM4_DATA_UNORM */ VKD3D_DATA_UNORM,
- /* VKD3D_SM4_DATA_SNORM */ VKD3D_DATA_SNORM,
- /* VKD3D_SM4_DATA_INT */ VKD3D_DATA_INT,
- /* VKD3D_SM4_DATA_UINT */ VKD3D_DATA_UINT,
- /* VKD3D_SM4_DATA_FLOAT */ VKD3D_DATA_FLOAT,
- /* VKD3D_SM4_DATA_MIXED */ VKD3D_DATA_MIXED,
- /* VKD3D_SM4_DATA_DOUBLE */ VKD3D_DATA_DOUBLE,
- /* VKD3D_SM4_DATA_CONTINUED */ VKD3D_DATA_CONTINUED,
- /* VKD3D_SM4_DATA_UNUSED */ VKD3D_DATA_UNUSED,
+static const enum vsir_data_type data_type_table[] =
+{
+ /* 0 */ VSIR_DATA_F32,
+ /* VKD3D_SM4_DATA_UNORM */ VSIR_DATA_UNORM,
+ /* VKD3D_SM4_DATA_SNORM */ VSIR_DATA_SNORM,
+ /* VKD3D_SM4_DATA_INT */ VSIR_DATA_I32,
+ /* VKD3D_SM4_DATA_UINT */ VSIR_DATA_U32,
+ /* VKD3D_SM4_DATA_FLOAT */ VSIR_DATA_F32,
+ /* VKD3D_SM4_DATA_MIXED */ VSIR_DATA_MIXED,
+ /* VKD3D_SM4_DATA_DOUBLE */ VSIR_DATA_F64,
+ /* VKD3D_SM4_DATA_CONTINUED */ VSIR_DATA_CONTINUED,
+ /* VKD3D_SM4_DATA_UNUSED */ VSIR_DATA_UNUSED,
};
static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4)
@@ -769,9 +770,9 @@ static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4)
}
static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr,
- const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_src_param *src_param);
+ const uint32_t *end, enum vsir_data_type data_type, struct vkd3d_shader_src_param *src_param);
static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr,
- const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_dst_param *dst_param);
+ const uint32_t *end, enum vsir_data_type data_type, struct vkd3d_shader_dst_param *dst_param);
static bool shader_sm4_read_register_space(struct vkd3d_shader_sm4_parser *priv,
const uint32_t **ptr, const uint32_t *end, unsigned int *register_space)
@@ -794,7 +795,7 @@ static bool shader_sm4_read_register_space(struct vkd3d_shader_sm4_parser *priv,
static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins, uint32_t opcode,
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{
- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, &ins->src[0]);
+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VSIR_DATA_U32, &ins->src[0]);
ins->flags = (opcode_token & VKD3D_SM4_CONDITIONAL_NZ) ?
VKD3D_SHADER_CONDITIONAL_OP_NZ : VKD3D_SHADER_CONDITIONAL_OP_Z;
}
@@ -802,7 +803,7 @@ static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins,
static void shader_sm4_read_case_condition(struct vkd3d_shader_instruction *ins, uint32_t opcode,
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{
- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, &ins->src[0]);
+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VSIR_DATA_U32, &ins->src[0]);
if (ins->src[0].reg.type != VKD3DSPR_IMMCONST)
{
FIXME("Switch case value is not a 32-bit constant.\n");
@@ -822,7 +823,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui
if (type != VKD3D_SM4_SHADER_DATA_IMMEDIATE_CONSTANT_BUFFER)
{
FIXME("Ignoring shader data type %#x.\n", type);
- ins->opcode = VKD3DSIH_NOP;
+ ins->opcode = VSIR_OP_NOP;
return;
}
@@ -831,7 +832,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui
if (icb_size % 4)
{
FIXME("Unexpected immediate constant buffer size %u.\n", icb_size);
- ins->opcode = VKD3DSIH_INVALID;
+ ins->opcode = VSIR_OP_INVALID;
return;
}
@@ -839,11 +840,11 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui
{
ERR("Failed to allocate immediate constant buffer, size %u.\n", icb_size);
vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory.");
- ins->opcode = VKD3DSIH_INVALID;
+ ins->opcode = VSIR_OP_INVALID;
return;
}
icb->register_idx = 0;
- icb->data_type = VKD3D_DATA_FLOAT;
+ icb->data_type = VSIR_DATA_F32;
icb->component_count = VKD3D_VEC4_SIZE;
icb->element_count = icb_size / VKD3D_VEC4_SIZE;
icb->is_null = false;
@@ -872,7 +873,7 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins, u
enum vkd3d_sm4_resource_type resource_type;
const uint32_t *end = &tokens[token_count];
enum vkd3d_sm4_data_type data_type;
- enum vkd3d_data_type reg_data_type;
+ enum vsir_data_type reg_data_type;
uint32_t components;
unsigned int i;
@@ -894,7 +895,7 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins, u
>> VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT;
}
- reg_data_type = VKD3D_DATA_UNUSED;
+ reg_data_type = VSIR_DATA_UNUSED;
shader_sm4_read_dst_param(priv, &tokens, end, reg_data_type, &semantic->resource.reg);
shader_sm4_set_descriptor_register_range(priv, &semantic->resource.reg.reg, &semantic->resource.range);
@@ -906,7 +907,7 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins, u
if (!data_type || (data_type >= ARRAY_SIZE(data_type_table)))
{
FIXME("Unhandled data type %#x.\n", data_type);
- semantic->resource_data_type[i] = VKD3D_DATA_FLOAT;
+ semantic->resource_data_type[i] = VSIR_DATA_F32;
}
else
{
@@ -925,7 +926,7 @@ static void shader_sm4_read_dcl_constant_buffer(struct vkd3d_shader_instruction
{
const uint32_t *end = &tokens[token_count];
- shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_FLOAT, &ins->declaration.cb.src);
+ shader_sm4_read_src_param(priv, &tokens, end, VSIR_DATA_F32, &ins->declaration.cb.src);
shader_sm4_set_descriptor_register_range(priv, &ins->declaration.cb.src.reg, &ins->declaration.cb.range);
if (opcode_token & VKD3D_SM4_INDEX_TYPE_MASK)
ins->flags |= VKD3DSI_INDEXED_DYNAMIC;
@@ -956,14 +957,14 @@ static void shader_sm4_read_dcl_sampler(struct vkd3d_shader_instruction *ins, ui
ins->flags = (opcode_token & VKD3D_SM4_SAMPLER_MODE_MASK) >> VKD3D_SM4_SAMPLER_MODE_SHIFT;
if (ins->flags & ~VKD3D_SM4_SAMPLER_COMPARISON)
FIXME("Unhandled sampler mode %#x.\n", ins->flags);
- shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &ins->declaration.sampler.src);
+ shader_sm4_read_src_param(priv, &tokens, end, VSIR_DATA_UNUSED, &ins->declaration.sampler.src);
shader_sm4_set_descriptor_register_range(priv, &ins->declaration.sampler.src.reg, &ins->declaration.sampler.range);
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.sampler.range.space);
}
static bool sm4_parser_is_in_fork_or_join_phase(const struct vkd3d_shader_sm4_parser *sm4)
{
- return sm4->phase == VKD3DSIH_HS_FORK_PHASE || sm4->phase == VKD3DSIH_HS_JOIN_PHASE;
+ return sm4->phase == VSIR_OP_HS_FORK_PHASE || sm4->phase == VSIR_OP_HS_JOIN_PHASE;
}
static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins, uint32_t opcode,
@@ -978,8 +979,7 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins
unsigned int *io_masks;
uint32_t write_mask;
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE,
- &index_range->dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_OPAQUE, &index_range->dst);
index_range->register_count = *tokens;
register_idx = index_range->dst.reg.idx[index_range->dst.reg.idx_count - 1].offset;
@@ -1141,14 +1141,14 @@ static void shader_sm4_read_declaration_count(struct vkd3d_shader_instruction *i
static void shader_sm4_read_declaration_dst(struct vkd3d_shader_instruction *ins, uint32_t opcode,
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, &ins->declaration.dst);
}
static void shader_sm4_read_declaration_register_semantic(struct vkd3d_shader_instruction *ins, uint32_t opcode,
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT,
- &ins->declaration.register_semantic.reg);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count],
+ VSIR_DATA_F32, &ins->declaration.register_semantic.reg);
ins->declaration.register_semantic.sysval_semantic = *tokens;
}
@@ -1158,7 +1158,7 @@ static void shader_sm4_read_dcl_input_ps(struct vkd3d_shader_instruction *ins, u
struct vkd3d_shader_dst_param *dst = &ins->declaration.dst;
ins->flags = (opcode_token & VKD3D_SM4_INTERPOLATION_MODE_MASK) >> VKD3D_SM4_INTERPOLATION_MODE_SHIFT;
- if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, dst))
+ if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, dst))
{
struct signature_element *e = vsir_signature_find_element_for_reg(
&priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask);
@@ -1168,7 +1168,7 @@ static void shader_sm4_read_dcl_input_ps(struct vkd3d_shader_instruction *ins, u
WARN("No matching signature element for input register %u with mask %#x.\n",
dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask);
vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DCL,
- "No matching signature element for input register %u with mask %#x.\n",
+ "No matching signature element for input register %u with mask %#x.",
dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask);
}
else
@@ -1184,7 +1184,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct vkd3d_shader_instruction *in
struct vkd3d_shader_dst_param *dst = &ins->declaration.register_semantic.reg;
ins->flags = (opcode_token & VKD3D_SM4_INTERPOLATION_MODE_MASK) >> VKD3D_SM4_INTERPOLATION_MODE_SHIFT;
- if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, dst))
+ if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, dst))
{
struct signature_element *e = vsir_signature_find_element_for_reg(
&priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask);
@@ -1194,7 +1194,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct vkd3d_shader_instruction *in
WARN("No matching signature element for input register %u with mask %#x.\n",
dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask);
vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DCL,
- "No matching signature element for input register %u with mask %#x.\n",
+ "No matching signature element for input register %u with mask %#x.",
dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask);
}
else
@@ -1211,7 +1211,7 @@ static void shader_sm4_read_dcl_indexable_temp(struct vkd3d_shader_instruction *
ins->declaration.indexable_temp.register_idx = *tokens++;
ins->declaration.indexable_temp.register_size = *tokens++;
ins->declaration.indexable_temp.alignment = 0;
- ins->declaration.indexable_temp.data_type = VKD3D_DATA_FLOAT;
+ ins->declaration.indexable_temp.data_type = VSIR_DATA_F32;
ins->declaration.indexable_temp.component_count = *tokens;
ins->declaration.indexable_temp.has_function_scope = false;
}
@@ -1227,7 +1227,7 @@ static void shader_sm5_read_fcall(struct vkd3d_shader_instruction *ins, uint32_t
const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{
ins->src[0].reg.u.fp_body_idx = *tokens++;
- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE, &ins->src[0]);
+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VSIR_DATA_OPAQUE, &ins->src[0]);
}
static void shader_sm5_read_dcl_function_body(struct vkd3d_shader_instruction *ins, uint32_t opcode,
@@ -1314,7 +1314,7 @@ static void shader_sm5_read_dcl_uav_raw(struct vkd3d_shader_instruction *ins, ui
struct vkd3d_shader_raw_resource *resource = &ins->declaration.raw_resource;
const uint32_t *end = &tokens[token_count];
- shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &resource->resource.reg);
+ shader_sm4_read_dst_param(priv, &tokens, end, VSIR_DATA_UNUSED, &resource->resource.reg);
shader_sm4_set_descriptor_register_range(priv, &resource->resource.reg.reg, &resource->resource.range);
ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT;
shader_sm4_read_register_space(priv, &tokens, end, &resource->resource.range.space);
@@ -1326,7 +1326,7 @@ static void shader_sm5_read_dcl_uav_structured(struct vkd3d_shader_instruction *
struct vkd3d_shader_structured_resource *resource = &ins->declaration.structured_resource;
const uint32_t *end = &tokens[token_count];
- shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &resource->resource.reg);
+ shader_sm4_read_dst_param(priv, &tokens, end, VSIR_DATA_UNUSED, &resource->resource.reg);
shader_sm4_set_descriptor_register_range(priv, &resource->resource.reg.reg, &resource->resource.range);
ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT;
resource->byte_stride = *tokens++;
@@ -1338,7 +1338,7 @@ static void shader_sm5_read_dcl_uav_structured(struct vkd3d_shader_instruction *
static void shader_sm5_read_dcl_tgsm_raw(struct vkd3d_shader_instruction *ins, uint32_t opcode,
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, &ins->declaration.tgsm_raw.reg);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, &ins->declaration.tgsm_raw.reg);
ins->declaration.tgsm_raw.byte_count = *tokens;
if (ins->declaration.tgsm_raw.byte_count % 4)
FIXME("Byte count %u is not multiple of 4.\n", ins->declaration.tgsm_raw.byte_count);
@@ -1348,8 +1348,8 @@ static void shader_sm5_read_dcl_tgsm_raw(struct vkd3d_shader_instruction *ins, u
static void shader_sm5_read_dcl_tgsm_structured(struct vkd3d_shader_instruction *ins, uint32_t opcode,
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT,
- &ins->declaration.tgsm_structured.reg);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count],
+ VSIR_DATA_F32, &ins->declaration.tgsm_structured.reg);
ins->declaration.tgsm_structured.byte_stride = *tokens++;
ins->declaration.tgsm_structured.structure_count = *tokens;
if (ins->declaration.tgsm_structured.byte_stride % 4)
@@ -1363,7 +1363,7 @@ static void shader_sm5_read_dcl_resource_structured(struct vkd3d_shader_instruct
struct vkd3d_shader_structured_resource *resource = &ins->declaration.structured_resource;
const uint32_t *end = &tokens[token_count];
- shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &resource->resource.reg);
+ shader_sm4_read_dst_param(priv, &tokens, end, VSIR_DATA_UNUSED, &resource->resource.reg);
shader_sm4_set_descriptor_register_range(priv, &resource->resource.reg.reg, &resource->resource.range);
resource->byte_stride = *tokens++;
if (resource->byte_stride % 4)
@@ -1377,7 +1377,7 @@ static void shader_sm5_read_dcl_resource_raw(struct vkd3d_shader_instruction *in
struct vkd3d_shader_raw_resource *resource = &ins->declaration.raw_resource;
const uint32_t *end = &tokens[token_count];
- shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &resource->resource.reg);
+ shader_sm4_read_dst_param(priv, &tokens, end, VSIR_DATA_UNUSED, &resource->resource.reg);
shader_sm4_set_descriptor_register_range(priv, &resource->resource.reg.reg, &resource->resource.range);
shader_sm4_read_register_space(priv, &tokens, end, &resource->resource.range.space);
}
@@ -1429,284 +1429,284 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup)
unsigned int i;
/*
- * d -> VKD3D_DATA_DOUBLE
- * f -> VKD3D_DATA_FLOAT
- * i -> VKD3D_DATA_INT
- * u -> VKD3D_DATA_UINT
- * O -> VKD3D_DATA_OPAQUE
- * R -> VKD3D_DATA_RESOURCE
- * S -> VKD3D_DATA_SAMPLER
- * U -> VKD3D_DATA_UAV
+ * d -> VSIR_DATA_F64
+ * f -> VSIR_DATA_F32
+ * i -> VSIR_DATA_I32
+ * u -> VSIR_DATA_U32
+ * O -> VSIR_DATA_OPAQUE
+ * * -> VSIR_DATA_UNUSED
*/
static const struct vkd3d_sm4_opcode_info opcode_table[] =
{
- {VKD3D_SM4_OP_ADD, VKD3DSIH_ADD, "f", "ff"},
- {VKD3D_SM4_OP_AND, VKD3DSIH_AND, "u", "uu"},
- {VKD3D_SM4_OP_BREAK, VKD3DSIH_BREAK, "", ""},
- {VKD3D_SM4_OP_BREAKC, VKD3DSIH_BREAKP, "", "u",
+ {VKD3D_SM4_OP_ADD, VSIR_OP_ADD, "f", "ff"},
+ {VKD3D_SM4_OP_AND, VSIR_OP_AND, "u", "uu"},
+ {VKD3D_SM4_OP_BREAK, VSIR_OP_BREAK, "", ""},
+ {VKD3D_SM4_OP_BREAKC, VSIR_OP_BREAKP, "", "u",
shader_sm4_read_conditional_op, true},
- {VKD3D_SM4_OP_CASE, VKD3DSIH_CASE, "", "u",
+ {VKD3D_SM4_OP_CASE, VSIR_OP_CASE, "", "u",
shader_sm4_read_case_condition},
- {VKD3D_SM4_OP_CONTINUE, VKD3DSIH_CONTINUE, "", ""},
- {VKD3D_SM4_OP_CONTINUEC, VKD3DSIH_CONTINUEP, "", "u",
+ {VKD3D_SM4_OP_CONTINUE, VSIR_OP_CONTINUE, "", ""},
+ {VKD3D_SM4_OP_CONTINUEC, VSIR_OP_CONTINUEP, "", "u",
shader_sm4_read_conditional_op, true},
- {VKD3D_SM4_OP_CUT, VKD3DSIH_CUT, "", ""},
- {VKD3D_SM4_OP_DEFAULT, VKD3DSIH_DEFAULT, "", ""},
- {VKD3D_SM4_OP_DERIV_RTX, VKD3DSIH_DSX, "f", "f"},
- {VKD3D_SM4_OP_DERIV_RTY, VKD3DSIH_DSY, "f", "f"},
- {VKD3D_SM4_OP_DISCARD, VKD3DSIH_DISCARD, "", "u",
+ {VKD3D_SM4_OP_CUT, VSIR_OP_CUT, "", ""},
+ {VKD3D_SM4_OP_DEFAULT, VSIR_OP_DEFAULT, "", ""},
+ {VKD3D_SM4_OP_DERIV_RTX, VSIR_OP_DSX, "f", "f"},
+ {VKD3D_SM4_OP_DERIV_RTY, VSIR_OP_DSY, "f", "f"},
+ {VKD3D_SM4_OP_DISCARD, VSIR_OP_DISCARD, "", "u",
shader_sm4_read_conditional_op, true},
- {VKD3D_SM4_OP_DIV, VKD3DSIH_DIV, "f", "ff"},
- {VKD3D_SM4_OP_DP2, VKD3DSIH_DP2, "f", "ff"},
- {VKD3D_SM4_OP_DP3, VKD3DSIH_DP3, "f", "ff"},
- {VKD3D_SM4_OP_DP4, VKD3DSIH_DP4, "f", "ff"},
- {VKD3D_SM4_OP_ELSE, VKD3DSIH_ELSE, "", ""},
- {VKD3D_SM4_OP_EMIT, VKD3DSIH_EMIT, "", ""},
- {VKD3D_SM4_OP_ENDIF, VKD3DSIH_ENDIF, "", ""},
- {VKD3D_SM4_OP_ENDLOOP, VKD3DSIH_ENDLOOP, "", ""},
- {VKD3D_SM4_OP_ENDSWITCH, VKD3DSIH_ENDSWITCH, "", ""},
- {VKD3D_SM4_OP_EQ, VKD3DSIH_EQO, "u", "ff"},
- {VKD3D_SM4_OP_EXP, VKD3DSIH_EXP, "f", "f"},
- {VKD3D_SM4_OP_FRC, VKD3DSIH_FRC, "f", "f"},
- {VKD3D_SM4_OP_FTOI, VKD3DSIH_FTOI, "i", "f"},
- {VKD3D_SM4_OP_FTOU, VKD3DSIH_FTOU, "u", "f"},
- {VKD3D_SM4_OP_GE, VKD3DSIH_GEO, "u", "ff"},
- {VKD3D_SM4_OP_IADD, VKD3DSIH_IADD, "i", "ii"},
- {VKD3D_SM4_OP_IF, VKD3DSIH_IF, "", "u",
+ {VKD3D_SM4_OP_DIV, VSIR_OP_DIV, "f", "ff"},
+ {VKD3D_SM4_OP_DP2, VSIR_OP_DP2, "f", "ff"},
+ {VKD3D_SM4_OP_DP3, VSIR_OP_DP3, "f", "ff"},
+ {VKD3D_SM4_OP_DP4, VSIR_OP_DP4, "f", "ff"},
+ {VKD3D_SM4_OP_ELSE, VSIR_OP_ELSE, "", ""},
+ {VKD3D_SM4_OP_EMIT, VSIR_OP_EMIT, "", ""},
+ {VKD3D_SM4_OP_ENDIF, VSIR_OP_ENDIF, "", ""},
+ {VKD3D_SM4_OP_ENDLOOP, VSIR_OP_ENDLOOP, "", ""},
+ {VKD3D_SM4_OP_ENDSWITCH, VSIR_OP_ENDSWITCH, "", ""},
+ {VKD3D_SM4_OP_EQ, VSIR_OP_EQO, "u", "ff"},
+ {VKD3D_SM4_OP_EXP, VSIR_OP_EXP, "f", "f"},
+ {VKD3D_SM4_OP_FRC, VSIR_OP_FRC, "f", "f"},
+ {VKD3D_SM4_OP_FTOI, VSIR_OP_FTOI, "i", "f"},
+ {VKD3D_SM4_OP_FTOU, VSIR_OP_FTOU, "u", "f"},
+ {VKD3D_SM4_OP_GE, VSIR_OP_GEO, "u", "ff"},
+ {VKD3D_SM4_OP_IADD, VSIR_OP_IADD, "i", "ii"},
+ {VKD3D_SM4_OP_IF, VSIR_OP_IF, "", "u",
shader_sm4_read_conditional_op, true},
- {VKD3D_SM4_OP_IEQ, VKD3DSIH_IEQ, "u", "ii"},
- {VKD3D_SM4_OP_IGE, VKD3DSIH_IGE, "u", "ii"},
- {VKD3D_SM4_OP_ILT, VKD3DSIH_ILT, "u", "ii"},
- {VKD3D_SM4_OP_IMAD, VKD3DSIH_IMAD, "i", "iii"},
- {VKD3D_SM4_OP_IMAX, VKD3DSIH_IMAX, "i", "ii"},
- {VKD3D_SM4_OP_IMIN, VKD3DSIH_IMIN, "i", "ii"},
- {VKD3D_SM4_OP_IMUL, VKD3DSIH_IMUL, "ii", "ii"},
- {VKD3D_SM4_OP_INE, VKD3DSIH_INE, "u", "ii"},
- {VKD3D_SM4_OP_INEG, VKD3DSIH_INEG, "i", "i"},
- {VKD3D_SM4_OP_ISHL, VKD3DSIH_ISHL, "i", "ii"},
- {VKD3D_SM4_OP_ISHR, VKD3DSIH_ISHR, "i", "ii"},
- {VKD3D_SM4_OP_ITOF, VKD3DSIH_ITOF, "f", "i"},
- {VKD3D_SM4_OP_LABEL, VKD3DSIH_LABEL, "", "O"},
- {VKD3D_SM4_OP_LD, VKD3DSIH_LD, "u", "i*"},
- {VKD3D_SM4_OP_LD2DMS, VKD3DSIH_LD2DMS, "u", "i*i"},
- {VKD3D_SM4_OP_LOG, VKD3DSIH_LOG, "f", "f"},
- {VKD3D_SM4_OP_LOOP, VKD3DSIH_LOOP, "", ""},
- {VKD3D_SM4_OP_LT, VKD3DSIH_LTO, "u", "ff"},
- {VKD3D_SM4_OP_MAD, VKD3DSIH_MAD, "f", "fff"},
- {VKD3D_SM4_OP_MIN, VKD3DSIH_MIN, "f", "ff"},
- {VKD3D_SM4_OP_MAX, VKD3DSIH_MAX, "f", "ff"},
- {VKD3D_SM4_OP_SHADER_DATA, VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER, "", "",
+ {VKD3D_SM4_OP_IEQ, VSIR_OP_IEQ, "u", "ii"},
+ {VKD3D_SM4_OP_IGE, VSIR_OP_IGE, "u", "ii"},
+ {VKD3D_SM4_OP_ILT, VSIR_OP_ILT, "u", "ii"},
+ {VKD3D_SM4_OP_IMAD, VSIR_OP_IMAD, "i", "iii"},
+ {VKD3D_SM4_OP_IMAX, VSIR_OP_IMAX, "i", "ii"},
+ {VKD3D_SM4_OP_IMIN, VSIR_OP_IMIN, "i", "ii"},
+ {VKD3D_SM4_OP_IMUL, VSIR_OP_IMUL, "ii", "ii"},
+ {VKD3D_SM4_OP_INE, VSIR_OP_INE, "u", "ii"},
+ {VKD3D_SM4_OP_INEG, VSIR_OP_INEG, "i", "i"},
+ {VKD3D_SM4_OP_ISHL, VSIR_OP_ISHL, "i", "ii"},
+ {VKD3D_SM4_OP_ISHR, VSIR_OP_ISHR, "i", "ii"},
+ {VKD3D_SM4_OP_ITOF, VSIR_OP_ITOF, "f", "i"},
+ {VKD3D_SM4_OP_LABEL, VSIR_OP_LABEL, "", "O"},
+ {VKD3D_SM4_OP_LD, VSIR_OP_LD, "u", "i*"},
+ {VKD3D_SM4_OP_LD2DMS, VSIR_OP_LD2DMS, "u", "i*i"},
+ {VKD3D_SM4_OP_LOG, VSIR_OP_LOG, "f", "f"},
+ {VKD3D_SM4_OP_LOOP, VSIR_OP_LOOP, "", ""},
+ {VKD3D_SM4_OP_LT, VSIR_OP_LTO, "u", "ff"},
+ {VKD3D_SM4_OP_MAD, VSIR_OP_MAD, "f", "fff"},
+ {VKD3D_SM4_OP_MIN, VSIR_OP_MIN, "f", "ff"},
+ {VKD3D_SM4_OP_MAX, VSIR_OP_MAX, "f", "ff"},
+ {VKD3D_SM4_OP_SHADER_DATA, VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER, "", "",
shader_sm4_read_shader_data},
- {VKD3D_SM4_OP_MOV, VKD3DSIH_MOV, "f", "f"},
- {VKD3D_SM4_OP_MOVC, VKD3DSIH_MOVC, "f", "uff"},
- {VKD3D_SM4_OP_MUL, VKD3DSIH_MUL, "f", "ff"},
- {VKD3D_SM4_OP_NE, VKD3DSIH_NEU, "u", "ff"},
- {VKD3D_SM4_OP_NOP, VKD3DSIH_NOP, "", ""},
- {VKD3D_SM4_OP_NOT, VKD3DSIH_NOT, "u", "u"},
- {VKD3D_SM4_OP_OR, VKD3DSIH_OR, "u", "uu"},
- {VKD3D_SM4_OP_RESINFO, VKD3DSIH_RESINFO, "f", "i*"},
- {VKD3D_SM4_OP_RET, VKD3DSIH_RET, "", ""},
- {VKD3D_SM4_OP_RETC, VKD3DSIH_RETP, "", "u",
+ {VKD3D_SM4_OP_MOV, VSIR_OP_MOV, "f", "f"},
+ {VKD3D_SM4_OP_MOVC, VSIR_OP_MOVC, "f", "uff"},
+ {VKD3D_SM4_OP_MUL, VSIR_OP_MUL, "f", "ff"},
+ {VKD3D_SM4_OP_NE, VSIR_OP_NEU, "u", "ff"},
+ {VKD3D_SM4_OP_NOP, VSIR_OP_NOP, "", ""},
+ {VKD3D_SM4_OP_NOT, VSIR_OP_NOT, "u", "u"},
+ {VKD3D_SM4_OP_OR, VSIR_OP_OR, "u", "uu"},
+ {VKD3D_SM4_OP_RESINFO, VSIR_OP_RESINFO, "f", "i*"},
+ {VKD3D_SM4_OP_RET, VSIR_OP_RET, "", ""},
+ {VKD3D_SM4_OP_RETC, VSIR_OP_RETP, "", "u",
shader_sm4_read_conditional_op, true},
- {VKD3D_SM4_OP_ROUND_NE, VKD3DSIH_ROUND_NE, "f", "f"},
- {VKD3D_SM4_OP_ROUND_NI, VKD3DSIH_ROUND_NI, "f", "f"},
- {VKD3D_SM4_OP_ROUND_PI, VKD3DSIH_ROUND_PI, "f", "f"},
- {VKD3D_SM4_OP_ROUND_Z, VKD3DSIH_ROUND_Z, "f", "f"},
- {VKD3D_SM4_OP_RSQ, VKD3DSIH_RSQ, "f", "f"},
- {VKD3D_SM4_OP_SAMPLE, VKD3DSIH_SAMPLE, "u", "f**"},
- {VKD3D_SM4_OP_SAMPLE_C, VKD3DSIH_SAMPLE_C, "f", "f**f"},
- {VKD3D_SM4_OP_SAMPLE_C_LZ, VKD3DSIH_SAMPLE_C_LZ, "f", "f**f"},
- {VKD3D_SM4_OP_SAMPLE_LOD, VKD3DSIH_SAMPLE_LOD, "u", "f**f"},
- {VKD3D_SM4_OP_SAMPLE_GRAD, VKD3DSIH_SAMPLE_GRAD, "u", "f**ff"},
- {VKD3D_SM4_OP_SAMPLE_B, VKD3DSIH_SAMPLE_B, "u", "f**f"},
- {VKD3D_SM4_OP_SQRT, VKD3DSIH_SQRT, "f", "f"},
- {VKD3D_SM4_OP_SWITCH, VKD3DSIH_SWITCH, "", "i"},
- {VKD3D_SM4_OP_SINCOS, VKD3DSIH_SINCOS, "ff", "f"},
- {VKD3D_SM4_OP_UDIV, VKD3DSIH_UDIV, "uu", "uu"},
- {VKD3D_SM4_OP_ULT, VKD3DSIH_ULT, "u", "uu"},
- {VKD3D_SM4_OP_UGE, VKD3DSIH_UGE, "u", "uu"},
- {VKD3D_SM4_OP_UMUL, VKD3DSIH_UMUL, "uu", "uu"},
- {VKD3D_SM4_OP_UMAX, VKD3DSIH_UMAX, "u", "uu"},
- {VKD3D_SM4_OP_UMIN, VKD3DSIH_UMIN, "u", "uu"},
- {VKD3D_SM4_OP_USHR, VKD3DSIH_USHR, "u", "uu"},
- {VKD3D_SM4_OP_UTOF, VKD3DSIH_UTOF, "f", "u"},
- {VKD3D_SM4_OP_XOR, VKD3DSIH_XOR, "u", "uu"},
- {VKD3D_SM4_OP_DCL_RESOURCE, VKD3DSIH_DCL, "", "",
+ {VKD3D_SM4_OP_ROUND_NE, VSIR_OP_ROUND_NE, "f", "f"},
+ {VKD3D_SM4_OP_ROUND_NI, VSIR_OP_ROUND_NI, "f", "f"},
+ {VKD3D_SM4_OP_ROUND_PI, VSIR_OP_ROUND_PI, "f", "f"},
+ {VKD3D_SM4_OP_ROUND_Z, VSIR_OP_ROUND_Z, "f", "f"},
+ {VKD3D_SM4_OP_RSQ, VSIR_OP_RSQ, "f", "f"},
+ {VKD3D_SM4_OP_SAMPLE, VSIR_OP_SAMPLE, "u", "f**"},
+ {VKD3D_SM4_OP_SAMPLE_C, VSIR_OP_SAMPLE_C, "f", "f**f"},
+ {VKD3D_SM4_OP_SAMPLE_C_LZ, VSIR_OP_SAMPLE_C_LZ, "f", "f**f"},
+ {VKD3D_SM4_OP_SAMPLE_LOD, VSIR_OP_SAMPLE_LOD, "u", "f**f"},
+ {VKD3D_SM4_OP_SAMPLE_GRAD, VSIR_OP_SAMPLE_GRAD, "u", "f**ff"},
+ {VKD3D_SM4_OP_SAMPLE_B, VSIR_OP_SAMPLE_B, "u", "f**f"},
+ {VKD3D_SM4_OP_SQRT, VSIR_OP_SQRT, "f", "f"},
+ {VKD3D_SM4_OP_SWITCH, VSIR_OP_SWITCH, "", "i"},
+ {VKD3D_SM4_OP_SINCOS, VSIR_OP_SINCOS, "ff", "f"},
+ {VKD3D_SM4_OP_UDIV, VSIR_OP_UDIV, "uu", "uu"},
+ {VKD3D_SM4_OP_ULT, VSIR_OP_ULT, "u", "uu"},
+ {VKD3D_SM4_OP_UGE, VSIR_OP_UGE, "u", "uu"},
+ {VKD3D_SM4_OP_UMUL, VSIR_OP_UMUL, "uu", "uu"},
+ {VKD3D_SM4_OP_UMAX, VSIR_OP_UMAX, "u", "uu"},
+ {VKD3D_SM4_OP_UMIN, VSIR_OP_UMIN, "u", "uu"},
+ {VKD3D_SM4_OP_USHR, VSIR_OP_USHR, "u", "uu"},
+ {VKD3D_SM4_OP_UTOF, VSIR_OP_UTOF, "f", "u"},
+ {VKD3D_SM4_OP_XOR, VSIR_OP_XOR, "u", "uu"},
+ {VKD3D_SM4_OP_DCL_RESOURCE, VSIR_OP_DCL, "", "",
shader_sm4_read_dcl_resource},
- {VKD3D_SM4_OP_DCL_CONSTANT_BUFFER, VKD3DSIH_DCL_CONSTANT_BUFFER, "", "",
+ {VKD3D_SM4_OP_DCL_CONSTANT_BUFFER, VSIR_OP_DCL_CONSTANT_BUFFER, "", "",
shader_sm4_read_dcl_constant_buffer},
- {VKD3D_SM4_OP_DCL_SAMPLER, VKD3DSIH_DCL_SAMPLER, "", "",
+ {VKD3D_SM4_OP_DCL_SAMPLER, VSIR_OP_DCL_SAMPLER, "", "",
shader_sm4_read_dcl_sampler},
- {VKD3D_SM4_OP_DCL_INDEX_RANGE, VKD3DSIH_DCL_INDEX_RANGE, "", "",
+ {VKD3D_SM4_OP_DCL_INDEX_RANGE, VSIR_OP_DCL_INDEX_RANGE, "", "",
shader_sm4_read_dcl_index_range},
- {VKD3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, VKD3DSIH_DCL_OUTPUT_TOPOLOGY, "", "",
+ {VKD3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, VSIR_OP_DCL_OUTPUT_TOPOLOGY, "", "",
shader_sm4_read_dcl_output_topology},
- {VKD3D_SM4_OP_DCL_INPUT_PRIMITIVE, VKD3DSIH_DCL_INPUT_PRIMITIVE, "", "",
+ {VKD3D_SM4_OP_DCL_INPUT_PRIMITIVE, VSIR_OP_DCL_INPUT_PRIMITIVE, "", "",
shader_sm4_read_dcl_input_primitive},
- {VKD3D_SM4_OP_DCL_VERTICES_OUT, VKD3DSIH_DCL_VERTICES_OUT, "", "",
+ {VKD3D_SM4_OP_DCL_VERTICES_OUT, VSIR_OP_DCL_VERTICES_OUT, "", "",
shader_sm4_read_declaration_count},
- {VKD3D_SM4_OP_DCL_INPUT, VKD3DSIH_DCL_INPUT, "", "",
+ {VKD3D_SM4_OP_DCL_INPUT, VSIR_OP_DCL_INPUT, "", "",
shader_sm4_read_declaration_dst},
- {VKD3D_SM4_OP_DCL_INPUT_SGV, VKD3DSIH_DCL_INPUT_SGV, "", "",
+ {VKD3D_SM4_OP_DCL_INPUT_SGV, VSIR_OP_DCL_INPUT_SGV, "", "",
shader_sm4_read_declaration_register_semantic},
- {VKD3D_SM4_OP_DCL_INPUT_SIV, VKD3DSIH_DCL_INPUT_SIV, "", "",
+ {VKD3D_SM4_OP_DCL_INPUT_SIV, VSIR_OP_DCL_INPUT_SIV, "", "",
shader_sm4_read_declaration_register_semantic},
- {VKD3D_SM4_OP_DCL_INPUT_PS, VKD3DSIH_DCL_INPUT_PS, "", "",
+ {VKD3D_SM4_OP_DCL_INPUT_PS, VSIR_OP_DCL_INPUT_PS, "", "",
shader_sm4_read_dcl_input_ps},
- {VKD3D_SM4_OP_DCL_INPUT_PS_SGV, VKD3DSIH_DCL_INPUT_PS_SGV, "", "",
+ {VKD3D_SM4_OP_DCL_INPUT_PS_SGV, VSIR_OP_DCL_INPUT_PS_SGV, "", "",
shader_sm4_read_declaration_register_semantic},
- {VKD3D_SM4_OP_DCL_INPUT_PS_SIV, VKD3DSIH_DCL_INPUT_PS_SIV, "", "",
+ {VKD3D_SM4_OP_DCL_INPUT_PS_SIV, VSIR_OP_DCL_INPUT_PS_SIV, "", "",
shader_sm4_read_dcl_input_ps_siv},
- {VKD3D_SM4_OP_DCL_OUTPUT, VKD3DSIH_DCL_OUTPUT, "", "",
+ {VKD3D_SM4_OP_DCL_OUTPUT, VSIR_OP_DCL_OUTPUT, "", "",
shader_sm4_read_declaration_dst},
- {VKD3D_SM4_OP_DCL_OUTPUT_SIV, VKD3DSIH_DCL_OUTPUT_SIV, "", "",
+ {VKD3D_SM4_OP_DCL_OUTPUT_SGV, VSIR_OP_DCL_OUTPUT_SGV, "", "",
shader_sm4_read_declaration_register_semantic},
- {VKD3D_SM4_OP_DCL_TEMPS, VKD3DSIH_DCL_TEMPS, "", "",
+ {VKD3D_SM4_OP_DCL_OUTPUT_SIV, VSIR_OP_DCL_OUTPUT_SIV, "", "",
+ shader_sm4_read_declaration_register_semantic},
+ {VKD3D_SM4_OP_DCL_TEMPS, VSIR_OP_DCL_TEMPS, "", "",
shader_sm4_read_declaration_count},
- {VKD3D_SM4_OP_DCL_INDEXABLE_TEMP, VKD3DSIH_DCL_INDEXABLE_TEMP, "", "",
+ {VKD3D_SM4_OP_DCL_INDEXABLE_TEMP, VSIR_OP_DCL_INDEXABLE_TEMP, "", "",
shader_sm4_read_dcl_indexable_temp},
- {VKD3D_SM4_OP_DCL_GLOBAL_FLAGS, VKD3DSIH_DCL_GLOBAL_FLAGS, "", "",
+ {VKD3D_SM4_OP_DCL_GLOBAL_FLAGS, VSIR_OP_DCL_GLOBAL_FLAGS, "", "",
shader_sm4_read_dcl_global_flags},
- {VKD3D_SM4_OP_LOD, VKD3DSIH_LOD, "f", "f**"},
- {VKD3D_SM4_OP_GATHER4, VKD3DSIH_GATHER4, "u", "f**"},
- {VKD3D_SM4_OP_SAMPLE_POS, VKD3DSIH_SAMPLE_POS, "f", "*u"},
- {VKD3D_SM4_OP_SAMPLE_INFO, VKD3DSIH_SAMPLE_INFO, "f", "*"},
- {VKD3D_SM5_OP_HS_DECLS, VKD3DSIH_HS_DECLS, "", ""},
- {VKD3D_SM5_OP_HS_CONTROL_POINT_PHASE, VKD3DSIH_HS_CONTROL_POINT_PHASE, "", ""},
- {VKD3D_SM5_OP_HS_FORK_PHASE, VKD3DSIH_HS_FORK_PHASE, "", ""},
- {VKD3D_SM5_OP_HS_JOIN_PHASE, VKD3DSIH_HS_JOIN_PHASE, "", ""},
- {VKD3D_SM5_OP_EMIT_STREAM, VKD3DSIH_EMIT_STREAM, "", "f"},
- {VKD3D_SM5_OP_CUT_STREAM, VKD3DSIH_CUT_STREAM, "", "f"},
- {VKD3D_SM5_OP_FCALL, VKD3DSIH_FCALL, "", "O",
+ {VKD3D_SM4_OP_LOD, VSIR_OP_LOD, "f", "f**"},
+ {VKD3D_SM4_OP_GATHER4, VSIR_OP_GATHER4, "u", "f**"},
+ {VKD3D_SM4_OP_SAMPLE_POS, VSIR_OP_SAMPLE_POS, "f", "*u"},
+ {VKD3D_SM4_OP_SAMPLE_INFO, VSIR_OP_SAMPLE_INFO, "f", "*"},
+ {VKD3D_SM5_OP_HS_DECLS, VSIR_OP_HS_DECLS, "", ""},
+ {VKD3D_SM5_OP_HS_CONTROL_POINT_PHASE, VSIR_OP_HS_CONTROL_POINT_PHASE, "", ""},
+ {VKD3D_SM5_OP_HS_FORK_PHASE, VSIR_OP_HS_FORK_PHASE, "", ""},
+ {VKD3D_SM5_OP_HS_JOIN_PHASE, VSIR_OP_HS_JOIN_PHASE, "", ""},
+ {VKD3D_SM5_OP_EMIT_STREAM, VSIR_OP_EMIT_STREAM, "", "*"},
+ {VKD3D_SM5_OP_CUT_STREAM, VSIR_OP_CUT_STREAM, "", "*"},
+ {VKD3D_SM5_OP_FCALL, VSIR_OP_FCALL, "", "O",
shader_sm5_read_fcall},
- {VKD3D_SM5_OP_BUFINFO, VKD3DSIH_BUFINFO, "i", "*"},
- {VKD3D_SM5_OP_DERIV_RTX_COARSE, VKD3DSIH_DSX_COARSE, "f", "f"},
- {VKD3D_SM5_OP_DERIV_RTX_FINE, VKD3DSIH_DSX_FINE, "f", "f"},
- {VKD3D_SM5_OP_DERIV_RTY_COARSE, VKD3DSIH_DSY_COARSE, "f", "f"},
- {VKD3D_SM5_OP_DERIV_RTY_FINE, VKD3DSIH_DSY_FINE, "f", "f"},
- {VKD3D_SM5_OP_GATHER4_C, VKD3DSIH_GATHER4_C, "f", "f**f"},
- {VKD3D_SM5_OP_GATHER4_PO, VKD3DSIH_GATHER4_PO, "f", "fi**"},
- {VKD3D_SM5_OP_GATHER4_PO_C, VKD3DSIH_GATHER4_PO_C, "f", "fi**f"},
- {VKD3D_SM5_OP_RCP, VKD3DSIH_RCP, "f", "f"},
- {VKD3D_SM5_OP_F32TOF16, VKD3DSIH_F32TOF16, "u", "f"},
- {VKD3D_SM5_OP_F16TOF32, VKD3DSIH_F16TOF32, "f", "u"},
- {VKD3D_SM5_OP_COUNTBITS, VKD3DSIH_COUNTBITS, "u", "u"},
- {VKD3D_SM5_OP_FIRSTBIT_HI, VKD3DSIH_FIRSTBIT_HI, "u", "u"},
- {VKD3D_SM5_OP_FIRSTBIT_LO, VKD3DSIH_FIRSTBIT_LO, "u", "u"},
- {VKD3D_SM5_OP_FIRSTBIT_SHI, VKD3DSIH_FIRSTBIT_SHI, "u", "i"},
- {VKD3D_SM5_OP_UBFE, VKD3DSIH_UBFE, "u", "iiu"},
- {VKD3D_SM5_OP_IBFE, VKD3DSIH_IBFE, "i", "iii"},
- {VKD3D_SM5_OP_BFI, VKD3DSIH_BFI, "u", "iiuu"},
- {VKD3D_SM5_OP_BFREV, VKD3DSIH_BFREV, "u", "u"},
- {VKD3D_SM5_OP_SWAPC, VKD3DSIH_SWAPC, "ff", "uff"},
- {VKD3D_SM5_OP_DCL_STREAM, VKD3DSIH_DCL_STREAM, "", "O"},
- {VKD3D_SM5_OP_DCL_FUNCTION_BODY, VKD3DSIH_DCL_FUNCTION_BODY, "", "",
+ {VKD3D_SM5_OP_BUFINFO, VSIR_OP_BUFINFO, "i", "*"},
+ {VKD3D_SM5_OP_DERIV_RTX_COARSE, VSIR_OP_DSX_COARSE, "f", "f"},
+ {VKD3D_SM5_OP_DERIV_RTX_FINE, VSIR_OP_DSX_FINE, "f", "f"},
+ {VKD3D_SM5_OP_DERIV_RTY_COARSE, VSIR_OP_DSY_COARSE, "f", "f"},
+ {VKD3D_SM5_OP_DERIV_RTY_FINE, VSIR_OP_DSY_FINE, "f", "f"},
+ {VKD3D_SM5_OP_GATHER4_C, VSIR_OP_GATHER4_C, "f", "f**f"},
+ {VKD3D_SM5_OP_GATHER4_PO, VSIR_OP_GATHER4_PO, "f", "fi**"},
+ {VKD3D_SM5_OP_GATHER4_PO_C, VSIR_OP_GATHER4_PO_C, "f", "fi**f"},
+ {VKD3D_SM5_OP_RCP, VSIR_OP_RCP, "f", "f"},
+ {VKD3D_SM5_OP_F32TOF16, VSIR_OP_F32TOF16, "u", "f"},
+ {VKD3D_SM5_OP_F16TOF32, VSIR_OP_F16TOF32, "f", "u"},
+ {VKD3D_SM5_OP_COUNTBITS, VSIR_OP_COUNTBITS, "u", "u"},
+ {VKD3D_SM5_OP_FIRSTBIT_HI, VSIR_OP_FIRSTBIT_HI, "u", "u"},
+ {VKD3D_SM5_OP_FIRSTBIT_LO, VSIR_OP_FIRSTBIT_LO, "u", "u"},
+ {VKD3D_SM5_OP_FIRSTBIT_SHI, VSIR_OP_FIRSTBIT_SHI, "u", "i"},
+ {VKD3D_SM5_OP_UBFE, VSIR_OP_UBFE, "u", "iiu"},
+ {VKD3D_SM5_OP_IBFE, VSIR_OP_IBFE, "i", "iii"},
+ {VKD3D_SM5_OP_BFI, VSIR_OP_BFI, "u", "iiuu"},
+ {VKD3D_SM5_OP_BFREV, VSIR_OP_BFREV, "u", "u"},
+ {VKD3D_SM5_OP_SWAPC, VSIR_OP_SWAPC, "ff", "uff"},
+ {VKD3D_SM5_OP_DCL_STREAM, VSIR_OP_DCL_STREAM, "", "*"},
+ {VKD3D_SM5_OP_DCL_FUNCTION_BODY, VSIR_OP_DCL_FUNCTION_BODY, "", "",
shader_sm5_read_dcl_function_body},
- {VKD3D_SM5_OP_DCL_FUNCTION_TABLE, VKD3DSIH_DCL_FUNCTION_TABLE, "", "",
+ {VKD3D_SM5_OP_DCL_FUNCTION_TABLE, VSIR_OP_DCL_FUNCTION_TABLE, "", "",
shader_sm5_read_dcl_function_table},
- {VKD3D_SM5_OP_DCL_INTERFACE, VKD3DSIH_DCL_INTERFACE, "", "",
+ {VKD3D_SM5_OP_DCL_INTERFACE, VSIR_OP_DCL_INTERFACE, "", "",
shader_sm5_read_dcl_interface},
- {VKD3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT, VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT, "", "",
+ {VKD3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT, VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT, "", "",
shader_sm5_read_control_point_count},
- {VKD3D_SM5_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, "", "",
+ {VKD3D_SM5_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, "", "",
shader_sm5_read_control_point_count},
- {VKD3D_SM5_OP_DCL_TESSELLATOR_DOMAIN, VKD3DSIH_DCL_TESSELLATOR_DOMAIN, "", "",
+ {VKD3D_SM5_OP_DCL_TESSELLATOR_DOMAIN, VSIR_OP_DCL_TESSELLATOR_DOMAIN, "", "",
shader_sm5_read_dcl_tessellator_domain},
- {VKD3D_SM5_OP_DCL_TESSELLATOR_PARTITIONING, VKD3DSIH_DCL_TESSELLATOR_PARTITIONING, "", "",
+ {VKD3D_SM5_OP_DCL_TESSELLATOR_PARTITIONING, VSIR_OP_DCL_TESSELLATOR_PARTITIONING, "", "",
shader_sm5_read_dcl_tessellator_partitioning},
- {VKD3D_SM5_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, "", "",
+ {VKD3D_SM5_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, "", "",
shader_sm5_read_dcl_tessellator_output_primitive},
- {VKD3D_SM5_OP_DCL_HS_MAX_TESSFACTOR, VKD3DSIH_DCL_HS_MAX_TESSFACTOR, "", "",
+ {VKD3D_SM5_OP_DCL_HS_MAX_TESSFACTOR, VSIR_OP_DCL_HS_MAX_TESSFACTOR, "", "",
shader_sm5_read_dcl_hs_max_tessfactor},
- {VKD3D_SM5_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT, VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT, "", "",
+ {VKD3D_SM5_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT, VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT, "", "",
shader_sm4_read_declaration_count},
- {VKD3D_SM5_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, "", "",
+ {VKD3D_SM5_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, "", "",
shader_sm4_read_declaration_count},
- {VKD3D_SM5_OP_DCL_THREAD_GROUP, VKD3DSIH_DCL_THREAD_GROUP, "", "",
+ {VKD3D_SM5_OP_DCL_THREAD_GROUP, VSIR_OP_DCL_THREAD_GROUP, "", "",
shader_sm5_read_dcl_thread_group},
- {VKD3D_SM5_OP_DCL_UAV_TYPED, VKD3DSIH_DCL_UAV_TYPED, "", "",
+ {VKD3D_SM5_OP_DCL_UAV_TYPED, VSIR_OP_DCL_UAV_TYPED, "", "",
shader_sm4_read_dcl_resource},
- {VKD3D_SM5_OP_DCL_UAV_RAW, VKD3DSIH_DCL_UAV_RAW, "", "",
+ {VKD3D_SM5_OP_DCL_UAV_RAW, VSIR_OP_DCL_UAV_RAW, "", "",
shader_sm5_read_dcl_uav_raw},
- {VKD3D_SM5_OP_DCL_UAV_STRUCTURED, VKD3DSIH_DCL_UAV_STRUCTURED, "", "",
+ {VKD3D_SM5_OP_DCL_UAV_STRUCTURED, VSIR_OP_DCL_UAV_STRUCTURED, "", "",
shader_sm5_read_dcl_uav_structured},
- {VKD3D_SM5_OP_DCL_TGSM_RAW, VKD3DSIH_DCL_TGSM_RAW, "", "",
+ {VKD3D_SM5_OP_DCL_TGSM_RAW, VSIR_OP_DCL_TGSM_RAW, "", "",
shader_sm5_read_dcl_tgsm_raw},
- {VKD3D_SM5_OP_DCL_TGSM_STRUCTURED, VKD3DSIH_DCL_TGSM_STRUCTURED, "", "",
+ {VKD3D_SM5_OP_DCL_TGSM_STRUCTURED, VSIR_OP_DCL_TGSM_STRUCTURED, "", "",
shader_sm5_read_dcl_tgsm_structured},
- {VKD3D_SM5_OP_DCL_RESOURCE_RAW, VKD3DSIH_DCL_RESOURCE_RAW, "", "",
+ {VKD3D_SM5_OP_DCL_RESOURCE_RAW, VSIR_OP_DCL_RESOURCE_RAW, "", "",
shader_sm5_read_dcl_resource_raw},
- {VKD3D_SM5_OP_DCL_RESOURCE_STRUCTURED, VKD3DSIH_DCL_RESOURCE_STRUCTURED, "", "",
+ {VKD3D_SM5_OP_DCL_RESOURCE_STRUCTURED, VSIR_OP_DCL_RESOURCE_STRUCTURED, "", "",
shader_sm5_read_dcl_resource_structured},
- {VKD3D_SM5_OP_LD_UAV_TYPED, VKD3DSIH_LD_UAV_TYPED, "u", "i*"},
- {VKD3D_SM5_OP_STORE_UAV_TYPED, VKD3DSIH_STORE_UAV_TYPED, "*", "iu"},
- {VKD3D_SM5_OP_LD_RAW, VKD3DSIH_LD_RAW, "u", "i*"},
- {VKD3D_SM5_OP_STORE_RAW, VKD3DSIH_STORE_RAW, "*", "uu"},
- {VKD3D_SM5_OP_LD_STRUCTURED, VKD3DSIH_LD_STRUCTURED, "u", "ii*"},
- {VKD3D_SM5_OP_STORE_STRUCTURED, VKD3DSIH_STORE_STRUCTURED, "*", "iiu"},
- {VKD3D_SM5_OP_ATOMIC_AND, VKD3DSIH_ATOMIC_AND, "*", "iu"},
- {VKD3D_SM5_OP_ATOMIC_OR, VKD3DSIH_ATOMIC_OR, "*", "iu"},
- {VKD3D_SM5_OP_ATOMIC_XOR, VKD3DSIH_ATOMIC_XOR, "*", "iu"},
- {VKD3D_SM5_OP_ATOMIC_CMP_STORE, VKD3DSIH_ATOMIC_CMP_STORE, "*", "iuu"},
- {VKD3D_SM5_OP_ATOMIC_IADD, VKD3DSIH_ATOMIC_IADD, "*", "ii"},
- {VKD3D_SM5_OP_ATOMIC_IMAX, VKD3DSIH_ATOMIC_IMAX, "*", "ii"},
- {VKD3D_SM5_OP_ATOMIC_IMIN, VKD3DSIH_ATOMIC_IMIN, "*", "ii"},
- {VKD3D_SM5_OP_ATOMIC_UMAX, VKD3DSIH_ATOMIC_UMAX, "*", "iu"},
- {VKD3D_SM5_OP_ATOMIC_UMIN, VKD3DSIH_ATOMIC_UMIN, "*", "iu"},
- {VKD3D_SM5_OP_IMM_ATOMIC_ALLOC, VKD3DSIH_IMM_ATOMIC_ALLOC, "u", "*"},
- {VKD3D_SM5_OP_IMM_ATOMIC_CONSUME, VKD3DSIH_IMM_ATOMIC_CONSUME, "u", "*"},
- {VKD3D_SM5_OP_IMM_ATOMIC_IADD, VKD3DSIH_IMM_ATOMIC_IADD, "u*", "ii"},
- {VKD3D_SM5_OP_IMM_ATOMIC_AND, VKD3DSIH_IMM_ATOMIC_AND, "u*", "iu"},
- {VKD3D_SM5_OP_IMM_ATOMIC_OR, VKD3DSIH_IMM_ATOMIC_OR, "u*", "iu"},
- {VKD3D_SM5_OP_IMM_ATOMIC_XOR, VKD3DSIH_IMM_ATOMIC_XOR, "u*", "iu"},
- {VKD3D_SM5_OP_IMM_ATOMIC_EXCH, VKD3DSIH_IMM_ATOMIC_EXCH, "u*", "iu"},
- {VKD3D_SM5_OP_IMM_ATOMIC_CMP_EXCH, VKD3DSIH_IMM_ATOMIC_CMP_EXCH, "u*", "iuu"},
- {VKD3D_SM5_OP_IMM_ATOMIC_IMAX, VKD3DSIH_IMM_ATOMIC_IMAX, "i*", "ii"},
- {VKD3D_SM5_OP_IMM_ATOMIC_IMIN, VKD3DSIH_IMM_ATOMIC_IMIN, "i*", "ii"},
- {VKD3D_SM5_OP_IMM_ATOMIC_UMAX, VKD3DSIH_IMM_ATOMIC_UMAX, "u*", "iu"},
- {VKD3D_SM5_OP_IMM_ATOMIC_UMIN, VKD3DSIH_IMM_ATOMIC_UMIN, "u*", "iu"},
- {VKD3D_SM5_OP_SYNC, VKD3DSIH_SYNC, "", "",
+ {VKD3D_SM5_OP_LD_UAV_TYPED, VSIR_OP_LD_UAV_TYPED, "u", "i*"},
+ {VKD3D_SM5_OP_STORE_UAV_TYPED, VSIR_OP_STORE_UAV_TYPED, "*", "iu"},
+ {VKD3D_SM5_OP_LD_RAW, VSIR_OP_LD_RAW, "u", "i*"},
+ {VKD3D_SM5_OP_STORE_RAW, VSIR_OP_STORE_RAW, "*", "uu"},
+ {VKD3D_SM5_OP_LD_STRUCTURED, VSIR_OP_LD_STRUCTURED, "u", "ii*"},
+ {VKD3D_SM5_OP_STORE_STRUCTURED, VSIR_OP_STORE_STRUCTURED, "*", "iiu"},
+ {VKD3D_SM5_OP_ATOMIC_AND, VSIR_OP_ATOMIC_AND, "*", "iu"},
+ {VKD3D_SM5_OP_ATOMIC_OR, VSIR_OP_ATOMIC_OR, "*", "iu"},
+ {VKD3D_SM5_OP_ATOMIC_XOR, VSIR_OP_ATOMIC_XOR, "*", "iu"},
+ {VKD3D_SM5_OP_ATOMIC_CMP_STORE, VSIR_OP_ATOMIC_CMP_STORE, "*", "iuu"},
+ {VKD3D_SM5_OP_ATOMIC_IADD, VSIR_OP_ATOMIC_IADD, "*", "ii"},
+ {VKD3D_SM5_OP_ATOMIC_IMAX, VSIR_OP_ATOMIC_IMAX, "*", "ii"},
+ {VKD3D_SM5_OP_ATOMIC_IMIN, VSIR_OP_ATOMIC_IMIN, "*", "ii"},
+ {VKD3D_SM5_OP_ATOMIC_UMAX, VSIR_OP_ATOMIC_UMAX, "*", "iu"},
+ {VKD3D_SM5_OP_ATOMIC_UMIN, VSIR_OP_ATOMIC_UMIN, "*", "iu"},
+ {VKD3D_SM5_OP_IMM_ATOMIC_ALLOC, VSIR_OP_IMM_ATOMIC_ALLOC, "u", "*"},
+ {VKD3D_SM5_OP_IMM_ATOMIC_CONSUME, VSIR_OP_IMM_ATOMIC_CONSUME, "u", "*"},
+ {VKD3D_SM5_OP_IMM_ATOMIC_IADD, VSIR_OP_IMM_ATOMIC_IADD, "u*", "ii"},
+ {VKD3D_SM5_OP_IMM_ATOMIC_AND, VSIR_OP_IMM_ATOMIC_AND, "u*", "iu"},
+ {VKD3D_SM5_OP_IMM_ATOMIC_OR, VSIR_OP_IMM_ATOMIC_OR, "u*", "iu"},
+ {VKD3D_SM5_OP_IMM_ATOMIC_XOR, VSIR_OP_IMM_ATOMIC_XOR, "u*", "iu"},
+ {VKD3D_SM5_OP_IMM_ATOMIC_EXCH, VSIR_OP_IMM_ATOMIC_EXCH, "u*", "iu"},
+ {VKD3D_SM5_OP_IMM_ATOMIC_CMP_EXCH, VSIR_OP_IMM_ATOMIC_CMP_EXCH, "u*", "iuu"},
+ {VKD3D_SM5_OP_IMM_ATOMIC_IMAX, VSIR_OP_IMM_ATOMIC_IMAX, "i*", "ii"},
+ {VKD3D_SM5_OP_IMM_ATOMIC_IMIN, VSIR_OP_IMM_ATOMIC_IMIN, "i*", "ii"},
+ {VKD3D_SM5_OP_IMM_ATOMIC_UMAX, VSIR_OP_IMM_ATOMIC_UMAX, "u*", "iu"},
+ {VKD3D_SM5_OP_IMM_ATOMIC_UMIN, VSIR_OP_IMM_ATOMIC_UMIN, "u*", "iu"},
+ {VKD3D_SM5_OP_SYNC, VSIR_OP_SYNC, "", "",
shader_sm5_read_sync},
- {VKD3D_SM5_OP_DADD, VKD3DSIH_DADD, "d", "dd"},
- {VKD3D_SM5_OP_DMAX, VKD3DSIH_DMAX, "d", "dd"},
- {VKD3D_SM5_OP_DMIN, VKD3DSIH_DMIN, "d", "dd"},
- {VKD3D_SM5_OP_DMUL, VKD3DSIH_DMUL, "d", "dd"},
- {VKD3D_SM5_OP_DEQ, VKD3DSIH_DEQO, "u", "dd"},
- {VKD3D_SM5_OP_DGE, VKD3DSIH_DGEO, "u", "dd"},
- {VKD3D_SM5_OP_DLT, VKD3DSIH_DLT, "u", "dd"},
- {VKD3D_SM5_OP_DNE, VKD3DSIH_DNE, "u", "dd"},
- {VKD3D_SM5_OP_DMOV, VKD3DSIH_DMOV, "d", "d"},
- {VKD3D_SM5_OP_DMOVC, VKD3DSIH_DMOVC, "d", "udd"},
- {VKD3D_SM5_OP_DTOF, VKD3DSIH_DTOF, "f", "d"},
- {VKD3D_SM5_OP_FTOD, VKD3DSIH_FTOD, "d", "f"},
- {VKD3D_SM5_OP_EVAL_SAMPLE_INDEX, VKD3DSIH_EVAL_SAMPLE_INDEX, "f", "fi"},
- {VKD3D_SM5_OP_EVAL_CENTROID, VKD3DSIH_EVAL_CENTROID, "f", "f"},
- {VKD3D_SM5_OP_DCL_GS_INSTANCES, VKD3DSIH_DCL_GS_INSTANCES, "", "",
+ {VKD3D_SM5_OP_DADD, VSIR_OP_DADD, "d", "dd"},
+ {VKD3D_SM5_OP_DMAX, VSIR_OP_DMAX, "d", "dd"},
+ {VKD3D_SM5_OP_DMIN, VSIR_OP_DMIN, "d", "dd"},
+ {VKD3D_SM5_OP_DMUL, VSIR_OP_DMUL, "d", "dd"},
+ {VKD3D_SM5_OP_DEQ, VSIR_OP_DEQO, "u", "dd"},
+ {VKD3D_SM5_OP_DGE, VSIR_OP_DGEO, "u", "dd"},
+ {VKD3D_SM5_OP_DLT, VSIR_OP_DLT, "u", "dd"},
+ {VKD3D_SM5_OP_DNE, VSIR_OP_DNE, "u", "dd"},
+ {VKD3D_SM5_OP_DMOV, VSIR_OP_DMOV, "d", "d"},
+ {VKD3D_SM5_OP_DMOVC, VSIR_OP_DMOVC, "d", "udd"},
+ {VKD3D_SM5_OP_DTOF, VSIR_OP_DTOF, "f", "d"},
+ {VKD3D_SM5_OP_FTOD, VSIR_OP_FTOD, "d", "f"},
+ {VKD3D_SM5_OP_EVAL_SAMPLE_INDEX, VSIR_OP_EVAL_SAMPLE_INDEX, "f", "fi"},
+ {VKD3D_SM5_OP_EVAL_CENTROID, VSIR_OP_EVAL_CENTROID, "f", "f"},
+ {VKD3D_SM5_OP_DCL_GS_INSTANCES, VSIR_OP_DCL_GS_INSTANCES, "", "",
shader_sm4_read_declaration_count},
- {VKD3D_SM5_OP_DDIV, VKD3DSIH_DDIV, "d", "dd"},
- {VKD3D_SM5_OP_DFMA, VKD3DSIH_DFMA, "d", "ddd"},
- {VKD3D_SM5_OP_DRCP, VKD3DSIH_DRCP, "d", "d"},
- {VKD3D_SM5_OP_MSAD, VKD3DSIH_MSAD, "u", "uuu"},
- {VKD3D_SM5_OP_DTOI, VKD3DSIH_DTOI, "i", "d"},
- {VKD3D_SM5_OP_DTOU, VKD3DSIH_DTOU, "u", "d"},
- {VKD3D_SM5_OP_ITOD, VKD3DSIH_ITOD, "d", "i"},
- {VKD3D_SM5_OP_UTOD, VKD3DSIH_UTOD, "d", "u"},
- {VKD3D_SM5_OP_GATHER4_S, VKD3DSIH_GATHER4_S, "uu", "f**"},
- {VKD3D_SM5_OP_GATHER4_C_S, VKD3DSIH_GATHER4_C_S, "fu", "f**f"},
- {VKD3D_SM5_OP_GATHER4_PO_S, VKD3DSIH_GATHER4_PO_S, "fu", "fi**"},
- {VKD3D_SM5_OP_GATHER4_PO_C_S, VKD3DSIH_GATHER4_PO_C_S, "fu", "fi**f"},
- {VKD3D_SM5_OP_LD_S, VKD3DSIH_LD_S, "uu", "i*"},
- {VKD3D_SM5_OP_LD2DMS_S, VKD3DSIH_LD2DMS_S, "uu", "i*i"},
- {VKD3D_SM5_OP_LD_UAV_TYPED_S, VKD3DSIH_LD_UAV_TYPED_S, "uu", "iU"},
- {VKD3D_SM5_OP_LD_RAW_S, VKD3DSIH_LD_RAW_S, "uu", "iU"},
- {VKD3D_SM5_OP_LD_STRUCTURED_S, VKD3DSIH_LD_STRUCTURED_S, "uu", "ii*"},
- {VKD3D_SM5_OP_SAMPLE_LOD_S, VKD3DSIH_SAMPLE_LOD_S, "uu", "f**f"},
- {VKD3D_SM5_OP_SAMPLE_C_LZ_S, VKD3DSIH_SAMPLE_C_LZ_S, "fu", "f**f"},
- {VKD3D_SM5_OP_SAMPLE_CL_S, VKD3DSIH_SAMPLE_CL_S, "uu", "f**f"},
- {VKD3D_SM5_OP_SAMPLE_B_CL_S, VKD3DSIH_SAMPLE_B_CL_S, "uu", "f**ff"},
- {VKD3D_SM5_OP_SAMPLE_GRAD_CL_S, VKD3DSIH_SAMPLE_GRAD_CL_S, "uu", "f**fff"},
- {VKD3D_SM5_OP_SAMPLE_C_CL_S, VKD3DSIH_SAMPLE_C_CL_S, "fu", "f**ff"},
- {VKD3D_SM5_OP_CHECK_ACCESS_FULLY_MAPPED, VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED, "u", "u"},
+ {VKD3D_SM5_OP_DDIV, VSIR_OP_DDIV, "d", "dd"},
+ {VKD3D_SM5_OP_DFMA, VSIR_OP_DFMA, "d", "ddd"},
+ {VKD3D_SM5_OP_DRCP, VSIR_OP_DRCP, "d", "d"},
+ {VKD3D_SM5_OP_MSAD, VSIR_OP_MSAD, "u", "uuu"},
+ {VKD3D_SM5_OP_DTOI, VSIR_OP_DTOI, "i", "d"},
+ {VKD3D_SM5_OP_DTOU, VSIR_OP_DTOU, "u", "d"},
+ {VKD3D_SM5_OP_ITOD, VSIR_OP_ITOD, "d", "i"},
+ {VKD3D_SM5_OP_UTOD, VSIR_OP_UTOD, "d", "u"},
+ {VKD3D_SM5_OP_GATHER4_S, VSIR_OP_GATHER4_S, "uu", "f**"},
+ {VKD3D_SM5_OP_GATHER4_C_S, VSIR_OP_GATHER4_C_S, "fu", "f**f"},
+ {VKD3D_SM5_OP_GATHER4_PO_S, VSIR_OP_GATHER4_PO_S, "fu", "fi**"},
+ {VKD3D_SM5_OP_GATHER4_PO_C_S, VSIR_OP_GATHER4_PO_C_S, "fu", "fi**f"},
+ {VKD3D_SM5_OP_LD_S, VSIR_OP_LD_S, "uu", "i*"},
+ {VKD3D_SM5_OP_LD2DMS_S, VSIR_OP_LD2DMS_S, "uu", "i*i"},
+ {VKD3D_SM5_OP_LD_UAV_TYPED_S, VSIR_OP_LD_UAV_TYPED_S, "uu", "iU"},
+ {VKD3D_SM5_OP_LD_RAW_S, VSIR_OP_LD_RAW_S, "uu", "iU"},
+ {VKD3D_SM5_OP_LD_STRUCTURED_S, VSIR_OP_LD_STRUCTURED_S, "uu", "ii*"},
+ {VKD3D_SM5_OP_SAMPLE_LOD_S, VSIR_OP_SAMPLE_LOD_S, "uu", "f**f"},
+ {VKD3D_SM5_OP_SAMPLE_C_LZ_S, VSIR_OP_SAMPLE_C_LZ_S, "fu", "f**f"},
+ {VKD3D_SM5_OP_SAMPLE_CL_S, VSIR_OP_SAMPLE_CL_S, "uu", "f**f"},
+ {VKD3D_SM5_OP_SAMPLE_B_CL_S, VSIR_OP_SAMPLE_B_CL_S, "uu", "f**ff"},
+ {VKD3D_SM5_OP_SAMPLE_GRAD_CL_S, VSIR_OP_SAMPLE_GRAD_CL_S, "uu", "f**fff"},
+ {VKD3D_SM5_OP_SAMPLE_C_CL_S, VSIR_OP_SAMPLE_C_CL_S, "fu", "f**ff"},
+ {VKD3D_SM5_OP_CHECK_ACCESS_FULLY_MAPPED, VSIR_OP_CHECK_ACCESS_FULLY_MAPPED, "u", "u"},
};
static const struct vkd3d_sm4_register_type_info register_type_table[] =
@@ -1941,7 +1941,7 @@ static const struct vkd3d_sm4_opcode_info *get_info_from_sm4_opcode(
static const struct vkd3d_sm4_opcode_info *get_info_from_vsir_opcode(
const struct vkd3d_sm4_lookup_tables *lookup, enum vkd3d_shader_opcode vsir_opcode)
{
- if (vsir_opcode >= VKD3DSIH_COUNT)
+ if (vsir_opcode >= VSIR_OP_COUNT)
return NULL;
return lookup->opcode_info_from_vsir[vsir_opcode];
}
@@ -1982,25 +1982,25 @@ static enum vkd3d_sm4_stat_field get_stat_field_from_sm4_opcode(
return field_info->field;
}
-static enum vkd3d_data_type map_data_type(char t)
+static enum vsir_data_type map_data_type(char t)
{
switch (t)
{
case 'd':
- return VKD3D_DATA_DOUBLE;
+ return VSIR_DATA_F64;
case 'f':
- return VKD3D_DATA_FLOAT;
+ return VSIR_DATA_F32;
case 'i':
- return VKD3D_DATA_INT;
+ return VSIR_DATA_I32;
case 'u':
- return VKD3D_DATA_UINT;
+ return VSIR_DATA_U32;
case 'O':
- return VKD3D_DATA_OPAQUE;
+ return VSIR_DATA_OPAQUE;
case '*':
- return VKD3D_DATA_UNUSED;
+ return VSIR_DATA_UNUSED;
default:
ERR("Invalid data type '%c'.\n", t);
- return VKD3D_DATA_FLOAT;
+ return VSIR_DATA_F32;
}
}
@@ -2021,7 +2021,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const
reg_idx->offset = *(*ptr)++;
else
reg_idx->offset = 0;
- shader_sm4_read_src_param(priv, ptr, end, VKD3D_DATA_INT, rel_addr);
+ shader_sm4_read_src_param(priv, ptr, end, VSIR_DATA_I32, rel_addr);
}
else
{
@@ -2033,7 +2033,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const
}
static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, const uint32_t *end,
- enum vkd3d_data_type data_type, struct vkd3d_shader_register *param, enum vkd3d_shader_src_modifier *modifier)
+ enum vsir_data_type data_type, struct vkd3d_shader_register *param, enum vkd3d_shader_src_modifier *modifier)
{
const struct vkd3d_sm4_register_type_info *register_type_info;
enum vkd3d_shader_register_type vsir_register_type;
@@ -2234,12 +2234,9 @@ bool shader_sm4_is_scalar_register(const struct vkd3d_shader_register *reg)
{
switch (reg->type)
{
- case VKD3DSPR_COVERAGE:
case VKD3DSPR_DEPTHOUT:
case VKD3DSPR_DEPTHOUTGE:
case VKD3DSPR_DEPTHOUTLE:
- case VKD3DSPR_GSINSTID:
- case VKD3DSPR_LOCALTHREADINDEX:
case VKD3DSPR_OUTPOINTID:
case VKD3DSPR_PRIMID:
case VKD3DSPR_SAMPLEMASK:
@@ -2286,7 +2283,7 @@ static bool register_is_control_point_input(const struct vkd3d_shader_register *
const struct vkd3d_shader_sm4_parser *priv)
{
return reg->type == VKD3DSPR_INCONTROLPOINT || reg->type == VKD3DSPR_OUTCONTROLPOINT
- || (reg->type == VKD3DSPR_INPUT && (priv->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE
+ || (reg->type == VKD3DSPR_INPUT && (priv->phase == VSIR_OP_HS_CONTROL_POINT_PHASE
|| priv->p.program->shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY));
}
@@ -2351,7 +2348,7 @@ static bool shader_sm4_validate_input_output_register(struct vkd3d_shader_sm4_pa
}
static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr,
- const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_src_param *src_param)
+ const uint32_t *end, enum vsir_data_type data_type, struct vkd3d_shader_src_param *src_param)
{
unsigned int dimension, mask;
uint32_t token;
@@ -2439,7 +2436,7 @@ static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, cons
}
static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr,
- const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_dst_param *dst_param)
+ const uint32_t *end, enum vsir_data_type data_type, struct vkd3d_shader_dst_param *dst_param)
{
enum vkd3d_sm4_swizzle_type swizzle_type;
enum vkd3d_shader_src_modifier modifier;
@@ -2509,7 +2506,7 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons
break;
}
- if (data_type == VKD3D_DATA_DOUBLE)
+ if (data_type == VSIR_DATA_F64)
dst_param->write_mask = vsir_write_mask_64_from_32(dst_param->write_mask);
/* Some scalar registers are declared with no write mask in shader bytecode. */
if (!dst_param->write_mask && shader_sm4_is_scalar_register(&dst_param->reg))
@@ -2570,7 +2567,7 @@ static void shader_sm4_read_instruction_modifier(uint32_t modifier, struct vkd3d
if (!data_type || (data_type >= ARRAY_SIZE(data_type_table)))
{
FIXME("Unhandled data type %#x.\n", data_type);
- ins->resource_data_type[i] = VKD3D_DATA_FLOAT;
+ ins->resource_data_type[i] = VSIR_DATA_F32;
}
else
{
@@ -2653,16 +2650,16 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str
if (!(opcode_info = get_info_from_sm4_opcode(&sm4->lookup, opcode)))
{
FIXME("Unrecognized opcode %#x, opcode_token 0x%08x.\n", opcode, opcode_token);
- ins->opcode = VKD3DSIH_INVALID;
+ ins->opcode = VSIR_OP_INVALID;
*ptr += len;
return;
}
vsir_instruction_init(ins, &sm4->p.location, opcode_info->handler_idx);
- if (ins->opcode == VKD3DSIH_HS_CONTROL_POINT_PHASE || ins->opcode == VKD3DSIH_HS_FORK_PHASE
- || ins->opcode == VKD3DSIH_HS_JOIN_PHASE)
+ if (ins->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE || ins->opcode == VSIR_OP_HS_FORK_PHASE
+ || ins->opcode == VSIR_OP_HS_JOIN_PHASE)
sm4->phase = ins->opcode;
- sm4->has_control_point_phase |= ins->opcode == VKD3DSIH_HS_CONTROL_POINT_PHASE;
+ sm4->has_control_point_phase |= ins->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE;
ins->flags = 0;
ins->coissue = false;
ins->raw = false;
@@ -2675,15 +2672,15 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str
{
ERR("Failed to allocate src parameters.\n");
vkd3d_shader_parser_error(&sm4->p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory.");
- ins->opcode = VKD3DSIH_INVALID;
+ ins->opcode = VSIR_OP_INVALID;
return;
}
ins->resource_type = VKD3D_SHADER_RESOURCE_NONE;
ins->resource_stride = 0;
- ins->resource_data_type[0] = VKD3D_DATA_FLOAT;
- ins->resource_data_type[1] = VKD3D_DATA_FLOAT;
- ins->resource_data_type[2] = VKD3D_DATA_FLOAT;
- ins->resource_data_type[3] = VKD3D_DATA_FLOAT;
+ ins->resource_data_type[0] = VSIR_DATA_F32;
+ ins->resource_data_type[1] = VSIR_DATA_F32;
+ ins->resource_data_type[2] = VSIR_DATA_F32;
+ ins->resource_data_type[3] = VSIR_DATA_F32;
memset(&ins->texel_offset, 0, sizeof(ins->texel_offset));
p = *ptr;
@@ -2717,7 +2714,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str
{
ERR("Failed to allocate dst parameters.\n");
vkd3d_shader_parser_error(&sm4->p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory.");
- ins->opcode = VKD3DSIH_INVALID;
+ ins->opcode = VSIR_OP_INVALID;
return;
}
for (i = 0; i < ins->dst_count; ++i)
@@ -2725,7 +2722,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str
if (!(shader_sm4_read_dst_param(sm4, &p, *ptr, map_data_type(opcode_info->dst_info[i]),
&dst_params[i])))
{
- ins->opcode = VKD3DSIH_INVALID;
+ ins->opcode = VSIR_OP_INVALID;
return;
}
dst_params[i].modifiers |= instruction_dst_modifier;
@@ -2736,17 +2733,21 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str
if (!(shader_sm4_read_src_param(sm4, &p, *ptr, map_data_type(opcode_info->src_info[i]),
&src_params[i])))
{
- ins->opcode = VKD3DSIH_INVALID;
+ ins->opcode = VSIR_OP_INVALID;
return;
}
}
}
+ if ((ins->opcode == VSIR_OP_SAMPLE_INFO && ins->flags & VKD3DSI_SAMPLE_INFO_UINT)
+ || (ins->opcode == VSIR_OP_RESINFO && ins->flags & VKD3DSI_RESINFO_UINT))
+ ins->dst[0].reg.data_type = VSIR_DATA_U32;
+
return;
fail:
*ptr = sm4->end;
- ins->opcode = VKD3DSIH_INVALID;
+ ins->opcode = VSIR_OP_INVALID;
return;
}
@@ -2895,7 +2896,6 @@ static void shader_sm4_validate_default_phase_index_ranges(struct vkd3d_shader_s
int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
struct vkd3d_shader_message_context *message_context, struct vsir_program *program)
{
- struct vkd3d_shader_instruction_array *instructions;
struct vkd3d_shader_sm4_parser sm4 = {0};
struct dxbc_shader_desc dxbc_desc = {0};
struct vkd3d_shader_instruction *ins;
@@ -2955,26 +2955,22 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con
return VKD3D_ERROR_INVALID_SHADER;
}
- instructions = &program->instructions;
while (sm4.ptr != sm4.end)
{
- if (!shader_instruction_array_reserve(instructions, instructions->count + 1))
+ if (!(ins = vsir_program_append(program)))
{
- ERR("Failed to allocate instructions.\n");
vkd3d_shader_parser_error(&sm4.p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory.");
vsir_program_cleanup(program);
return VKD3D_ERROR_OUT_OF_MEMORY;
}
- ins = &instructions->elements[instructions->count];
shader_sm4_read_instruction(&sm4, ins);
- if (ins->opcode == VKD3DSIH_INVALID)
+ if (ins->opcode == VSIR_OP_INVALID)
{
WARN("Encountered unrecognized or invalid instruction.\n");
vsir_program_cleanup(program);
return VKD3D_ERROR_OUT_OF_MEMORY;
}
- ++instructions->count;
}
if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL
&& !sm4.has_control_point_phase && !sm4.p.failed)
@@ -3129,6 +3125,9 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s
{"position", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_POSITION},
{"sv_position", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_POSITION},
{"sv_primitiveid", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_PRIMITIVE_ID},
+ {"sv_isfrontface", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_IS_FRONT_FACE},
+ {"sv_rendertargetarrayindex", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX},
+ {"sv_viewportarrayindex", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX},
{"sv_outputcontrolpointid", false, VKD3D_SHADER_TYPE_HULL, ~0u},
{"sv_position", false, VKD3D_SHADER_TYPE_HULL, ~0u},
@@ -3255,6 +3254,8 @@ static int signature_element_pointer_compare(const void *x, const void *y)
const struct signature_element *f = *(const struct signature_element **)y;
int ret;
+ if ((ret = vkd3d_u32_compare(e->stream_index, f->stream_index)))
+ return ret;
if ((ret = vkd3d_u32_compare(e->register_index, f->register_index)))
return ret;
return vkd3d_u32_compare(e->mask, f->mask);
@@ -3263,12 +3264,17 @@ static int signature_element_pointer_compare(const void *x, const void *y)
static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_signature *signature, uint32_t tag)
{
bool has_minimum_precision = tpf->program->global_flags & VKD3DSGF_ENABLE_MINIMUM_PRECISION;
- bool output = tag == TAG_OSGN || (tag == TAG_PCSG
- && tpf->program->shader_version.type == VKD3D_SHADER_TYPE_HULL);
+ const struct vkd3d_shader_version *version = &tpf->program->shader_version;
const struct signature_element **sorted_elements;
struct vkd3d_bytecode_buffer buffer = {0};
+ bool has_stream_index, output;
unsigned int i;
+ output = tag == TAG_OSGN || (tag == TAG_PCSG && version->type == VKD3D_SHADER_TYPE_HULL);
+ if (output && version->type == VKD3D_SHADER_TYPE_GEOMETRY && version->major >= 5)
+ tag = TAG_OSG5;
+ has_stream_index = tag == TAG_OSG5 || has_minimum_precision;
+
put_u32(&buffer, signature->element_count);
put_u32(&buffer, 8); /* unknown */
@@ -3291,8 +3297,8 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si
if (sysval >= VKD3D_SHADER_SV_TARGET)
sysval = VKD3D_SHADER_SV_NONE;
- if (has_minimum_precision)
- put_u32(&buffer, 0); /* FIXME: stream index */
+ if (has_stream_index)
+ put_u32(&buffer, element->stream_index);
put_u32(&buffer, 0); /* name */
put_u32(&buffer, element->semantic_index);
put_u32(&buffer, sysval);
@@ -3306,13 +3312,16 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si
for (i = 0; i < signature->element_count; ++i)
{
const struct signature_element *element = sorted_elements[i];
+ size_t name_index = 2 + i * 6;
size_t string_offset;
- string_offset = put_string(&buffer, element->semantic_name);
+ if (has_stream_index)
+ name_index += i + 1;
if (has_minimum_precision)
- set_u32(&buffer, (2 + i * 8 + 1) * sizeof(uint32_t), string_offset);
- else
- set_u32(&buffer, (2 + i * 6) * sizeof(uint32_t), string_offset);
+ name_index += i;
+
+ string_offset = put_string(&buffer, element->semantic_name);
+ set_u32(&buffer, name_index * sizeof(uint32_t), string_offset);
}
if (has_minimum_precision)
@@ -3822,7 +3831,7 @@ static void tpf_dcl_sampler(const struct tpf_compiler *tpf, const struct vkd3d_s
write_sm4_instruction(tpf, &instr);
}
-static uint32_t pack_resource_data_type(const enum vkd3d_data_type *resource_data_type)
+static uint32_t pack_resource_data_type(const enum vsir_data_type *resource_data_type)
{
unsigned int i, k, type = 0;
@@ -3843,9 +3852,8 @@ static uint32_t pack_resource_data_type(const enum vkd3d_data_type *resource_dat
static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins)
{
- const struct vkd3d_shader_structured_resource *structured_resource = &ins->declaration.structured_resource;
- const struct vkd3d_shader_semantic *semantic = &ins->declaration.semantic;
const struct vkd3d_shader_version *version = &tpf->program->shader_version;
+ const struct vkd3d_shader_resource *resource;
const struct vkd3d_sm4_opcode_info *info;
struct sm4_instruction instr = {0};
bool uav;
@@ -3853,33 +3861,44 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s
info = get_info_from_vsir_opcode(&tpf->lookup, ins->opcode);
VKD3D_ASSERT(info);
- uav = ins->opcode == VKD3DSIH_DCL_UAV_TYPED
- || ins->opcode == VKD3DSIH_DCL_UAV_RAW
- || ins->opcode == VKD3DSIH_DCL_UAV_STRUCTURED;
+ uav = ins->opcode == VSIR_OP_DCL_UAV_TYPED
+ || ins->opcode == VSIR_OP_DCL_UAV_RAW
+ || ins->opcode == VSIR_OP_DCL_UAV_STRUCTURED;
instr.opcode = info->opcode;
- instr.dsts[0] = semantic->resource.reg;
- instr.dst_count = 1;
-
- if (ins->opcode == VKD3DSIH_DCL || ins->opcode == VKD3DSIH_DCL_UAV_TYPED)
+ if (ins->opcode == VSIR_OP_DCL || ins->opcode == VSIR_OP_DCL_UAV_TYPED)
{
- instr.idx[0] = pack_resource_data_type(semantic->resource_data_type);
+ instr.idx[0] = pack_resource_data_type(ins->declaration.semantic.resource_data_type);
instr.idx_count = 1;
+ instr.extra_bits |= ins->declaration.semantic.sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT;
+ resource = &ins->declaration.semantic.resource;
}
+ else if (ins->opcode == VSIR_OP_DCL_RESOURCE_RAW || ins->opcode == VSIR_OP_DCL_UAV_RAW)
+ {
+ resource = &ins->declaration.raw_resource.resource;
+ }
+ else
+ {
+ instr.byte_stride = ins->declaration.structured_resource.byte_stride;
+ resource = &ins->declaration.structured_resource.resource;
+ }
+
+ instr.dsts[0] = resource->reg;
+ instr.dst_count = 1;
if (vkd3d_shader_ver_ge(version, 5, 1))
{
- instr.dsts[0].reg.idx[0].offset = semantic->resource.reg.reg.idx[0].offset;
- instr.dsts[0].reg.idx[1].offset = semantic->resource.range.first;
- instr.dsts[0].reg.idx[2].offset = semantic->resource.range.last;
+ instr.dsts[0].reg.idx[0].offset = resource->reg.reg.idx[0].offset;
+ instr.dsts[0].reg.idx[1].offset = resource->range.first;
+ instr.dsts[0].reg.idx[2].offset = resource->range.last;
instr.dsts[0].reg.idx_count = 3;
- instr.idx[instr.idx_count++] = semantic->resource.range.space;
+ instr.idx[instr.idx_count++] = resource->range.space;
}
else
{
- instr.dsts[0].reg.idx[0].offset = semantic->resource.range.first;
+ instr.dsts[0].reg.idx[0].offset = resource->range.first;
instr.dsts[0].reg.idx_count = 1;
}
@@ -3887,10 +3906,23 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s
instr.extra_bits |= ins->flags << VKD3D_SM5_UAV_FLAGS_SHIFT;
instr.extra_bits |= (sm4_resource_dimension(ins->resource_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT);
- instr.extra_bits |= semantic->sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT;
- if (ins->structured)
- instr.byte_stride = structured_resource->byte_stride;
+ write_sm4_instruction(tpf, &instr);
+}
+
+static void tpf_dcl_tgsm_raw(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins)
+{
+ const struct vkd3d_shader_tgsm_raw *tgsm = &ins->declaration.tgsm_raw;
+ struct sm4_instruction instr =
+ {
+ .opcode = VKD3D_SM5_OP_DCL_TGSM_RAW,
+
+ .dsts[0] = tgsm->reg,
+ .dst_count = 1,
+
+ .idx[0] = tgsm->byte_count,
+ .idx_count = 1,
+ };
write_sm4_instruction(tpf, &instr);
}
@@ -4024,6 +4056,39 @@ static void tpf_write_dcl_vertices_out(const struct tpf_compiler *tpf, unsigned
write_sm4_instruction(tpf, &instr);
}
+/* Descriptor registers are stored in shader model 5.1 format regardless
+ * of the program's version. Convert them to the 4.0 format if necessary. */
+static void rewrite_descriptor_register(const struct tpf_compiler *tpf, struct vkd3d_shader_register *reg)
+{
+ if (vkd3d_shader_ver_ge(&tpf->program->shader_version, 5, 1))
+ return;
+
+ switch (reg->type)
+ {
+ case VKD3DSPR_CONSTBUFFER:
+ reg->idx[0] = reg->idx[1];
+ reg->idx[1] = reg->idx[2];
+ reg->idx_count = 2;
+ break;
+
+ case VKD3DSPR_RESOURCE:
+ case VKD3DSPR_SAMPLER:
+ case VKD3DSPR_UAV:
+ reg->idx[0] = reg->idx[1];
+ reg->idx_count = 1;
+ break;
+
+ default:
+ break;
+ }
+
+ for (unsigned int i = 0; i < reg->idx_count; ++i)
+ {
+ if (reg->idx[i].rel_addr)
+ rewrite_descriptor_register(tpf, &reg->idx[i].rel_addr->reg);
+ }
+}
+
static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins)
{
struct sm4_instruction_modifier *modifier;
@@ -4039,14 +4104,14 @@ static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_
if (ins->dst_count != dst_count)
{
- ERR("Invalid destination count %u for vsir instruction %#x (expected %u).\n",
+ ERR("Invalid destination count %zu for vsir instruction %#x (expected %u).\n",
ins->dst_count, ins->opcode, dst_count);
tpf->result = VKD3D_ERROR_INVALID_SHADER;
return;
}
if (ins->src_count != src_count)
{
- ERR("Invalid source count %u for vsir instruction %#x (expected %u).\n",
+ ERR("Invalid source count %zu for vsir instruction %#x (expected %u).\n",
ins->src_count, ins->opcode, src_count);
tpf->result = VKD3D_ERROR_INVALID_SHADER;
return;
@@ -4060,6 +4125,7 @@ static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_
for (unsigned int i = 0; i < ins->dst_count; ++i)
{
instr.dsts[i] = ins->dst[i];
+ rewrite_descriptor_register(tpf, &instr.dsts[i].reg);
if (instr.dsts[i].modifiers & VKD3DSPDM_SATURATE)
{
@@ -4070,7 +4136,10 @@ static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_
}
}
for (unsigned int i = 0; i < ins->src_count; ++i)
+ {
instr.srcs[i] = ins->src[i];
+ rewrite_descriptor_register(tpf, &instr.srcs[i].reg);
+ }
if (ins->texel_offset.u || ins->texel_offset.v || ins->texel_offset.w)
{
@@ -4095,177 +4164,188 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_
{
switch (ins->opcode)
{
- case VKD3DSIH_DCL_CONSTANT_BUFFER:
+ case VSIR_OP_DCL_CONSTANT_BUFFER:
tpf_dcl_constant_buffer(tpf, ins);
break;
- case VKD3DSIH_DCL_TEMPS:
+ case VSIR_OP_DCL_TEMPS:
tpf_dcl_temps(tpf, ins->declaration.count);
break;
- case VKD3DSIH_DCL_INDEXABLE_TEMP:
+ case VSIR_OP_DCL_INDEXABLE_TEMP:
tpf_dcl_indexable_temp(tpf, &ins->declaration.indexable_temp);
break;
- case VKD3DSIH_DCL_INPUT:
+ case VSIR_OP_DCL_INPUT:
tpf_dcl_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT, &ins->declaration.dst, 0);
break;
- case VKD3DSIH_DCL_INPUT_PS:
+ case VSIR_OP_DCL_INPUT_PS:
tpf_dcl_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_PS, &ins->declaration.dst, ins->flags);
break;
- case VKD3DSIH_DCL_INPUT_PS_SGV:
+ case VSIR_OP_DCL_INPUT_PS_SGV:
tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_PS_SGV, &ins->declaration.register_semantic, 0);
break;
- case VKD3DSIH_DCL_INPUT_PS_SIV:
+ case VSIR_OP_DCL_INPUT_PS_SIV:
tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_PS_SIV, &ins->declaration.register_semantic, ins->flags);
break;
- case VKD3DSIH_DCL_INPUT_SGV:
+ case VSIR_OP_DCL_INPUT_SGV:
tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_SGV, &ins->declaration.register_semantic, 0);
break;
- case VKD3DSIH_DCL_INPUT_SIV:
+ case VSIR_OP_DCL_INPUT_SIV:
tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_SIV, &ins->declaration.register_semantic, 0);
break;
- case VKD3DSIH_DCL_OUTPUT:
+ case VSIR_OP_DCL_OUTPUT:
tpf_dcl_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT, &ins->declaration.dst, 0);
break;
- case VKD3DSIH_DCL_OUTPUT_SIV:
+ case VSIR_OP_DCL_OUTPUT_SGV:
+ tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT_SGV, &ins->declaration.register_semantic, 0);
+ break;
+
+ case VSIR_OP_DCL_OUTPUT_SIV:
tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT_SIV, &ins->declaration.register_semantic, 0);
break;
- case VKD3DSIH_DCL_SAMPLER:
+ case VSIR_OP_DCL_SAMPLER:
tpf_dcl_sampler(tpf, ins);
break;
- case VKD3DSIH_DCL:
- case VKD3DSIH_DCL_RESOURCE_RAW:
- case VKD3DSIH_DCL_UAV_RAW:
- case VKD3DSIH_DCL_UAV_STRUCTURED:
- case VKD3DSIH_DCL_UAV_TYPED:
+ case VSIR_OP_DCL_TGSM_RAW:
+ tpf_dcl_tgsm_raw(tpf, ins);
+ break;
+
+ case VSIR_OP_DCL:
+ case VSIR_OP_DCL_RESOURCE_RAW:
+ case VSIR_OP_DCL_UAV_RAW:
+ case VSIR_OP_DCL_UAV_STRUCTURED:
+ case VSIR_OP_DCL_UAV_TYPED:
tpf_dcl_texture(tpf, ins);
break;
- case VKD3DSIH_ADD:
- case VKD3DSIH_ATOMIC_AND:
- case VKD3DSIH_ATOMIC_CMP_STORE:
- case VKD3DSIH_ATOMIC_IADD:
- case VKD3DSIH_ATOMIC_IMAX:
- case VKD3DSIH_ATOMIC_IMIN:
- case VKD3DSIH_ATOMIC_UMAX:
- case VKD3DSIH_ATOMIC_UMIN:
- case VKD3DSIH_ATOMIC_OR:
- case VKD3DSIH_ATOMIC_XOR:
- case VKD3DSIH_AND:
- case VKD3DSIH_BREAK:
- case VKD3DSIH_CASE:
- case VKD3DSIH_CONTINUE:
- case VKD3DSIH_CUT:
- case VKD3DSIH_DEFAULT:
- case VKD3DSIH_DISCARD:
- case VKD3DSIH_DIV:
- case VKD3DSIH_DP2:
- case VKD3DSIH_DP3:
- case VKD3DSIH_DP4:
- case VKD3DSIH_DSX:
- case VKD3DSIH_DSX_COARSE:
- case VKD3DSIH_DSX_FINE:
- case VKD3DSIH_DSY:
- case VKD3DSIH_DSY_COARSE:
- case VKD3DSIH_DSY_FINE:
- case VKD3DSIH_ELSE:
- case VKD3DSIH_EMIT:
- case VKD3DSIH_ENDIF:
- case VKD3DSIH_ENDLOOP:
- case VKD3DSIH_ENDSWITCH:
- case VKD3DSIH_EQO:
- case VKD3DSIH_EXP:
- case VKD3DSIH_F16TOF32:
- case VKD3DSIH_F32TOF16:
- case VKD3DSIH_FRC:
- case VKD3DSIH_FTOI:
- case VKD3DSIH_FTOU:
- case VKD3DSIH_GATHER4:
- case VKD3DSIH_GATHER4_PO:
- case VKD3DSIH_GATHER4_C:
- case VKD3DSIH_GATHER4_PO_C:
- case VKD3DSIH_GEO:
- case VKD3DSIH_HS_CONTROL_POINT_PHASE:
- case VKD3DSIH_HS_FORK_PHASE:
- case VKD3DSIH_IADD:
- case VKD3DSIH_IEQ:
- case VKD3DSIH_IF:
- case VKD3DSIH_IGE:
- case VKD3DSIH_ILT:
- case VKD3DSIH_IMAD:
- case VKD3DSIH_IMAX:
- case VKD3DSIH_IMIN:
- case VKD3DSIH_IMM_ATOMIC_AND:
- case VKD3DSIH_IMM_ATOMIC_CMP_EXCH:
- case VKD3DSIH_IMM_ATOMIC_EXCH:
- case VKD3DSIH_IMM_ATOMIC_IADD:
- case VKD3DSIH_IMM_ATOMIC_IMAX:
- case VKD3DSIH_IMM_ATOMIC_IMIN:
- case VKD3DSIH_IMM_ATOMIC_UMAX:
- case VKD3DSIH_IMM_ATOMIC_UMIN:
- case VKD3DSIH_IMM_ATOMIC_OR:
- case VKD3DSIH_IMM_ATOMIC_XOR:
- case VKD3DSIH_SYNC:
- case VKD3DSIH_IMUL:
- case VKD3DSIH_INE:
- case VKD3DSIH_INEG:
- case VKD3DSIH_ISHL:
- case VKD3DSIH_ISHR:
- case VKD3DSIH_ITOF:
- case VKD3DSIH_LD:
- case VKD3DSIH_LD2DMS:
- case VKD3DSIH_LD_RAW:
- case VKD3DSIH_LD_UAV_TYPED:
- case VKD3DSIH_LOG:
- case VKD3DSIH_LOOP:
- case VKD3DSIH_LTO:
- case VKD3DSIH_MAD:
- case VKD3DSIH_MAX:
- case VKD3DSIH_MIN:
- case VKD3DSIH_MOV:
- case VKD3DSIH_MOVC:
- case VKD3DSIH_MUL:
- case VKD3DSIH_NEU:
- case VKD3DSIH_NOT:
- case VKD3DSIH_OR:
- case VKD3DSIH_RCP:
- case VKD3DSIH_RESINFO:
- case VKD3DSIH_RET:
- case VKD3DSIH_ROUND_NE:
- case VKD3DSIH_ROUND_NI:
- case VKD3DSIH_ROUND_PI:
- case VKD3DSIH_ROUND_Z:
- case VKD3DSIH_RSQ:
- case VKD3DSIH_SAMPLE:
- case VKD3DSIH_SAMPLE_B:
- case VKD3DSIH_SAMPLE_C:
- case VKD3DSIH_SAMPLE_C_LZ:
- case VKD3DSIH_SAMPLE_GRAD:
- case VKD3DSIH_SAMPLE_INFO:
- case VKD3DSIH_SAMPLE_LOD:
- case VKD3DSIH_SINCOS:
- case VKD3DSIH_SQRT:
- case VKD3DSIH_STORE_RAW:
- case VKD3DSIH_STORE_UAV_TYPED:
- case VKD3DSIH_SWITCH:
- case VKD3DSIH_UDIV:
- case VKD3DSIH_UGE:
- case VKD3DSIH_ULT:
- case VKD3DSIH_UMAX:
- case VKD3DSIH_UMIN:
- case VKD3DSIH_USHR:
- case VKD3DSIH_UTOF:
- case VKD3DSIH_XOR:
+ case VSIR_OP_ADD:
+ case VSIR_OP_ATOMIC_AND:
+ case VSIR_OP_ATOMIC_CMP_STORE:
+ case VSIR_OP_ATOMIC_IADD:
+ case VSIR_OP_ATOMIC_IMAX:
+ case VSIR_OP_ATOMIC_IMIN:
+ case VSIR_OP_ATOMIC_UMAX:
+ case VSIR_OP_ATOMIC_UMIN:
+ case VSIR_OP_ATOMIC_OR:
+ case VSIR_OP_ATOMIC_XOR:
+ case VSIR_OP_AND:
+ case VSIR_OP_BREAK:
+ case VSIR_OP_CASE:
+ case VSIR_OP_CONTINUE:
+ case VSIR_OP_CUT:
+ case VSIR_OP_CUT_STREAM:
+ case VSIR_OP_DCL_STREAM:
+ case VSIR_OP_DEFAULT:
+ case VSIR_OP_DISCARD:
+ case VSIR_OP_DIV:
+ case VSIR_OP_DP2:
+ case VSIR_OP_DP3:
+ case VSIR_OP_DP4:
+ case VSIR_OP_DSX:
+ case VSIR_OP_DSX_COARSE:
+ case VSIR_OP_DSX_FINE:
+ case VSIR_OP_DSY:
+ case VSIR_OP_DSY_COARSE:
+ case VSIR_OP_DSY_FINE:
+ case VSIR_OP_ELSE:
+ case VSIR_OP_EMIT:
+ case VSIR_OP_EMIT_STREAM:
+ case VSIR_OP_ENDIF:
+ case VSIR_OP_ENDLOOP:
+ case VSIR_OP_ENDSWITCH:
+ case VSIR_OP_EQO:
+ case VSIR_OP_EXP:
+ case VSIR_OP_F16TOF32:
+ case VSIR_OP_F32TOF16:
+ case VSIR_OP_FRC:
+ case VSIR_OP_FTOI:
+ case VSIR_OP_FTOU:
+ case VSIR_OP_GATHER4:
+ case VSIR_OP_GATHER4_PO:
+ case VSIR_OP_GATHER4_C:
+ case VSIR_OP_GATHER4_PO_C:
+ case VSIR_OP_GEO:
+ case VSIR_OP_HS_CONTROL_POINT_PHASE:
+ case VSIR_OP_HS_FORK_PHASE:
+ case VSIR_OP_IADD:
+ case VSIR_OP_IEQ:
+ case VSIR_OP_IF:
+ case VSIR_OP_IGE:
+ case VSIR_OP_ILT:
+ case VSIR_OP_IMAD:
+ case VSIR_OP_IMAX:
+ case VSIR_OP_IMIN:
+ case VSIR_OP_IMM_ATOMIC_AND:
+ case VSIR_OP_IMM_ATOMIC_CMP_EXCH:
+ case VSIR_OP_IMM_ATOMIC_EXCH:
+ case VSIR_OP_IMM_ATOMIC_IADD:
+ case VSIR_OP_IMM_ATOMIC_IMAX:
+ case VSIR_OP_IMM_ATOMIC_IMIN:
+ case VSIR_OP_IMM_ATOMIC_UMAX:
+ case VSIR_OP_IMM_ATOMIC_UMIN:
+ case VSIR_OP_IMM_ATOMIC_OR:
+ case VSIR_OP_IMM_ATOMIC_XOR:
+ case VSIR_OP_SYNC:
+ case VSIR_OP_IMUL:
+ case VSIR_OP_INE:
+ case VSIR_OP_INEG:
+ case VSIR_OP_ISHL:
+ case VSIR_OP_ISHR:
+ case VSIR_OP_ITOF:
+ case VSIR_OP_LD:
+ case VSIR_OP_LD2DMS:
+ case VSIR_OP_LD_RAW:
+ case VSIR_OP_LD_UAV_TYPED:
+ case VSIR_OP_LOG:
+ case VSIR_OP_LOOP:
+ case VSIR_OP_LTO:
+ case VSIR_OP_MAD:
+ case VSIR_OP_MAX:
+ case VSIR_OP_MIN:
+ case VSIR_OP_MOV:
+ case VSIR_OP_MOVC:
+ case VSIR_OP_MUL:
+ case VSIR_OP_NEU:
+ case VSIR_OP_NOT:
+ case VSIR_OP_OR:
+ case VSIR_OP_RCP:
+ case VSIR_OP_RESINFO:
+ case VSIR_OP_RET:
+ case VSIR_OP_ROUND_NE:
+ case VSIR_OP_ROUND_NI:
+ case VSIR_OP_ROUND_PI:
+ case VSIR_OP_ROUND_Z:
+ case VSIR_OP_RSQ:
+ case VSIR_OP_SAMPLE:
+ case VSIR_OP_SAMPLE_B:
+ case VSIR_OP_SAMPLE_C:
+ case VSIR_OP_SAMPLE_C_LZ:
+ case VSIR_OP_SAMPLE_GRAD:
+ case VSIR_OP_SAMPLE_INFO:
+ case VSIR_OP_SAMPLE_LOD:
+ case VSIR_OP_SINCOS:
+ case VSIR_OP_SQRT:
+ case VSIR_OP_STORE_RAW:
+ case VSIR_OP_STORE_UAV_TYPED:
+ case VSIR_OP_SWITCH:
+ case VSIR_OP_UDIV:
+ case VSIR_OP_UGE:
+ case VSIR_OP_ULT:
+ case VSIR_OP_UMAX:
+ case VSIR_OP_UMIN:
+ case VSIR_OP_USHR:
+ case VSIR_OP_UTOF:
+ case VSIR_OP_XOR:
tpf_simple_instruction(tpf, ins);
break;
@@ -4275,20 +4355,23 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_
}
}
-static void tpf_write_program(struct tpf_compiler *tpf, const struct vsir_program *program)
+static void tpf_write_program(struct tpf_compiler *tpf, struct vsir_program *program)
{
- unsigned int i;
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
+ struct vkd3d_shader_instruction *ins;
if (tpf->program->shader_version.type == VKD3D_SHADER_TYPE_COMPUTE)
tpf_dcl_thread_group(tpf, &tpf->program->thread_group_size);
- for (i = 0; i < program->instructions.count; ++i)
- tpf_handle_instruction(tpf, &program->instructions.elements[i]);
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
+ {
+ tpf_handle_instruction(tpf, ins);
+ }
}
static void tpf_write_shdr(struct tpf_compiler *tpf)
{
- const struct vsir_program *program = tpf->program;
+ struct vsir_program *program = tpf->program;
const struct vkd3d_shader_version *version;
struct vkd3d_bytecode_buffer buffer = {0};
size_t token_count_position;
@@ -4434,6 +4517,12 @@ int tpf_compile(struct vsir_program *program, uint64_t config_flags, const struc
size_t i;
int ret;
+ if ((ret = vsir_allocate_temp_registers(program, message_context)))
+ return ret;
+
+ if ((ret = vsir_update_dcl_temps(program, message_context)))
+ return ret;
+
tpf.program = program;
tpf.buffer = NULL;
tpf.stat = &stat;
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
index f56608940db..d1992c9d446 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -23,6 +23,8 @@
#include <stdio.h>
#include <math.h>
+/* VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG"); */
+
static inline int char_to_int(char c)
{
if ('0' <= c && c <= '9')
@@ -55,6 +57,39 @@ uint32_t vkd3d_parse_integer(const char *s)
return ret;
}
+bool vkd3d_shader_source_list_append(struct vkd3d_shader_source_list *l, const char *source)
+{
+ char *s;
+
+ if (!(s = vkd3d_strdup(source)))
+ return false;
+
+ if (!vkd3d_array_reserve((void **)&l->sources, &l->capacity, l->count + 1, sizeof(*l->sources)))
+ {
+ vkd3d_free(s);
+ return false;
+ }
+ l->sources[l->count++] = s;
+
+ return true;
+}
+
+void vkd3d_shader_source_list_cleanup(struct vkd3d_shader_source_list *l)
+{
+ size_t i;
+
+ for (i = 0; i < l->count; ++i)
+ {
+ vkd3d_free((void *)l->sources[i]);
+ }
+ vkd3d_free(l->sources);
+}
+
+void vkd3d_shader_source_list_init(struct vkd3d_shader_source_list *l)
+{
+ memset(l, 0, sizeof(*l));
+}
+
void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer)
{
buffer->buffer_size = 16;
@@ -85,7 +120,7 @@ void vkd3d_string_buffer_truncate(struct vkd3d_string_buffer *buffer, size_t siz
static bool vkd3d_string_buffer_resize(struct vkd3d_string_buffer *buffer, int rc)
{
- unsigned int new_buffer_size = rc >= 0 ? buffer->content_size + rc + 1 : buffer->buffer_size * 2;
+ size_t new_buffer_size = rc >= 0 ? buffer->content_size + rc + 1 : buffer->buffer_size * 2;
if (!vkd3d_array_reserve((void **)&buffer->buffer, &buffer->buffer_size, new_buffer_size, 1))
{
@@ -98,7 +133,7 @@ static bool vkd3d_string_buffer_resize(struct vkd3d_string_buffer *buffer, int r
int vkd3d_string_buffer_vprintf(struct vkd3d_string_buffer *buffer, const char *format, va_list args)
{
- unsigned int rem;
+ size_t rem;
va_list a;
int rc;
@@ -133,7 +168,7 @@ int vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer, const char *f
int vkd3d_string_buffer_print_f32(struct vkd3d_string_buffer *buffer, float f)
{
- unsigned int idx = buffer->content_size + 1;
+ size_t idx = buffer->content_size + 1;
int ret;
if (!(ret = vkd3d_string_buffer_printf(buffer, "%.8e", f)) && isfinite(f))
@@ -148,7 +183,7 @@ int vkd3d_string_buffer_print_f32(struct vkd3d_string_buffer *buffer, float f)
int vkd3d_string_buffer_print_f64(struct vkd3d_string_buffer *buffer, double d)
{
- unsigned int idx = buffer->content_size + 1;
+ size_t idx = buffer->content_size + 1;
int ret;
if (!(ret = vkd3d_string_buffer_printf(buffer, "%.16e", d)) && isfinite(d))
@@ -336,7 +371,10 @@ bool vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_cont
void vkd3d_shader_vnote(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
enum vkd3d_shader_log_level level, const char *format, va_list args)
{
- if (context->log_level < level)
+ struct vkd3d_string_buffer *messages = &context->messages;
+ size_t pos = messages->content_size;
+
+ if (!WARN_ON() && context->log_level < level)
return;
if (location)
@@ -344,19 +382,26 @@ void vkd3d_shader_vnote(struct vkd3d_shader_message_context *context, const stru
const char *source_name = location->source_name ? location->source_name : "<anonymous>";
if (location->line)
- vkd3d_string_buffer_printf(&context->messages, "%s:%u:%u: ",
+ vkd3d_string_buffer_printf(messages, "%s:%u:%u: ",
source_name, location->line, location->column);
else
- vkd3d_string_buffer_printf(&context->messages, "%s: ", source_name);
+ vkd3d_string_buffer_printf(messages, "%s: ", source_name);
}
- vkd3d_string_buffer_vprintf(&context->messages, format, args);
- vkd3d_string_buffer_printf(&context->messages, "\n");
+ vkd3d_string_buffer_vprintf(messages, format, args);
+ vkd3d_string_buffer_printf(messages, "\n");
+
+ WARN("%.*s", (int)(messages->content_size - pos), &messages->buffer[pos]);
+ if (context->log_level < level)
+ messages->content_size = pos;
}
void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
enum vkd3d_shader_error error, const char *format, va_list args)
{
- if (context->log_level < VKD3D_SHADER_LOG_WARNING)
+ struct vkd3d_string_buffer *messages = &context->messages;
+ size_t pos = messages->content_size;
+
+ if (!WARN_ON() && context->log_level < VKD3D_SHADER_LOG_WARNING)
return;
if (location)
@@ -364,17 +409,21 @@ void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const s
const char *source_name = location->source_name ? location->source_name : "<anonymous>";
if (location->line)
- vkd3d_string_buffer_printf(&context->messages, "%s:%u:%u: W%04u: ",
+ vkd3d_string_buffer_printf(messages, "%s:%u:%u: W%04u: ",
source_name, location->line, location->column, error);
else
- vkd3d_string_buffer_printf(&context->messages, "%s: W%04u: ", source_name, error);
+ vkd3d_string_buffer_printf(messages, "%s: W%04u: ", source_name, error);
}
else
{
- vkd3d_string_buffer_printf(&context->messages, "W%04u: ", error);
+ vkd3d_string_buffer_printf(messages, "W%04u: ", error);
}
- vkd3d_string_buffer_vprintf(&context->messages, format, args);
- vkd3d_string_buffer_printf(&context->messages, "\n");
+ vkd3d_string_buffer_vprintf(messages, format, args);
+ vkd3d_string_buffer_printf(messages, "\n");
+
+ WARN("%.*s", (int)(messages->content_size - pos), &messages->buffer[pos]);
+ if (context->log_level < VKD3D_SHADER_LOG_WARNING)
+ messages->content_size = pos;
}
void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
@@ -390,7 +439,10 @@ void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const st
void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
enum vkd3d_shader_error error, const char *format, va_list args)
{
- if (context->log_level < VKD3D_SHADER_LOG_ERROR)
+ struct vkd3d_string_buffer *messages = &context->messages;
+ size_t pos = messages->content_size;
+
+ if (!WARN_ON() && context->log_level < VKD3D_SHADER_LOG_ERROR)
return;
if (location)
@@ -398,17 +450,21 @@ void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const str
const char *source_name = location->source_name ? location->source_name : "<anonymous>";
if (location->line)
- vkd3d_string_buffer_printf(&context->messages, "%s:%u:%u: E%04u: ",
+ vkd3d_string_buffer_printf(messages, "%s:%u:%u: E%04u: ",
source_name, location->line, location->column, error);
else
- vkd3d_string_buffer_printf(&context->messages, "%s: E%04u: ", source_name, error);
+ vkd3d_string_buffer_printf(messages, "%s: E%04u: ", source_name, error);
}
else
{
- vkd3d_string_buffer_printf(&context->messages, "E%04u: ", error);
+ vkd3d_string_buffer_printf(messages, "E%04u: ", error);
}
- vkd3d_string_buffer_vprintf(&context->messages, format, args);
- vkd3d_string_buffer_printf(&context->messages, "\n");
+ vkd3d_string_buffer_vprintf(messages, format, args);
+ vkd3d_string_buffer_printf(messages, "\n");
+
+ WARN("%.*s", (int)(messages->content_size - pos), &messages->buffer[pos]);
+ if (context->log_level < VKD3D_SHADER_LOG_ERROR)
+ messages->content_size = pos;
}
void vkd3d_shader_error(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location,
@@ -744,12 +800,28 @@ static int vkd3d_shader_validate_compile_info(const struct vkd3d_shader_compile_
}
static enum vkd3d_result vsir_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags,
- struct vkd3d_shader_message_context *message_context, struct vsir_program *program)
+ const struct shader_dump_data *dump_data, struct vkd3d_shader_message_context *message_context,
+ struct vsir_program *program, struct vkd3d_shader_code *reflection_data)
{
+ struct vkd3d_shader_compile_info preprocessed_info;
+ struct vkd3d_shader_code preprocessed;
enum vkd3d_result ret;
switch (compile_info->source_type)
{
+ case VKD3D_SHADER_SOURCE_HLSL:
+ if ((ret = preproc_lexer_parse(compile_info, &preprocessed, message_context)) >= 0)
+ {
+ vkd3d_shader_dump_shader(dump_data, preprocessed.code, preprocessed.size, SHADER_DUMP_TYPE_PREPROC);
+
+ preprocessed_info = *compile_info;
+ preprocessed_info.source = preprocessed;
+ ret = hlsl_parse(&preprocessed_info, message_context, program, reflection_data);
+
+ vkd3d_shader_free_shader_code(&preprocessed);
+ }
+ break;
+
case VKD3D_SHADER_SOURCE_D3D_BYTECODE:
ret = d3dbc_parse(compile_info, config_flags, message_context, program);
break;
@@ -780,13 +852,19 @@ static enum vkd3d_result vsir_parse(const struct vkd3d_shader_compile_info *comp
if (TRACE_ON())
vsir_program_trace(program);
-
- vsir_program_cleanup(program);
- return ret;
+ goto fail;
}
- if (compile_info->target_type != VKD3D_SHADER_TARGET_NONE)
- ret = vsir_program_transform_early(program, config_flags, compile_info, message_context);
+ if (compile_info->target_type != VKD3D_SHADER_TARGET_NONE
+ && (ret = vsir_program_transform_early(program, config_flags, compile_info, message_context)) < 0)
+ goto fail;
+
+ return ret;
+
+fail:
+ vkd3d_shader_free_shader_code(reflection_data);
+ vsir_program_cleanup(program);
+
return ret;
}
@@ -1018,11 +1096,11 @@ static bool vkd3d_shader_instruction_is_uav_read(const struct vkd3d_shader_instr
{
enum vkd3d_shader_opcode opcode = instruction->opcode;
- return (VKD3DSIH_ATOMIC_AND <= opcode && opcode <= VKD3DSIH_ATOMIC_XOR)
- || (VKD3DSIH_IMM_ATOMIC_ALLOC <= opcode && opcode <= VKD3DSIH_IMM_ATOMIC_XOR)
- || opcode == VKD3DSIH_LD_UAV_TYPED
- || (opcode == VKD3DSIH_LD_RAW && instruction->src[1].reg.type == VKD3DSPR_UAV)
- || (opcode == VKD3DSIH_LD_STRUCTURED && instruction->src[2].reg.type == VKD3DSPR_UAV);
+ return (VSIR_OP_ATOMIC_AND <= opcode && opcode <= VSIR_OP_ATOMIC_XOR)
+ || (VSIR_OP_IMM_ATOMIC_ALLOC <= opcode && opcode <= VSIR_OP_IMM_ATOMIC_XOR)
+ || opcode == VSIR_OP_LD_UAV_TYPED
+ || (opcode == VSIR_OP_LD_RAW && instruction->src[1].reg.type == VKD3DSPR_UAV)
+ || (opcode == VSIR_OP_LD_STRUCTURED && instruction->src[2].reg.type == VKD3DSPR_UAV);
}
static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_context *context,
@@ -1035,7 +1113,7 @@ static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_in
{
enum vkd3d_shader_opcode opcode = instruction->opcode;
- return opcode == VKD3DSIH_IMM_ATOMIC_ALLOC || opcode == VKD3DSIH_IMM_ATOMIC_CONSUME;
+ return opcode == VSIR_OP_IMM_ATOMIC_ALLOC || opcode == VSIR_OP_IMM_ATOMIC_CONSUME;
}
static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_context *context,
@@ -1048,8 +1126,8 @@ static bool vkd3d_shader_instruction_is_uav_atomic_op(const struct vkd3d_shader_
{
enum vkd3d_shader_opcode opcode = instruction->opcode;
- return (VKD3DSIH_ATOMIC_AND <= opcode && opcode <= VKD3DSIH_ATOMIC_XOR)
- || (VKD3DSIH_IMM_ATOMIC_ALLOC <= opcode && opcode <= VKD3DSIH_IMM_ATOMIC_XOR);
+ return (VSIR_OP_ATOMIC_AND <= opcode && opcode <= VSIR_OP_ATOMIC_XOR)
+ || (VSIR_OP_IMM_ATOMIC_ALLOC <= opcode && opcode <= VSIR_OP_IMM_ATOMIC_XOR);
}
static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_context *context,
@@ -1061,7 +1139,7 @@ static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_cont
static struct vkd3d_shader_descriptor_info1 *vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context,
enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register *reg,
const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type,
- enum vkd3d_data_type resource_data_type)
+ enum vsir_data_type resource_data_type)
{
struct vkd3d_shader_scan_descriptor_info1 *info = context->scan_descriptor_info;
struct vkd3d_shader_descriptor_info1 *d;
@@ -1097,7 +1175,7 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc
struct vkd3d_shader_descriptor_info1 *d;
if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV,
- &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT)))
+ &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32)))
return;
d->buffer_size = cb->size;
}
@@ -1109,7 +1187,7 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte
struct vkd3d_shader_descriptor_info1 *d;
if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER,
- &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UNUSED)))
+ &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED)))
return;
if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE)
@@ -1120,9 +1198,9 @@ static void vkd3d_shader_scan_combined_sampler_declaration(
struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_semantic *semantic)
{
vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &semantic->resource.reg.reg,
- &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UNUSED);
+ &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED);
vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, &semantic->resource.reg.reg,
- &semantic->resource.range, semantic->resource_type, VKD3D_DATA_FLOAT);
+ &semantic->resource.range, semantic->resource_type, VSIR_DATA_F32);
}
const struct vkd3d_shader_descriptor_info1 *vkd3d_shader_find_descriptor(
@@ -1210,9 +1288,43 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co
s->sampler_index = sampler_idx;
}
+static void vkd3d_shader_scan_sample_instruction(struct vkd3d_shader_scan_context *context,
+ const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register *sampler)
+{
+ unsigned int resource_idx = resource->idx[0].offset;
+ unsigned int sampler_idx = sampler->idx[0].offset;
+
+ vkd3d_shader_scan_combined_sampler_usage(context, resource, sampler);
+
+ if (!context->scan_descriptor_info)
+ return;
+
+ /* Sample instructions lowered from 1.x texture instructions have no
+ * DCL, so we need to add the resource if it didn't already exist.
+ * Such descriptors have a fixed count, type, etc. */
+
+ if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info,
+ VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_idx))
+ {
+ struct vkd3d_shader_register_range range = {.first = resource_idx, .last = resource_idx};
+
+ vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource,
+ &range, VKD3D_SHADER_RESOURCE_TEXTURE_2D, VSIR_DATA_F32);
+ }
+
+ if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info,
+ VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_idx))
+ {
+ struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx};
+
+ vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, resource,
+ &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED);
+ }
+}
+
static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context,
const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type,
- enum vkd3d_data_type resource_data_type, unsigned int sample_count,
+ enum vsir_data_type resource_data_type, unsigned int sample_count,
unsigned int structure_stride, bool raw, uint32_t flags)
{
struct vkd3d_shader_descriptor_info1 *d;
@@ -1260,13 +1372,13 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
switch (instruction->opcode)
{
- case VKD3DSIH_DCL_CONSTANT_BUFFER:
+ case VSIR_OP_DCL_CONSTANT_BUFFER:
vkd3d_shader_scan_constant_buffer_declaration(context, instruction);
break;
- case VKD3DSIH_DCL_SAMPLER:
+ case VSIR_OP_DCL_SAMPLER:
vkd3d_shader_scan_sampler_declaration(context, instruction);
break;
- case VKD3DSIH_DCL:
+ case VSIR_OP_DCL:
if (instruction->declaration.semantic.resource_type == VKD3D_SHADER_RESOURCE_NONE)
break;
@@ -1276,33 +1388,33 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
break;
}
/* fall through */
- case VKD3DSIH_DCL_UAV_TYPED:
+ case VSIR_OP_DCL_UAV_TYPED:
vkd3d_shader_scan_typed_resource_declaration(context, instruction);
break;
- case VKD3DSIH_DCL_RESOURCE_RAW:
- case VKD3DSIH_DCL_UAV_RAW:
+ case VSIR_OP_DCL_RESOURCE_RAW:
+ case VSIR_OP_DCL_UAV_RAW:
vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.raw_resource.resource,
- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, 0, true, instruction->flags);
+ VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32, 0, 0, true, instruction->flags);
break;
- case VKD3DSIH_DCL_RESOURCE_STRUCTURED:
- case VKD3DSIH_DCL_UAV_STRUCTURED:
+ case VSIR_OP_DCL_RESOURCE_STRUCTURED:
+ case VSIR_OP_DCL_UAV_STRUCTURED:
vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.structured_resource.resource,
- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0,
+ VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32, 0,
instruction->declaration.structured_resource.byte_stride, false, instruction->flags);
break;
- case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE:
+ case VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE:
context->output_primitive = instruction->declaration.tessellator_output_primitive;
break;
- case VKD3DSIH_DCL_TESSELLATOR_PARTITIONING:
+ case VSIR_OP_DCL_TESSELLATOR_PARTITIONING:
context->partitioning = instruction->declaration.tessellator_partitioning;
break;
- case VKD3DSIH_IF:
- case VKD3DSIH_IFC:
+ case VSIR_OP_IF:
+ case VSIR_OP_IFC:
cf_info = vkd3d_shader_scan_push_cf_info(context);
cf_info->type = VKD3D_SHADER_BLOCK_IF;
cf_info->inside_block = true;
break;
- case VKD3DSIH_ELSE:
+ case VSIR_OP_ELSE:
if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_IF)
{
vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
@@ -1311,7 +1423,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
}
cf_info->inside_block = true;
break;
- case VKD3DSIH_ENDIF:
+ case VSIR_OP_ENDIF:
if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_IF)
{
vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
@@ -1320,12 +1432,12 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
}
vkd3d_shader_scan_pop_cf_info(context);
break;
- case VKD3DSIH_LOOP:
+ case VSIR_OP_LOOP:
cf_info = vkd3d_shader_scan_push_cf_info(context);
cf_info->type = VKD3D_SHADER_BLOCK_LOOP;
cf_info->inside_block = true;
break;
- case VKD3DSIH_ENDLOOP:
+ case VSIR_OP_ENDLOOP:
if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_LOOP)
{
vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
@@ -1334,11 +1446,11 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
}
vkd3d_shader_scan_pop_cf_info(context);
break;
- case VKD3DSIH_SWITCH:
+ case VSIR_OP_SWITCH:
cf_info = vkd3d_shader_scan_push_cf_info(context);
cf_info->type = VKD3D_SHADER_BLOCK_SWITCH;
break;
- case VKD3DSIH_ENDSWITCH:
+ case VSIR_OP_ENDSWITCH:
if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context))
|| cf_info->type != VKD3D_SHADER_BLOCK_SWITCH || cf_info->inside_block)
{
@@ -1348,7 +1460,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
}
vkd3d_shader_scan_pop_cf_info(context);
break;
- case VKD3DSIH_CASE:
+ case VSIR_OP_CASE:
if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context))
|| cf_info->type != VKD3D_SHADER_BLOCK_SWITCH)
{
@@ -1358,7 +1470,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
}
cf_info->inside_block = true;
break;
- case VKD3DSIH_DEFAULT:
+ case VSIR_OP_DEFAULT:
if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context))
|| cf_info->type != VKD3D_SHADER_BLOCK_SWITCH)
{
@@ -1375,7 +1487,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
cf_info->inside_block = true;
cf_info->has_default = true;
break;
- case VKD3DSIH_BREAK:
+ case VSIR_OP_BREAK:
if (!(cf_info = vkd3d_shader_scan_find_innermost_breakable_cf_info(context)))
{
vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
@@ -1384,7 +1496,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
}
cf_info->inside_block = false;
break;
- case VKD3DSIH_BREAKP:
+ case VSIR_OP_BREAKP:
if (!(cf_info = vkd3d_shader_scan_find_innermost_loop_cf_info(context)))
{
vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
@@ -1392,7 +1504,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
return VKD3D_ERROR_INVALID_SHADER;
}
break;
- case VKD3DSIH_CONTINUE:
+ case VSIR_OP_CONTINUE:
if (!(cf_info = vkd3d_shader_scan_find_innermost_loop_cf_info(context)))
{
vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
@@ -1401,7 +1513,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
}
cf_info->inside_block = false;
break;
- case VKD3DSIH_CONTINUEP:
+ case VSIR_OP_CONTINUEP:
if (!(cf_info = vkd3d_shader_scan_find_innermost_loop_cf_info(context)))
{
vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF,
@@ -1409,59 +1521,55 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
return VKD3D_ERROR_INVALID_SHADER;
}
break;
- case VKD3DSIH_RET:
+ case VSIR_OP_RET:
if (context->cf_info_count)
context->cf_info[context->cf_info_count - 1].inside_block = false;
break;
- case VKD3DSIH_TEX:
- if (context->version->major == 1)
- sampler_reg = &instruction->dst[0].reg;
- else
- sampler_reg = &instruction->src[1].reg;
- vkd3d_shader_scan_combined_sampler_usage(context, sampler_reg, sampler_reg);
- break;
- case VKD3DSIH_TEXBEM:
- case VKD3DSIH_TEXBEML:
- case VKD3DSIH_TEXDP3TEX:
- case VKD3DSIH_TEXM3x2TEX:
- case VKD3DSIH_TEXM3x3SPEC:
- case VKD3DSIH_TEXM3x3TEX:
- case VKD3DSIH_TEXM3x3VSPEC:
- case VKD3DSIH_TEXREG2AR:
- case VKD3DSIH_TEXREG2GB:
- case VKD3DSIH_TEXREG2RGB:
+ case VSIR_OP_TEX:
+ case VSIR_OP_TEXBEM:
+ case VSIR_OP_TEXBEML:
+ case VSIR_OP_TEXDP3TEX:
+ case VSIR_OP_TEXM3x2TEX:
+ case VSIR_OP_TEXM3x3SPEC:
+ case VSIR_OP_TEXM3x3TEX:
+ case VSIR_OP_TEXM3x3VSPEC:
+ case VSIR_OP_TEXREG2AR:
+ case VSIR_OP_TEXREG2GB:
+ case VSIR_OP_TEXREG2RGB:
sampler_reg = &instruction->dst[0].reg;
vkd3d_shader_scan_combined_sampler_usage(context, sampler_reg, sampler_reg);
break;
- case VKD3DSIH_GATHER4:
- case VKD3DSIH_GATHER4_C:
- case VKD3DSIH_SAMPLE:
- case VKD3DSIH_SAMPLE_B:
- case VKD3DSIH_SAMPLE_C:
- case VKD3DSIH_SAMPLE_C_LZ:
- case VKD3DSIH_SAMPLE_GRAD:
- case VKD3DSIH_SAMPLE_LOD:
+ case VSIR_OP_GATHER4:
+ case VSIR_OP_GATHER4_C:
+ case VSIR_OP_SAMPLE_B:
+ case VSIR_OP_SAMPLE_C:
+ case VSIR_OP_SAMPLE_C_LZ:
+ case VSIR_OP_SAMPLE_GRAD:
+ case VSIR_OP_SAMPLE_LOD:
vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, &instruction->src[2].reg);
break;
- case VKD3DSIH_GATHER4_PO:
- case VKD3DSIH_GATHER4_PO_C:
+ case VSIR_OP_SAMPLE:
+ vkd3d_shader_scan_sample_instruction(context, &instruction->src[1].reg, &instruction->src[2].reg);
+ break;
+ case VSIR_OP_GATHER4_PO:
+ case VSIR_OP_GATHER4_PO_C:
vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[2].reg, &instruction->src[3].reg);
break;
- case VKD3DSIH_LD:
- case VKD3DSIH_LD2DMS:
+ case VSIR_OP_LD:
+ case VSIR_OP_LD2DMS:
vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, NULL);
break;
- case VKD3DSIH_BUFINFO:
- case VKD3DSIH_SAMPLE_INFO:
+ case VSIR_OP_BUFINFO:
+ case VSIR_OP_SAMPLE_INFO:
if (instruction->src[0].reg.type == VKD3DSPR_RESOURCE)
vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[0].reg, NULL);
break;
- case VKD3DSIH_LD_RAW:
- case VKD3DSIH_RESINFO:
+ case VSIR_OP_LD_RAW:
+ case VSIR_OP_RESINFO:
if (instruction->src[1].reg.type == VKD3DSPR_RESOURCE)
vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, NULL);
break;
- case VKD3DSIH_LD_STRUCTURED:
+ case VSIR_OP_LD_STRUCTURED:
if (instruction->src[2].reg.type == VKD3DSPR_RESOURCE)
vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[2].reg, NULL);
break;
@@ -1498,27 +1606,27 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
return VKD3D_OK;
}
-static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_type(enum vkd3d_data_type data_type)
+static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_type(enum vsir_data_type data_type)
{
switch (data_type)
{
- case VKD3D_DATA_UNORM:
- return VKD3D_SHADER_RESOURCE_DATA_UNORM;
- case VKD3D_DATA_SNORM:
- return VKD3D_SHADER_RESOURCE_DATA_SNORM;
- case VKD3D_DATA_INT:
+ case VSIR_DATA_F32:
+ return VKD3D_SHADER_RESOURCE_DATA_FLOAT;
+ case VSIR_DATA_F64:
+ return VKD3D_SHADER_RESOURCE_DATA_DOUBLE;
+ case VSIR_DATA_I32:
return VKD3D_SHADER_RESOURCE_DATA_INT;
- case VKD3D_DATA_UINT:
+ case VSIR_DATA_U32:
return VKD3D_SHADER_RESOURCE_DATA_UINT;
- case VKD3D_DATA_FLOAT:
- return VKD3D_SHADER_RESOURCE_DATA_FLOAT;
- case VKD3D_DATA_MIXED:
+ case VSIR_DATA_SNORM:
+ return VKD3D_SHADER_RESOURCE_DATA_SNORM;
+ case VSIR_DATA_UNORM:
+ return VKD3D_SHADER_RESOURCE_DATA_UNORM;
+ case VSIR_DATA_MIXED:
return VKD3D_SHADER_RESOURCE_DATA_MIXED;
- case VKD3D_DATA_DOUBLE:
- return VKD3D_SHADER_RESOURCE_DATA_DOUBLE;
- case VKD3D_DATA_CONTINUED:
+ case VSIR_DATA_CONTINUED:
return VKD3D_SHADER_RESOURCE_DATA_CONTINUED;
- case VKD3D_DATA_UNUSED:
+ case VSIR_DATA_UNUSED:
return VKD3D_SHADER_RESOURCE_DATA_NONE;
default:
ERR("Invalid resource data type %#x.\n", data_type);
@@ -1574,12 +1682,13 @@ void vkd3d_shader_free_scan_descriptor_info1(struct vkd3d_shader_scan_descriptor
static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_message_context *message_context, bool add_descriptor_info)
{
+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions);
struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info;
struct vkd3d_shader_scan_hull_shader_tessellation_info *tessellation_info;
struct vkd3d_shader_scan_descriptor_info *descriptor_info;
struct vkd3d_shader_scan_signature_info *signature_info;
- struct vkd3d_shader_instruction *instruction;
struct vkd3d_shader_scan_context context;
+ struct vkd3d_shader_instruction *ins;
int ret = VKD3D_OK;
unsigned int i;
@@ -1607,10 +1716,9 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh
if (TRACE_ON())
vsir_program_trace(program);
- for (i = 0; i < program->instructions.count; ++i)
+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it))
{
- instruction = &program->instructions.elements[i];
- if ((ret = vkd3d_shader_scan_instruction(&context, instruction)) < 0)
+ if ((ret = vkd3d_shader_scan_instruction(&context, ins)) < 0)
break;
}
@@ -1623,8 +1731,8 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh
if (size)
{
- if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, &reg,
- &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT)))
+ if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV,
+ &reg, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32)))
d->buffer_size = size * 16;
}
}
@@ -1667,7 +1775,9 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh
int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char **messages)
{
struct vkd3d_shader_message_context message_context;
+ struct vkd3d_shader_code reflection_data = {0};
struct shader_dump_data dump_data;
+ struct vsir_program program;
int ret;
TRACE("compile_info %p, messages %p.\n", compile_info, messages);
@@ -1685,21 +1795,12 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
fill_shader_dump_data(compile_info, &dump_data);
vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, SHADER_DUMP_TYPE_SOURCE);
- if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL)
+ if (!(ret = vsir_parse(compile_info, vkd3d_shader_init_config_flags(),
+ &dump_data, &message_context, &program, &reflection_data)))
{
- FIXME("HLSL support not implemented.\n");
- ret = VKD3D_ERROR_NOT_IMPLEMENTED;
- }
- else
- {
- uint64_t config_flags = vkd3d_shader_init_config_flags();
- struct vsir_program program;
-
- if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program)))
- {
- ret = vsir_program_scan(&program, compile_info, &message_context, false);
- vsir_program_cleanup(&program);
- }
+ ret = vsir_program_scan(&program, compile_info, &message_context, false);
+ vkd3d_shader_free_shader_code(&reflection_data);
+ vsir_program_cleanup(&program);
}
vkd3d_shader_message_context_trace_messages(&message_context);
@@ -1709,12 +1810,13 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
return ret;
}
-int vsir_program_compile(struct vsir_program *program, uint64_t config_flags,
- const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out,
- struct vkd3d_shader_message_context *message_context)
+static int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader_code *reflection_data,
+ uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context)
{
struct vkd3d_shader_scan_combined_resource_sampler_info combined_sampler_info;
struct vkd3d_shader_compile_info scan_info;
+ enum vsir_asm_flags asm_flags;
int ret;
scan_info = *compile_info;
@@ -1722,7 +1824,25 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags,
switch (compile_info->target_type)
{
case VKD3D_SHADER_TARGET_D3D_ASM:
- ret = d3d_asm_compile(program, compile_info, out, VSIR_ASM_FLAG_NONE);
+ if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0)
+ return ret;
+ asm_flags = VSIR_ASM_FLAG_NONE;
+ if (program->shader_version.major < 6 && compile_info->source_type != VKD3D_SHADER_SOURCE_DXBC_TPF
+ && compile_info->source_type != VKD3D_SHADER_SOURCE_D3D_BYTECODE)
+ asm_flags |= VSIR_ASM_FLAG_ALLOCATE_TEMPS;
+ ret = d3d_asm_compile(program, compile_info, out, asm_flags, message_context);
+ break;
+
+ case VKD3D_SHADER_TARGET_D3D_BYTECODE:
+ if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0)
+ return ret;
+ ret = d3dbc_compile(program, config_flags, compile_info, reflection_data, out, message_context);
+ break;
+
+ case VKD3D_SHADER_TARGET_DXBC_TPF:
+ if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0)
+ return ret;
+ ret = tpf_compile(program, config_flags, reflection_data, out, message_context);
break;
case VKD3D_SHADER_TARGET_GLSL:
@@ -1757,10 +1877,11 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags,
return ret;
}
-static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info,
+static int fx_compile(const struct vkd3d_shader_compile_info *compile_info,
const struct shader_dump_data *dump_data, struct vkd3d_shader_code *out,
struct vkd3d_shader_message_context *message_context)
{
+ struct vkd3d_shader_compile_info preprocessed_info;
struct vkd3d_shader_code preprocessed;
int ret;
@@ -1769,7 +1890,9 @@ static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info,
vkd3d_shader_dump_shader(dump_data, preprocessed.code, preprocessed.size, SHADER_DUMP_TYPE_PREPROC);
- ret = hlsl_compile_shader(&preprocessed, compile_info, out, message_context);
+ preprocessed_info = *compile_info;
+ preprocessed_info.source = preprocessed;
+ ret = hlsl_compile_effect(&preprocessed_info, message_context, out);
vkd3d_shader_free_shader_code(&preprocessed);
return ret;
@@ -1797,22 +1920,30 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
fill_shader_dump_data(compile_info, &dump_data);
vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, SHADER_DUMP_TYPE_SOURCE);
- if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL)
+ if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL
+ && compile_info->target_type == VKD3D_SHADER_TARGET_FX)
{
- ret = compile_hlsl(compile_info, &dump_data, out, &message_context);
+ ret = fx_compile(compile_info, &dump_data, out, &message_context);
}
else if (compile_info->source_type == VKD3D_SHADER_SOURCE_FX)
{
ret = fx_parse(compile_info, out, &message_context);
}
+ else if (compile_info->source_type == VKD3D_SHADER_SOURCE_TX)
+ {
+ ret = tx_parse(compile_info, out, &message_context);
+ }
else
{
uint64_t config_flags = vkd3d_shader_init_config_flags();
+ struct vkd3d_shader_code reflection_data = {0};
struct vsir_program program;
- if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program)))
+ if (!(ret = vsir_parse(compile_info, config_flags, &dump_data,
+ &message_context, &program, &reflection_data)))
{
- ret = vsir_program_compile(&program, config_flags, compile_info, out, &message_context);
+ ret = vsir_program_compile(&program, &reflection_data, config_flags, compile_info, out, &message_context);
+ vkd3d_shader_free_shader_code(&reflection_data);
vsir_program_cleanup(&program);
}
}
@@ -2013,6 +2144,7 @@ const enum vkd3d_shader_source_type *vkd3d_shader_get_supported_source_types(uns
VKD3D_SHADER_SOURCE_D3D_BYTECODE,
VKD3D_SHADER_SOURCE_DXBC_DXIL,
VKD3D_SHADER_SOURCE_FX,
+ VKD3D_SHADER_SOURCE_TX,
};
TRACE("count %p.\n", count);
@@ -2070,6 +2202,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types(
VKD3D_SHADER_TARGET_SPIRV_TEXT,
# endif
VKD3D_SHADER_TARGET_D3D_ASM,
+#ifdef VKD3D_SHADER_UNSUPPORTED_MSL
+ VKD3D_SHADER_TARGET_MSL,
+#endif
};
static const enum vkd3d_shader_target_type fx_types[] =
@@ -2077,6 +2212,11 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types(
VKD3D_SHADER_TARGET_D3D_ASM,
};
+ static const enum vkd3d_shader_target_type tx_types[] =
+ {
+ VKD3D_SHADER_TARGET_D3D_ASM,
+ };
+
TRACE("source_type %#x, count %p.\n", source_type, count);
switch (source_type)
@@ -2101,6 +2241,10 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types(
*count = ARRAY_SIZE(fx_types);
return fx_types;
+ case VKD3D_SHADER_SOURCE_TX:
+ *count = ARRAY_SIZE(tx_types);
+ return tx_types;
+
default:
*count = 0;
return NULL;
@@ -2149,7 +2293,7 @@ static struct vkd3d_shader_param_node *shader_param_allocator_node_create(
}
static void shader_param_allocator_init(struct vkd3d_shader_param_allocator *allocator,
- unsigned int count, unsigned int stride)
+ size_t count, size_t stride)
{
allocator->count = max(count, MAX_REG_OUTPUT);
allocator->stride = stride;
@@ -2170,7 +2314,7 @@ static void shader_param_allocator_destroy(struct vkd3d_shader_param_allocator *
}
}
-void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, unsigned int count)
+void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, size_t count)
{
void *params;
@@ -2196,18 +2340,18 @@ void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator,
return params;
}
-bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve)
+bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, size_t reserve)
{
memset(instructions, 0, sizeof(*instructions));
/* Size the parameter initial allocations so they are large enough for most shaders. The
* code path for chained allocations will be tested if a few shaders need to use it. */
shader_param_allocator_init(&instructions->dst_params, reserve - reserve / 8u,
- sizeof(*instructions->elements->dst));
- shader_param_allocator_init(&instructions->src_params, reserve * 2u, sizeof(*instructions->elements->src));
+ sizeof(struct vkd3d_shader_dst_param));
+ shader_param_allocator_init(&instructions->src_params, reserve * 2u, sizeof(struct vkd3d_shader_src_param));
return shader_instruction_array_reserve(instructions, reserve);
}
-bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve)
+bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, size_t reserve)
{
if (!vkd3d_array_reserve((void **)&instructions->elements, &instructions->capacity, reserve,
sizeof(*instructions->elements)))
@@ -2219,7 +2363,7 @@ bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *ins
}
bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions,
- unsigned int idx, unsigned int count)
+ size_t idx, size_t count)
{
VKD3D_ASSERT(idx <= instructions->count);
@@ -2247,7 +2391,7 @@ bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *ins
static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params(
struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_src_param *params,
- unsigned int count);
+ size_t count);
static bool shader_register_clone_relative_addresses(struct vkd3d_shader_register *reg,
struct vkd3d_shader_instruction_array *instructions)
@@ -2268,10 +2412,10 @@ static bool shader_register_clone_relative_addresses(struct vkd3d_shader_registe
static struct vkd3d_shader_dst_param *shader_instruction_array_clone_dst_params(
struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_dst_param *params,
- unsigned int count)
+ size_t count)
{
struct vkd3d_shader_dst_param *dst_params;
- unsigned int i;
+ size_t i;
if (!(dst_params = shader_dst_param_allocator_get(&instructions->dst_params, count)))
return NULL;
@@ -2288,10 +2432,10 @@ static struct vkd3d_shader_dst_param *shader_instruction_array_clone_dst_params(
static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params(
struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_src_param *params,
- unsigned int count)
+ size_t count)
{
struct vkd3d_shader_src_param *src_params;
- unsigned int i;
+ size_t i;
if (!(src_params = shader_src_param_allocator_get(&instructions->src_params, count)))
return NULL;
@@ -2309,7 +2453,7 @@ static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params(
/* NOTE: Immediate constant buffers are not cloned, so the source must not be destroyed while the
* destination is in use. This seems like a reasonable requirement given how this is currently used. */
bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions,
- unsigned int dst, unsigned int src)
+ size_t dst, size_t src)
{
struct vkd3d_shader_instruction *ins = &instructions->elements[dst];
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index 3b4fb626fcc..e758c16b3d4 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -174,6 +174,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT = 5042,
VKD3D_SHADER_ERROR_HLSL_MISSING_PRIMITIVE_TYPE = 5043,
VKD3D_SHADER_ERROR_HLSL_MISPLACED_STREAM_OUTPUT = 5044,
+ VKD3D_SHADER_ERROR_HLSL_MISSING_INPUT_PATCH = 5045,
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300,
VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301,
@@ -182,6 +183,8 @@ enum vkd3d_shader_error
VKD3D_SHADER_WARNING_HLSL_NON_FINITE_RESULT = 5304,
VKD3D_SHADER_WARNING_HLSL_IGNORED_ATTRIBUTE = 5305,
VKD3D_SHADER_WARNING_HLSL_IGNORED_DEFAULT_VALUE = 5306,
+ VKD3D_SHADER_WARNING_HLSL_IGNORED_MODIFIER = 5307,
+ VKD3D_SHADER_WARNING_HLSL_OVERRIDDEN_SEMANTIC = 5308,
VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000,
VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND = 6001,
@@ -222,6 +225,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES = 8017,
VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES = 8018,
VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCE_HANDLE = 8019,
+ VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT = 8020,
VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER = 8300,
VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE = 8301,
@@ -236,7 +240,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_WARNING_DXIL_UNDEFINED_OPERAND = 8310,
VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000,
- VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER = 9001,
+ VKD3D_SHADER_ERROR_VSIR_INVALID_OPCODE = 9001,
VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE = 9002,
VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK = 9003,
VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS = 9004,
@@ -262,6 +266,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_TYPE = 9024,
VKD3D_SHADER_ERROR_VSIR_INVALID_RESOURCE_TYPE = 9025,
VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_COUNT = 9026,
+ VKD3D_SHADER_ERROR_VSIR_INVALID_FLAGS = 9027,
VKD3D_SHADER_WARNING_VSIR_DYNAMIC_DESCRIPTOR_ARRAY = 9300,
@@ -278,334 +283,345 @@ enum vkd3d_shader_error
enum vkd3d_shader_opcode
{
- VKD3DSIH_ABS,
- VKD3DSIH_ACOS,
- VKD3DSIH_ADD,
- VKD3DSIH_AND,
- VKD3DSIH_ASIN,
- VKD3DSIH_ATAN,
- VKD3DSIH_ATOMIC_AND,
- VKD3DSIH_ATOMIC_CMP_STORE,
- VKD3DSIH_ATOMIC_IADD,
- VKD3DSIH_ATOMIC_IMAX,
- VKD3DSIH_ATOMIC_IMIN,
- VKD3DSIH_ATOMIC_OR,
- VKD3DSIH_ATOMIC_UMAX,
- VKD3DSIH_ATOMIC_UMIN,
- VKD3DSIH_ATOMIC_XOR,
- VKD3DSIH_BEM,
- VKD3DSIH_BFI,
- VKD3DSIH_BFREV,
- VKD3DSIH_BRANCH,
- VKD3DSIH_BREAK,
- VKD3DSIH_BREAKC,
- VKD3DSIH_BREAKP,
- VKD3DSIH_BUFINFO,
- VKD3DSIH_CALL,
- VKD3DSIH_CALLNZ,
- VKD3DSIH_CASE,
- VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED,
- VKD3DSIH_CMP,
- VKD3DSIH_CND,
- VKD3DSIH_CONTINUE,
- VKD3DSIH_CONTINUEP,
- VKD3DSIH_COUNTBITS,
- VKD3DSIH_CRS,
- VKD3DSIH_CUT,
- VKD3DSIH_CUT_STREAM,
- VKD3DSIH_DADD,
- VKD3DSIH_DCL,
- VKD3DSIH_DCL_CONSTANT_BUFFER,
- VKD3DSIH_DCL_FUNCTION_BODY,
- VKD3DSIH_DCL_FUNCTION_TABLE,
- VKD3DSIH_DCL_GLOBAL_FLAGS,
- VKD3DSIH_DCL_GS_INSTANCES,
- VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT,
- VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT,
- VKD3DSIH_DCL_HS_MAX_TESSFACTOR,
- VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER,
- VKD3DSIH_DCL_INDEX_RANGE,
- VKD3DSIH_DCL_INDEXABLE_TEMP,
- VKD3DSIH_DCL_INPUT,
- VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT,
- VKD3DSIH_DCL_INPUT_PRIMITIVE,
- VKD3DSIH_DCL_INPUT_PS,
- VKD3DSIH_DCL_INPUT_PS_SGV,
- VKD3DSIH_DCL_INPUT_PS_SIV,
- VKD3DSIH_DCL_INPUT_SGV,
- VKD3DSIH_DCL_INPUT_SIV,
- VKD3DSIH_DCL_INTERFACE,
- VKD3DSIH_DCL_OUTPUT,
- VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT,
- VKD3DSIH_DCL_OUTPUT_SIV,
- VKD3DSIH_DCL_OUTPUT_TOPOLOGY,
- VKD3DSIH_DCL_RESOURCE_RAW,
- VKD3DSIH_DCL_RESOURCE_STRUCTURED,
- VKD3DSIH_DCL_SAMPLER,
- VKD3DSIH_DCL_STREAM,
- VKD3DSIH_DCL_TEMPS,
- VKD3DSIH_DCL_TESSELLATOR_DOMAIN,
- VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE,
- VKD3DSIH_DCL_TESSELLATOR_PARTITIONING,
- VKD3DSIH_DCL_TGSM_RAW,
- VKD3DSIH_DCL_TGSM_STRUCTURED,
- VKD3DSIH_DCL_THREAD_GROUP,
- VKD3DSIH_DCL_UAV_RAW,
- VKD3DSIH_DCL_UAV_STRUCTURED,
- VKD3DSIH_DCL_UAV_TYPED,
- VKD3DSIH_DCL_VERTICES_OUT,
- VKD3DSIH_DDIV,
- VKD3DSIH_DEF,
- VKD3DSIH_DEFAULT,
- VKD3DSIH_DEFB,
- VKD3DSIH_DEFI,
- VKD3DSIH_DEQO,
- VKD3DSIH_DFMA,
- VKD3DSIH_DGEO,
- VKD3DSIH_DISCARD,
- VKD3DSIH_DIV,
- VKD3DSIH_DLT,
- VKD3DSIH_DMAX,
- VKD3DSIH_DMIN,
- VKD3DSIH_DMOV,
- VKD3DSIH_DMOVC,
- VKD3DSIH_DMUL,
- VKD3DSIH_DNE,
- VKD3DSIH_DP2,
- VKD3DSIH_DP2ADD,
- VKD3DSIH_DP3,
- VKD3DSIH_DP4,
- VKD3DSIH_DRCP,
- VKD3DSIH_DST,
- VKD3DSIH_DSX,
- VKD3DSIH_DSX_COARSE,
- VKD3DSIH_DSX_FINE,
- VKD3DSIH_DSY,
- VKD3DSIH_DSY_COARSE,
- VKD3DSIH_DSY_FINE,
- VKD3DSIH_DTOF,
- VKD3DSIH_DTOI,
- VKD3DSIH_DTOU,
- VKD3DSIH_ELSE,
- VKD3DSIH_EMIT,
- VKD3DSIH_EMIT_STREAM,
- VKD3DSIH_ENDIF,
- VKD3DSIH_ENDLOOP,
- VKD3DSIH_ENDREP,
- VKD3DSIH_ENDSWITCH,
- VKD3DSIH_EQO,
- VKD3DSIH_EQU,
- VKD3DSIH_EVAL_CENTROID,
- VKD3DSIH_EVAL_SAMPLE_INDEX,
- VKD3DSIH_EXP,
- VKD3DSIH_EXPP,
- VKD3DSIH_F16TOF32,
- VKD3DSIH_F32TOF16,
- VKD3DSIH_FCALL,
- VKD3DSIH_FIRSTBIT_HI,
- VKD3DSIH_FIRSTBIT_LO,
- VKD3DSIH_FIRSTBIT_SHI,
- VKD3DSIH_FRC,
- VKD3DSIH_FREM,
- VKD3DSIH_FTOD,
- VKD3DSIH_FTOI,
- VKD3DSIH_FTOU,
- VKD3DSIH_GATHER4,
- VKD3DSIH_GATHER4_C,
- VKD3DSIH_GATHER4_C_S,
- VKD3DSIH_GATHER4_PO,
- VKD3DSIH_GATHER4_PO_C,
- VKD3DSIH_GATHER4_PO_C_S,
- VKD3DSIH_GATHER4_PO_S,
- VKD3DSIH_GATHER4_S,
- VKD3DSIH_GEO,
- VKD3DSIH_GEU,
- VKD3DSIH_HCOS,
- VKD3DSIH_HS_CONTROL_POINT_PHASE,
- VKD3DSIH_HS_DECLS,
- VKD3DSIH_HS_FORK_PHASE,
- VKD3DSIH_HS_JOIN_PHASE,
- VKD3DSIH_HSIN,
- VKD3DSIH_HTAN,
- VKD3DSIH_IADD,
- VKD3DSIH_IBFE,
- VKD3DSIH_IDIV,
- VKD3DSIH_IEQ,
- VKD3DSIH_IF,
- VKD3DSIH_IFC,
- VKD3DSIH_IGE,
- VKD3DSIH_ILT,
- VKD3DSIH_IMAD,
- VKD3DSIH_IMAX,
- VKD3DSIH_IMIN,
- VKD3DSIH_IMM_ATOMIC_ALLOC,
- VKD3DSIH_IMM_ATOMIC_AND,
- VKD3DSIH_IMM_ATOMIC_CMP_EXCH,
- VKD3DSIH_IMM_ATOMIC_CONSUME,
- VKD3DSIH_IMM_ATOMIC_EXCH,
- VKD3DSIH_IMM_ATOMIC_IADD,
- VKD3DSIH_IMM_ATOMIC_IMAX,
- VKD3DSIH_IMM_ATOMIC_IMIN,
- VKD3DSIH_IMM_ATOMIC_OR,
- VKD3DSIH_IMM_ATOMIC_UMAX,
- VKD3DSIH_IMM_ATOMIC_UMIN,
- VKD3DSIH_IMM_ATOMIC_XOR,
- VKD3DSIH_IMUL,
- VKD3DSIH_INE,
- VKD3DSIH_INEG,
- VKD3DSIH_ISFINITE,
- VKD3DSIH_ISHL,
- VKD3DSIH_ISHR,
- VKD3DSIH_ISINF,
- VKD3DSIH_ISNAN,
- VKD3DSIH_ITOD,
- VKD3DSIH_ITOF,
- VKD3DSIH_ITOI,
- VKD3DSIH_LABEL,
- VKD3DSIH_LD,
- VKD3DSIH_LD2DMS,
- VKD3DSIH_LD2DMS_S,
- VKD3DSIH_LD_RAW,
- VKD3DSIH_LD_RAW_S,
- VKD3DSIH_LD_S,
- VKD3DSIH_LD_STRUCTURED,
- VKD3DSIH_LD_STRUCTURED_S,
- VKD3DSIH_LD_UAV_TYPED,
- VKD3DSIH_LD_UAV_TYPED_S,
- VKD3DSIH_LIT,
- VKD3DSIH_LOD,
- VKD3DSIH_LOG,
- VKD3DSIH_LOGP,
- VKD3DSIH_LOOP,
- VKD3DSIH_LRP,
- VKD3DSIH_LTO,
- VKD3DSIH_LTU,
- VKD3DSIH_M3x2,
- VKD3DSIH_M3x3,
- VKD3DSIH_M3x4,
- VKD3DSIH_M4x3,
- VKD3DSIH_M4x4,
- VKD3DSIH_MAD,
- VKD3DSIH_MAX,
- VKD3DSIH_MIN,
- VKD3DSIH_MOV,
- VKD3DSIH_MOVA,
- VKD3DSIH_MOVC,
- VKD3DSIH_MSAD,
- VKD3DSIH_MUL,
- VKD3DSIH_NEO,
- VKD3DSIH_NEU,
- VKD3DSIH_NOP,
- VKD3DSIH_NOT,
- VKD3DSIH_NRM,
- VKD3DSIH_OR,
- VKD3DSIH_ORD,
- VKD3DSIH_PHASE,
- VKD3DSIH_PHI,
- VKD3DSIH_POW,
- VKD3DSIH_QUAD_READ_ACROSS_D,
- VKD3DSIH_QUAD_READ_ACROSS_X,
- VKD3DSIH_QUAD_READ_ACROSS_Y,
- VKD3DSIH_QUAD_READ_LANE_AT,
- VKD3DSIH_RCP,
- VKD3DSIH_REP,
- VKD3DSIH_RESINFO,
- VKD3DSIH_RET,
- VKD3DSIH_RETP,
- VKD3DSIH_ROUND_NE,
- VKD3DSIH_ROUND_NI,
- VKD3DSIH_ROUND_PI,
- VKD3DSIH_ROUND_Z,
- VKD3DSIH_RSQ,
- VKD3DSIH_SAMPLE,
- VKD3DSIH_SAMPLE_B,
- VKD3DSIH_SAMPLE_B_CL_S,
- VKD3DSIH_SAMPLE_C,
- VKD3DSIH_SAMPLE_C_CL_S,
- VKD3DSIH_SAMPLE_C_LZ,
- VKD3DSIH_SAMPLE_C_LZ_S,
- VKD3DSIH_SAMPLE_CL_S,
- VKD3DSIH_SAMPLE_GRAD,
- VKD3DSIH_SAMPLE_GRAD_CL_S,
- VKD3DSIH_SAMPLE_INFO,
- VKD3DSIH_SAMPLE_LOD,
- VKD3DSIH_SAMPLE_LOD_S,
- VKD3DSIH_SAMPLE_POS,
- VKD3DSIH_SETP,
- VKD3DSIH_SGE,
- VKD3DSIH_SGN,
- VKD3DSIH_SINCOS,
- VKD3DSIH_SLT,
- VKD3DSIH_SQRT,
- VKD3DSIH_STORE_RAW,
- VKD3DSIH_STORE_STRUCTURED,
- VKD3DSIH_STORE_UAV_TYPED,
- VKD3DSIH_SUB,
- VKD3DSIH_SWAPC,
- VKD3DSIH_SWITCH,
- VKD3DSIH_SWITCH_MONOLITHIC,
- VKD3DSIH_SYNC,
- VKD3DSIH_TAN,
- VKD3DSIH_TEX,
- VKD3DSIH_TEXBEM,
- VKD3DSIH_TEXBEML,
- VKD3DSIH_TEXCOORD,
- VKD3DSIH_TEXDEPTH,
- VKD3DSIH_TEXDP3,
- VKD3DSIH_TEXDP3TEX,
- VKD3DSIH_TEXKILL,
- VKD3DSIH_TEXLDD,
- VKD3DSIH_TEXLDL,
- VKD3DSIH_TEXM3x2DEPTH,
- VKD3DSIH_TEXM3x2PAD,
- VKD3DSIH_TEXM3x2TEX,
- VKD3DSIH_TEXM3x3,
- VKD3DSIH_TEXM3x3DIFF,
- VKD3DSIH_TEXM3x3PAD,
- VKD3DSIH_TEXM3x3SPEC,
- VKD3DSIH_TEXM3x3TEX,
- VKD3DSIH_TEXM3x3VSPEC,
- VKD3DSIH_TEXREG2AR,
- VKD3DSIH_TEXREG2GB,
- VKD3DSIH_TEXREG2RGB,
- VKD3DSIH_UBFE,
- VKD3DSIH_UDIV,
- VKD3DSIH_UGE,
- VKD3DSIH_ULT,
- VKD3DSIH_UMAX,
- VKD3DSIH_UMIN,
- VKD3DSIH_UMUL,
- VKD3DSIH_UNO,
- VKD3DSIH_USHR,
- VKD3DSIH_UTOD,
- VKD3DSIH_UTOF,
- VKD3DSIH_UTOU,
- VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL,
- VKD3DSIH_WAVE_ACTIVE_BALLOT,
- VKD3DSIH_WAVE_ACTIVE_BIT_AND,
- VKD3DSIH_WAVE_ACTIVE_BIT_OR,
- VKD3DSIH_WAVE_ACTIVE_BIT_XOR,
- VKD3DSIH_WAVE_ALL_BIT_COUNT,
- VKD3DSIH_WAVE_ALL_TRUE,
- VKD3DSIH_WAVE_ANY_TRUE,
- VKD3DSIH_WAVE_IS_FIRST_LANE,
- VKD3DSIH_WAVE_OP_ADD,
- VKD3DSIH_WAVE_OP_IMAX,
- VKD3DSIH_WAVE_OP_IMIN,
- VKD3DSIH_WAVE_OP_MAX,
- VKD3DSIH_WAVE_OP_MIN,
- VKD3DSIH_WAVE_OP_MUL,
- VKD3DSIH_WAVE_OP_UMAX,
- VKD3DSIH_WAVE_OP_UMIN,
- VKD3DSIH_WAVE_PREFIX_BIT_COUNT,
- VKD3DSIH_WAVE_READ_LANE_AT,
- VKD3DSIH_WAVE_READ_LANE_FIRST,
- VKD3DSIH_XOR,
-
- VKD3DSIH_INVALID,
-
- VKD3DSIH_COUNT,
-};
+ VSIR_OP_ABS,
+ VSIR_OP_ACOS,
+ VSIR_OP_ADD,
+ VSIR_OP_AND,
+ VSIR_OP_ASIN,
+ VSIR_OP_ATAN,
+ VSIR_OP_ATOMIC_AND,
+ VSIR_OP_ATOMIC_CMP_STORE,
+ VSIR_OP_ATOMIC_IADD,
+ VSIR_OP_ATOMIC_IMAX,
+ VSIR_OP_ATOMIC_IMIN,
+ VSIR_OP_ATOMIC_OR,
+ VSIR_OP_ATOMIC_UMAX,
+ VSIR_OP_ATOMIC_UMIN,
+ VSIR_OP_ATOMIC_XOR,
+ VSIR_OP_BEM,
+ VSIR_OP_BFI,
+ VSIR_OP_BFREV,
+ VSIR_OP_BRANCH,
+ VSIR_OP_BREAK,
+ VSIR_OP_BREAKC,
+ VSIR_OP_BREAKP,
+ VSIR_OP_BUFINFO,
+ VSIR_OP_CALL,
+ VSIR_OP_CALLNZ,
+ VSIR_OP_CASE,
+ VSIR_OP_CHECK_ACCESS_FULLY_MAPPED,
+ VSIR_OP_CMP,
+ VSIR_OP_CND,
+ VSIR_OP_CONTINUE,
+ VSIR_OP_CONTINUEP,
+ VSIR_OP_COS,
+ VSIR_OP_COUNTBITS,
+ VSIR_OP_CRS,
+ VSIR_OP_CUT,
+ VSIR_OP_CUT_STREAM,
+ VSIR_OP_DADD,
+ VSIR_OP_DCL,
+ VSIR_OP_DCL_CONSTANT_BUFFER,
+ VSIR_OP_DCL_FUNCTION_BODY,
+ VSIR_OP_DCL_FUNCTION_TABLE,
+ VSIR_OP_DCL_GLOBAL_FLAGS,
+ VSIR_OP_DCL_GS_INSTANCES,
+ VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT,
+ VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT,
+ VSIR_OP_DCL_HS_MAX_TESSFACTOR,
+ VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER,
+ VSIR_OP_DCL_INDEX_RANGE,
+ VSIR_OP_DCL_INDEXABLE_TEMP,
+ VSIR_OP_DCL_INPUT,
+ VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT,
+ VSIR_OP_DCL_INPUT_PRIMITIVE,
+ VSIR_OP_DCL_INPUT_PS,
+ VSIR_OP_DCL_INPUT_PS_SGV,
+ VSIR_OP_DCL_INPUT_PS_SIV,
+ VSIR_OP_DCL_INPUT_SGV,
+ VSIR_OP_DCL_INPUT_SIV,
+ VSIR_OP_DCL_INTERFACE,
+ VSIR_OP_DCL_OUTPUT,
+ VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT,
+ VSIR_OP_DCL_OUTPUT_SGV,
+ VSIR_OP_DCL_OUTPUT_SIV,
+ VSIR_OP_DCL_OUTPUT_TOPOLOGY,
+ VSIR_OP_DCL_RESOURCE_RAW,
+ VSIR_OP_DCL_RESOURCE_STRUCTURED,
+ VSIR_OP_DCL_SAMPLER,
+ VSIR_OP_DCL_STREAM,
+ VSIR_OP_DCL_TEMPS,
+ VSIR_OP_DCL_TESSELLATOR_DOMAIN,
+ VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE,
+ VSIR_OP_DCL_TESSELLATOR_PARTITIONING,
+ VSIR_OP_DCL_TGSM_RAW,
+ VSIR_OP_DCL_TGSM_STRUCTURED,
+ VSIR_OP_DCL_THREAD_GROUP,
+ VSIR_OP_DCL_UAV_RAW,
+ VSIR_OP_DCL_UAV_STRUCTURED,
+ VSIR_OP_DCL_UAV_TYPED,
+ VSIR_OP_DCL_VERTICES_OUT,
+ VSIR_OP_DDIV,
+ VSIR_OP_DEF,
+ VSIR_OP_DEFAULT,
+ VSIR_OP_DEFB,
+ VSIR_OP_DEFI,
+ VSIR_OP_DEQO,
+ VSIR_OP_DFMA,
+ VSIR_OP_DGEO,
+ VSIR_OP_DISCARD,
+ VSIR_OP_DIV,
+ VSIR_OP_DLT,
+ VSIR_OP_DMAX,
+ VSIR_OP_DMIN,
+ VSIR_OP_DMOV,
+ VSIR_OP_DMOVC,
+ VSIR_OP_DMUL,
+ VSIR_OP_DNE,
+ VSIR_OP_DP2,
+ VSIR_OP_DP2ADD,
+ VSIR_OP_DP3,
+ VSIR_OP_DP4,
+ VSIR_OP_DRCP,
+ VSIR_OP_DST,
+ VSIR_OP_DSX,
+ VSIR_OP_DSX_COARSE,
+ VSIR_OP_DSX_FINE,
+ VSIR_OP_DSY,
+ VSIR_OP_DSY_COARSE,
+ VSIR_OP_DSY_FINE,
+ VSIR_OP_DTOF,
+ VSIR_OP_DTOI,
+ VSIR_OP_DTOU,
+ VSIR_OP_ELSE,
+ VSIR_OP_EMIT,
+ VSIR_OP_EMIT_STREAM,
+ VSIR_OP_ENDIF,
+ VSIR_OP_ENDLOOP,
+ VSIR_OP_ENDREP,
+ VSIR_OP_ENDSWITCH,
+ VSIR_OP_EQO,
+ VSIR_OP_EQU,
+ VSIR_OP_EVAL_CENTROID,
+ VSIR_OP_EVAL_SAMPLE_INDEX,
+ VSIR_OP_EXP,
+ VSIR_OP_EXPP,
+ VSIR_OP_F16TOF32,
+ VSIR_OP_F32TOF16,
+ VSIR_OP_FCALL,
+ VSIR_OP_FIRSTBIT_HI,
+ VSIR_OP_FIRSTBIT_LO,
+ VSIR_OP_FIRSTBIT_SHI,
+ VSIR_OP_FRC,
+ VSIR_OP_FREM,
+ VSIR_OP_FTOD,
+ VSIR_OP_FTOI,
+ VSIR_OP_FTOU,
+ VSIR_OP_GATHER4,
+ VSIR_OP_GATHER4_C,
+ VSIR_OP_GATHER4_C_S,
+ VSIR_OP_GATHER4_PO,
+ VSIR_OP_GATHER4_PO_C,
+ VSIR_OP_GATHER4_PO_C_S,
+ VSIR_OP_GATHER4_PO_S,
+ VSIR_OP_GATHER4_S,
+ VSIR_OP_GEO,
+ VSIR_OP_GEU,
+ VSIR_OP_HCOS,
+ VSIR_OP_HS_CONTROL_POINT_PHASE,
+ VSIR_OP_HS_DECLS,
+ VSIR_OP_HS_FORK_PHASE,
+ VSIR_OP_HS_JOIN_PHASE,
+ VSIR_OP_HSIN,
+ VSIR_OP_HTAN,
+ VSIR_OP_IADD,
+ VSIR_OP_IBFE,
+ VSIR_OP_IDIV,
+ VSIR_OP_IEQ,
+ VSIR_OP_IF,
+ VSIR_OP_IFC,
+ VSIR_OP_IGE,
+ VSIR_OP_ILT,
+ VSIR_OP_IMAD,
+ VSIR_OP_IMAX,
+ VSIR_OP_IMIN,
+ VSIR_OP_IMM_ATOMIC_ALLOC,
+ VSIR_OP_IMM_ATOMIC_AND,
+ VSIR_OP_IMM_ATOMIC_CMP_EXCH,
+ VSIR_OP_IMM_ATOMIC_CONSUME,
+ VSIR_OP_IMM_ATOMIC_EXCH,
+ VSIR_OP_IMM_ATOMIC_IADD,
+ VSIR_OP_IMM_ATOMIC_IMAX,
+ VSIR_OP_IMM_ATOMIC_IMIN,
+ VSIR_OP_IMM_ATOMIC_OR,
+ VSIR_OP_IMM_ATOMIC_UMAX,
+ VSIR_OP_IMM_ATOMIC_UMIN,
+ VSIR_OP_IMM_ATOMIC_XOR,
+ VSIR_OP_IMUL,
+ VSIR_OP_IMUL_LOW,
+ VSIR_OP_INE,
+ VSIR_OP_INEG,
+ VSIR_OP_IREM,
+ VSIR_OP_ISFINITE,
+ VSIR_OP_ISHL,
+ VSIR_OP_ISHR,
+ VSIR_OP_ISINF,
+ VSIR_OP_ISNAN,
+ VSIR_OP_ITOD,
+ VSIR_OP_ITOF,
+ VSIR_OP_ITOI,
+ VSIR_OP_LABEL,
+ VSIR_OP_LD,
+ VSIR_OP_LD2DMS,
+ VSIR_OP_LD2DMS_S,
+ VSIR_OP_LD_RAW,
+ VSIR_OP_LD_RAW_S,
+ VSIR_OP_LD_S,
+ VSIR_OP_LD_STRUCTURED,
+ VSIR_OP_LD_STRUCTURED_S,
+ VSIR_OP_LD_UAV_TYPED,
+ VSIR_OP_LD_UAV_TYPED_S,
+ VSIR_OP_LIT,
+ VSIR_OP_LOD,
+ VSIR_OP_LOG,
+ VSIR_OP_LOGP,
+ VSIR_OP_LOOP,
+ VSIR_OP_LRP,
+ VSIR_OP_LTO,
+ VSIR_OP_LTU,
+ VSIR_OP_M3x2,
+ VSIR_OP_M3x3,
+ VSIR_OP_M3x4,
+ VSIR_OP_M4x3,
+ VSIR_OP_M4x4,
+ VSIR_OP_MAD,
+ VSIR_OP_MAX,
+ VSIR_OP_MIN,
+ VSIR_OP_MOV,
+ VSIR_OP_MOVA,
+ VSIR_OP_MOVC,
+ VSIR_OP_MSAD,
+ VSIR_OP_MUL,
+ VSIR_OP_NEO,
+ VSIR_OP_NEU,
+ VSIR_OP_NOP,
+ VSIR_OP_NOT,
+ VSIR_OP_NRM,
+ VSIR_OP_OR,
+ VSIR_OP_ORD,
+ VSIR_OP_PHASE,
+ VSIR_OP_PHI,
+ VSIR_OP_POW,
+ VSIR_OP_QUAD_READ_ACROSS_D,
+ VSIR_OP_QUAD_READ_ACROSS_X,
+ VSIR_OP_QUAD_READ_ACROSS_Y,
+ VSIR_OP_QUAD_READ_LANE_AT,
+ VSIR_OP_RCP,
+ VSIR_OP_REP,
+ VSIR_OP_RESINFO,
+ VSIR_OP_RET,
+ VSIR_OP_RETP,
+ VSIR_OP_ROUND_NE,
+ VSIR_OP_ROUND_NI,
+ VSIR_OP_ROUND_PI,
+ VSIR_OP_ROUND_Z,
+ VSIR_OP_RSQ,
+ VSIR_OP_SAMPLE,
+ VSIR_OP_SAMPLE_B,
+ VSIR_OP_SAMPLE_B_CL_S,
+ VSIR_OP_SAMPLE_C,
+ VSIR_OP_SAMPLE_C_CL_S,
+ VSIR_OP_SAMPLE_C_LZ,
+ VSIR_OP_SAMPLE_C_LZ_S,
+ VSIR_OP_SAMPLE_CL_S,
+ VSIR_OP_SAMPLE_GRAD,
+ VSIR_OP_SAMPLE_GRAD_CL_S,
+ VSIR_OP_SAMPLE_INFO,
+ VSIR_OP_SAMPLE_LOD,
+ VSIR_OP_SAMPLE_LOD_S,
+ VSIR_OP_SAMPLE_POS,
+ VSIR_OP_SETP,
+ VSIR_OP_SGE,
+ VSIR_OP_SGN,
+ VSIR_OP_SIN,
+ VSIR_OP_SINCOS,
+ VSIR_OP_SLT,
+ VSIR_OP_SQRT,
+ VSIR_OP_STORE_RAW,
+ VSIR_OP_STORE_STRUCTURED,
+ VSIR_OP_STORE_UAV_TYPED,
+ VSIR_OP_SUB,
+ VSIR_OP_SWAPC,
+ VSIR_OP_SWITCH,
+ VSIR_OP_SWITCH_MONOLITHIC,
+ VSIR_OP_SYNC,
+ VSIR_OP_TAN,
+ VSIR_OP_TEX,
+ VSIR_OP_TEXBEM,
+ VSIR_OP_TEXBEML,
+ VSIR_OP_TEXCOORD,
+ VSIR_OP_TEXCRD,
+ VSIR_OP_TEXDEPTH,
+ VSIR_OP_TEXDP3,
+ VSIR_OP_TEXDP3TEX,
+ VSIR_OP_TEXKILL,
+ VSIR_OP_TEXLD,
+ VSIR_OP_TEXLDD,
+ VSIR_OP_TEXLDL,
+ VSIR_OP_TEXM3x2DEPTH,
+ VSIR_OP_TEXM3x2PAD,
+ VSIR_OP_TEXM3x2TEX,
+ VSIR_OP_TEXM3x3,
+ VSIR_OP_TEXM3x3DIFF,
+ VSIR_OP_TEXM3x3PAD,
+ VSIR_OP_TEXM3x3SPEC,
+ VSIR_OP_TEXM3x3TEX,
+ VSIR_OP_TEXM3x3VSPEC,
+ VSIR_OP_TEXREG2AR,
+ VSIR_OP_TEXREG2GB,
+ VSIR_OP_TEXREG2RGB,
+ VSIR_OP_UBFE,
+ VSIR_OP_UDIV,
+ VSIR_OP_UDIV_SIMPLE,
+ VSIR_OP_UGE,
+ VSIR_OP_ULT,
+ VSIR_OP_UMAX,
+ VSIR_OP_UMIN,
+ VSIR_OP_UMUL,
+ VSIR_OP_UNO,
+ VSIR_OP_UREM,
+ VSIR_OP_USHR,
+ VSIR_OP_UTOD,
+ VSIR_OP_UTOF,
+ VSIR_OP_UTOU,
+ VSIR_OP_WAVE_ACTIVE_ALL_EQUAL,
+ VSIR_OP_WAVE_ACTIVE_BALLOT,
+ VSIR_OP_WAVE_ACTIVE_BIT_AND,
+ VSIR_OP_WAVE_ACTIVE_BIT_OR,
+ VSIR_OP_WAVE_ACTIVE_BIT_XOR,
+ VSIR_OP_WAVE_ALL_BIT_COUNT,
+ VSIR_OP_WAVE_ALL_TRUE,
+ VSIR_OP_WAVE_ANY_TRUE,
+ VSIR_OP_WAVE_IS_FIRST_LANE,
+ VSIR_OP_WAVE_OP_ADD,
+ VSIR_OP_WAVE_OP_IMAX,
+ VSIR_OP_WAVE_OP_IMIN,
+ VSIR_OP_WAVE_OP_MAX,
+ VSIR_OP_WAVE_OP_MIN,
+ VSIR_OP_WAVE_OP_MUL,
+ VSIR_OP_WAVE_OP_UMAX,
+ VSIR_OP_WAVE_OP_UMIN,
+ VSIR_OP_WAVE_PREFIX_BIT_COUNT,
+ VSIR_OP_WAVE_READ_LANE_AT,
+ VSIR_OP_WAVE_READ_LANE_FIRST,
+ VSIR_OP_XOR,
+
+ VSIR_OP_INVALID,
+
+ VSIR_OP_COUNT,
+};
+
+const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error);
enum vkd3d_shader_register_type
{
@@ -692,46 +708,51 @@ enum vkd3d_shader_register_precision
VKD3D_SHADER_REGISTER_PRECISION_INVALID = ~0u,
};
-enum vkd3d_data_type
+enum vsir_data_type
{
- VKD3D_DATA_FLOAT,
- VKD3D_DATA_INT,
- VKD3D_DATA_UINT,
- VKD3D_DATA_UNORM,
- VKD3D_DATA_SNORM,
- VKD3D_DATA_OPAQUE,
- VKD3D_DATA_MIXED,
- VKD3D_DATA_DOUBLE,
- VKD3D_DATA_CONTINUED,
- VKD3D_DATA_UNUSED,
- VKD3D_DATA_UINT8,
- VKD3D_DATA_UINT64,
- VKD3D_DATA_BOOL,
- VKD3D_DATA_UINT16,
- VKD3D_DATA_HALF,
+ VSIR_DATA_BOOL,
+
+ VSIR_DATA_F16,
+ VSIR_DATA_F32,
+ VSIR_DATA_F64,
+
+ VSIR_DATA_I32,
+
+ VSIR_DATA_U8,
+ VSIR_DATA_U16,
+ VSIR_DATA_U32,
+ VSIR_DATA_U64,
+
+ VSIR_DATA_SNORM,
+ VSIR_DATA_UNORM,
+
+ VSIR_DATA_OPAQUE,
+ VSIR_DATA_MIXED,
+ VSIR_DATA_CONTINUED,
+ VSIR_DATA_UNUSED,
- VKD3D_DATA_COUNT,
+ VSIR_DATA_TYPE_COUNT,
};
-static inline bool data_type_is_integer(enum vkd3d_data_type data_type)
+static inline bool data_type_is_integer(enum vsir_data_type data_type)
{
- return data_type == VKD3D_DATA_INT || data_type == VKD3D_DATA_UINT8 || data_type == VKD3D_DATA_UINT16
- || data_type == VKD3D_DATA_UINT || data_type == VKD3D_DATA_UINT64;
+ return data_type == VSIR_DATA_I32 || data_type == VSIR_DATA_U8 || data_type == VSIR_DATA_U16
+ || data_type == VSIR_DATA_U32 || data_type == VSIR_DATA_U64;
}
-static inline bool data_type_is_bool(enum vkd3d_data_type data_type)
+static inline bool data_type_is_bool(enum vsir_data_type data_type)
{
- return data_type == VKD3D_DATA_BOOL;
+ return data_type == VSIR_DATA_BOOL;
}
-static inline bool data_type_is_floating_point(enum vkd3d_data_type data_type)
+static inline bool data_type_is_floating_point(enum vsir_data_type data_type)
{
- return data_type == VKD3D_DATA_HALF || data_type == VKD3D_DATA_FLOAT || data_type == VKD3D_DATA_DOUBLE;
+ return data_type == VSIR_DATA_F16 || data_type == VSIR_DATA_F32 || data_type == VSIR_DATA_F64;
}
-static inline bool data_type_is_64_bit(enum vkd3d_data_type data_type)
+static inline bool data_type_is_64_bit(enum vsir_data_type data_type)
{
- return data_type == VKD3D_DATA_DOUBLE || data_type == VKD3D_DATA_UINT64;
+ return data_type == VSIR_DATA_F64 || data_type == VSIR_DATA_U64;
}
enum vsir_dimension
@@ -916,6 +937,16 @@ enum vkd3d_shader_type
struct vkd3d_shader_message_context;
+struct vkd3d_shader_source_list
+{
+ const char **sources;
+ size_t capacity, count;
+};
+
+bool vkd3d_shader_source_list_append(struct vkd3d_shader_source_list *l, const char *source);
+void vkd3d_shader_source_list_cleanup(struct vkd3d_shader_source_list *l);
+void vkd3d_shader_source_list_init(struct vkd3d_shader_source_list *l);
+
struct vkd3d_shader_version
{
enum vkd3d_shader_type type;
@@ -926,7 +957,7 @@ struct vkd3d_shader_version
struct vkd3d_shader_immediate_constant_buffer
{
unsigned int register_idx;
- enum vkd3d_data_type data_type;
+ enum vsir_data_type data_type;
/* total count is element_count * component_count */
unsigned int element_count;
unsigned int component_count;
@@ -939,7 +970,7 @@ struct vkd3d_shader_indexable_temp
unsigned int register_idx;
unsigned int register_size;
unsigned int alignment;
- enum vkd3d_data_type data_type;
+ enum vsir_data_type data_type;
unsigned int component_count;
bool has_function_scope;
const struct vkd3d_shader_immediate_constant_buffer *initialiser;
@@ -958,13 +989,13 @@ struct vkd3d_shader_register
enum vkd3d_shader_register_type type;
enum vkd3d_shader_register_precision precision;
bool non_uniform;
- enum vkd3d_data_type data_type;
+ enum vsir_data_type data_type;
struct vkd3d_shader_register_index idx[3];
unsigned int idx_count;
enum vsir_dimension dimension;
/* known address alignment for optimisation, or zero */
unsigned int alignment;
- union
+ union vsir_immediate_constant
{
uint32_t immconst_u32[VKD3D_VEC4_SIZE];
float immconst_f32[VKD3D_VEC4_SIZE];
@@ -975,7 +1006,7 @@ struct vkd3d_shader_register
};
void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type,
- enum vkd3d_data_type data_type, unsigned int idx_count);
+ enum vsir_data_type data_type, unsigned int idx_count);
static inline bool vsir_register_is_descriptor(const struct vkd3d_shader_register *reg)
{
@@ -992,6 +1023,20 @@ static inline bool vsir_register_is_descriptor(const struct vkd3d_shader_registe
}
}
+static inline enum vkd3d_shader_register_type vsir_register_type_from_sysval_input(
+ enum vkd3d_shader_sysval_semantic sysval)
+{
+ switch (sysval)
+ {
+ case VKD3D_SHADER_SV_PRIMITIVE_ID:
+ return VKD3DSPR_PRIMID;
+ case VKD3D_SHADER_SV_COVERAGE:
+ return VKD3DSPR_COVERAGE;
+ default:
+ return VKD3DSPR_INPUT;
+ }
+}
+
struct vkd3d_shader_dst_param
{
struct vkd3d_shader_register reg;
@@ -1008,9 +1053,9 @@ struct vkd3d_shader_src_param
};
void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type,
- enum vkd3d_data_type data_type, unsigned int idx_count);
+ enum vsir_data_type data_type, unsigned int idx_count);
void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type,
- enum vkd3d_data_type data_type, unsigned int idx_count);
+ enum vsir_data_type data_type, unsigned int idx_count);
void vsir_dst_param_init_null(struct vkd3d_shader_dst_param *dst);
void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id);
@@ -1056,7 +1101,7 @@ struct vkd3d_shader_semantic
unsigned int usage_idx;
enum vkd3d_shader_resource_type resource_type;
unsigned int sample_count;
- enum vkd3d_data_type resource_data_type[VKD3D_VEC4_SIZE];
+ enum vsir_data_type resource_data_type[VKD3D_VEC4_SIZE];
struct vkd3d_shader_resource resource;
};
@@ -1262,14 +1307,14 @@ struct vkd3d_shader_instruction
struct vkd3d_shader_location location;
enum vkd3d_shader_opcode opcode;
uint32_t flags;
- unsigned int dst_count;
- unsigned int src_count;
+ size_t dst_count;
+ size_t src_count;
struct vkd3d_shader_dst_param *dst;
struct vkd3d_shader_src_param *src;
struct vkd3d_shader_texel_offset texel_offset;
enum vkd3d_shader_resource_type resource_type;
unsigned int resource_stride;
- enum vkd3d_data_type resource_data_type[VKD3D_VEC4_SIZE];
+ enum vsir_data_type resource_data_type[VKD3D_VEC4_SIZE];
bool coissue, structured, raw;
const struct vkd3d_shader_src_param *predicate;
union
@@ -1332,12 +1377,6 @@ static inline bool register_is_constant_or_undef(const struct vkd3d_shader_regis
return register_is_constant(reg) || register_is_undef(reg);
}
-static inline bool register_is_scalar_constant_zero(const struct vkd3d_shader_register *reg)
-{
- return register_is_constant(reg) && reg->dimension == VSIR_DIMENSION_SCALAR
- && (data_type_is_64_bit(reg->data_type) ? !reg->u.immconst_u64[0] : !reg->u.immconst_u32[0]);
-}
-
static inline bool register_is_numeric_array(const struct vkd3d_shader_register *reg)
{
return (reg->type == VKD3DSPR_IMMCONSTBUFFER || reg->type == VKD3DSPR_IDXTEMP
@@ -1364,22 +1403,22 @@ struct vkd3d_shader_param_allocator
{
struct vkd3d_shader_param_node *head;
struct vkd3d_shader_param_node *current;
- unsigned int count;
- unsigned int stride;
- unsigned int index;
+ size_t count;
+ size_t stride;
+ size_t index;
};
-void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, unsigned int count);
+void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, size_t count);
static inline struct vkd3d_shader_src_param *shader_src_param_allocator_get(
- struct vkd3d_shader_param_allocator *allocator, unsigned int count)
+ struct vkd3d_shader_param_allocator *allocator, size_t count)
{
VKD3D_ASSERT(allocator->stride == sizeof(struct vkd3d_shader_src_param));
return shader_param_allocator_get(allocator, count);
}
static inline struct vkd3d_shader_dst_param *shader_dst_param_allocator_get(
- struct vkd3d_shader_param_allocator *allocator, unsigned int count)
+ struct vkd3d_shader_param_allocator *allocator, size_t count)
{
VKD3D_ASSERT(allocator->stride == sizeof(struct vkd3d_shader_dst_param));
return shader_param_allocator_get(allocator, count);
@@ -1400,16 +1439,77 @@ struct vkd3d_shader_instruction_array
struct vkd3d_shader_src_param *outpointid_param;
};
-bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve);
-bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve);
+bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, size_t reserve);
+bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, size_t reserve);
bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions,
- unsigned int idx, unsigned int count);
+ size_t idx, size_t count);
bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions,
struct vkd3d_shader_immediate_constant_buffer *icb);
bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions,
- unsigned int dst, unsigned int src);
+ size_t dst, size_t src);
void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions);
+struct vsir_program_iterator
+{
+ struct vkd3d_shader_instruction_array *array;
+ size_t idx;
+};
+
+static inline struct vsir_program_iterator vsir_program_iterator(struct vkd3d_shader_instruction_array *array)
+{
+ return (struct vsir_program_iterator){ .array = array };
+}
+
+static inline struct vkd3d_shader_instruction *vsir_program_iterator_current(
+ struct vsir_program_iterator *iterator)
+{
+ if (iterator->idx >= iterator->array->count)
+ return NULL;
+
+ return &iterator->array->elements[iterator->idx];
+}
+
+static inline struct vkd3d_shader_instruction *vsir_program_iterator_head(
+ struct vsir_program_iterator *iterator)
+{
+ iterator->idx = 0;
+
+ return vsir_program_iterator_current(iterator);
+}
+
+static inline struct vkd3d_shader_instruction *vsir_program_iterator_tail(struct vsir_program_iterator *iterator)
+{
+ iterator->idx = iterator->array->count - 1;
+
+ return vsir_program_iterator_current(iterator);
+}
+
+static inline struct vkd3d_shader_instruction *vsir_program_iterator_next(
+ struct vsir_program_iterator *iterator)
+{
+ if (iterator->idx < iterator->array->count || iterator->idx == SIZE_MAX)
+ ++iterator->idx;
+
+ return vsir_program_iterator_current(iterator);
+}
+
+static inline struct vkd3d_shader_instruction *vsir_program_iterator_prev(
+ struct vsir_program_iterator *iterator)
+{
+ if (iterator->idx != SIZE_MAX)
+ --iterator->idx;
+
+ return vsir_program_iterator_current(iterator);
+}
+
+/* When insertion takes place, argument `it' is updated to point to the same
+ * instruction as before the insertion, but all other iterators and pointers
+ * to the same container are invalidated and cannot be used any more. */
+static inline bool vsir_program_iterator_insert_after(struct vsir_program_iterator *it, size_t count)
+{
+ return shader_instruction_array_insert_at(it->array, it->idx + 1, count);
+}
+
enum vkd3d_shader_config_flags
{
VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION = 0x00000001,
@@ -1436,7 +1536,7 @@ struct vkd3d_shader_descriptor_info1
unsigned int register_index;
unsigned int register_id;
enum vkd3d_shader_resource_type resource_type;
- enum vkd3d_data_type resource_data_type;
+ enum vsir_data_type resource_data_type;
unsigned int flags;
unsigned int sample_count;
unsigned int buffer_size;
@@ -1496,19 +1596,23 @@ struct vsir_program
struct vsir_features features;
+ struct vkd3d_shader_source_list source_files;
const char **block_names;
size_t block_name_count;
};
-void vsir_program_cleanup(struct vsir_program *program);
-int vsir_program_compile(struct vsir_program *program, uint64_t config_flags,
- const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out,
+enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program,
+ struct vkd3d_shader_message_context *message_context);
+enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program,
struct vkd3d_shader_message_context *message_context);
+void vsir_program_cleanup(struct vsir_program *program);
const struct vkd3d_shader_parameter1 *vsir_program_get_parameter(
const struct vsir_program *program, enum vkd3d_shader_parameter_name name);
bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info,
const struct vkd3d_shader_version *version, unsigned int reserve, enum vsir_control_flow_type cf_type,
enum vsir_normalisation_level normalisation_level);
+enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_t config_flags,
+ const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context);
enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags,
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context);
enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uint64_t config_flags,
@@ -1521,6 +1625,16 @@ bool vsir_instruction_init_with_params(struct vsir_program *program,
struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location,
enum vkd3d_shader_opcode opcode, unsigned int dst_count, unsigned int src_count);
+static inline struct vkd3d_shader_instruction *vsir_program_append(struct vsir_program *program)
+{
+ struct vkd3d_shader_instruction_array *array = &program->instructions;
+
+ if (!shader_instruction_array_insert_at(array, array->count, 1))
+ return NULL;
+
+ return &array->elements[array->count - 1];
+}
+
static inline struct vkd3d_shader_dst_param *vsir_program_get_dst_params(
struct vsir_program *program, unsigned int count)
{
@@ -1548,7 +1662,7 @@ void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_pr
void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser,
enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4);
-void vsir_program_trace(const struct vsir_program *program);
+void vsir_program_trace(struct vsir_program *program);
const char *shader_get_type_prefix(enum vkd3d_shader_type type);
@@ -1571,11 +1685,12 @@ enum vsir_asm_flags
VSIR_ASM_FLAG_DUMP_ALL_INDICES = 0x2,
VSIR_ASM_FLAG_DUMP_SIGNATURES = 0x4,
VSIR_ASM_FLAG_DUMP_DESCRIPTORS = 0x8,
+ VSIR_ASM_FLAG_ALLOCATE_TEMPS = 0x10,
};
-enum vkd3d_result d3d_asm_compile(const struct vsir_program *program,
- const struct vkd3d_shader_compile_info *compile_info,
- struct vkd3d_shader_code *out, enum vsir_asm_flags flags);
+enum vkd3d_result d3d_asm_compile(struct vsir_program *program,
+ const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out,
+ enum vsir_asm_flags flags, struct vkd3d_shader_message_context *message_context);
void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer);
struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_cache *list);
void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer);
@@ -1682,6 +1797,8 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con
struct vkd3d_shader_message_context *message_context, struct vsir_program *program);
int fx_parse(const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
+int tx_parse(const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
void free_dxbc_shader_desc(struct dxbc_shader_desc *desc);
@@ -1723,54 +1840,55 @@ void vkd3d_compute_md5(const void *dxbc, size_t size, uint32_t checksum[4], enum
int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
-int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info,
- struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
+int hlsl_compile_effect(const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out);
+int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_message_context *message_context,
+ struct vsir_program *program, struct vkd3d_shader_code *reflection_data);
-static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type(
- enum vkd3d_data_type data_type)
+static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( enum vsir_data_type data_type)
{
switch (data_type)
{
- case VKD3D_DATA_HALF: /* Minimum precision. TODO: native 16-bit */
- case VKD3D_DATA_FLOAT:
- case VKD3D_DATA_UNORM:
- case VKD3D_DATA_SNORM:
+ case VSIR_DATA_BOOL:
+ return VKD3D_SHADER_COMPONENT_BOOL;
+ case VSIR_DATA_F16: /* Minimum precision. TODO: native 16-bit */
+ case VSIR_DATA_F32:
+ case VSIR_DATA_SNORM:
+ case VSIR_DATA_UNORM:
return VKD3D_SHADER_COMPONENT_FLOAT;
- case VKD3D_DATA_UINT16: /* Minimum precision. TODO: native 16-bit */
- case VKD3D_DATA_UINT:
- return VKD3D_SHADER_COMPONENT_UINT;
- case VKD3D_DATA_INT:
- return VKD3D_SHADER_COMPONENT_INT;
- case VKD3D_DATA_DOUBLE:
+ case VSIR_DATA_F64:
return VKD3D_SHADER_COMPONENT_DOUBLE;
- case VKD3D_DATA_UINT64:
+ case VSIR_DATA_I32:
+ return VKD3D_SHADER_COMPONENT_INT;
+ case VSIR_DATA_U16: /* Minimum precision. TODO: native 16-bit */
+ case VSIR_DATA_U32:
+ return VKD3D_SHADER_COMPONENT_UINT;
+ case VSIR_DATA_U64:
return VKD3D_SHADER_COMPONENT_UINT64;
- case VKD3D_DATA_BOOL:
- return VKD3D_SHADER_COMPONENT_BOOL;
default:
FIXME("Unhandled data type %#x.\n", data_type);
/* fall-through */
- case VKD3D_DATA_MIXED:
+ case VSIR_DATA_MIXED:
return VKD3D_SHADER_COMPONENT_UINT;
}
}
-static inline enum vkd3d_data_type vkd3d_data_type_from_component_type(
- enum vkd3d_shader_component_type component_type)
+static inline enum vsir_data_type vsir_data_type_from_component_type(enum vkd3d_shader_component_type component_type)
{
switch (component_type)
{
case VKD3D_SHADER_COMPONENT_FLOAT:
- return VKD3D_DATA_FLOAT;
+ return VSIR_DATA_F32;
case VKD3D_SHADER_COMPONENT_UINT:
- return VKD3D_DATA_UINT;
+ return VSIR_DATA_U32;
case VKD3D_SHADER_COMPONENT_INT:
- return VKD3D_DATA_INT;
+ return VSIR_DATA_I32;
case VKD3D_SHADER_COMPONENT_DOUBLE:
- return VKD3D_DATA_DOUBLE;
+ return VSIR_DATA_F64;
default:
FIXME("Unhandled component type %#x.\n", component_type);
- return VKD3D_DATA_FLOAT;
+ return VSIR_DATA_F32;
}
}
@@ -1779,14 +1897,6 @@ static inline bool component_type_is_64_bit(enum vkd3d_shader_component_type com
return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_UINT64;
}
-enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval,
- unsigned int index);
-
-static inline enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval(enum vkd3d_shader_sysval_semantic sysval)
-{
- return vkd3d_siv_from_sysval_indexed(sysval, 0);
-}
-
static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask)
{
unsigned int i;
@@ -1853,6 +1963,8 @@ static inline uint32_t vsir_write_mask_32_from_64(uint32_t write_mask64)
}
}
+const char *debug_vsir_writemask(unsigned int writemask);
+
static inline uint32_t vsir_swizzle_64_from_32(uint32_t swizzle32)
{
switch (swizzle32)
@@ -1902,6 +2014,12 @@ static inline unsigned int vsir_swizzle_get_component(uint32_t swizzle, unsigned
return (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx)) & VKD3D_SHADER_SWIZZLE_MASK;
}
+static inline void vsir_swizzle_set_component(uint32_t *swizzle, unsigned int idx, unsigned int component)
+{
+ *swizzle &= ~(VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(idx));
+ *swizzle |= component << VKD3D_SHADER_SWIZZLE_SHIFT(idx);
+}
+
static inline unsigned int vkd3d_compact_swizzle(uint32_t swizzle, uint32_t write_mask)
{
unsigned int i, compacted_swizzle = 0;
diff --git a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c
index f2b18b665f8..c41f8bae806 100644
--- a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c
+++ b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c
@@ -19,6 +19,8 @@
#include "vkd3d_utils_private.h"
#undef D3D12CreateDevice
+/* VKD3D_DEBUG_ENV_NAME("VKD3D_DEBUG"); */
+
static const char *debug_d3d_blob_part(D3D_BLOB_PART part)
{
switch (part)
diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c
index e487ed0b9ad..074d8430585 100644
--- a/libs/vkd3d/libs/vkd3d/command.c
+++ b/libs/vkd3d/libs/vkd3d/command.c
@@ -4221,13 +4221,21 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCo
TRACE("iface %p, viewport_count %u, viewports %p.\n", iface, viewport_count, viewports);
if (viewport_count > ARRAY_SIZE(vk_viewports))
- {
FIXME("Viewport count %u > D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE.\n", viewport_count);
- viewport_count = ARRAY_SIZE(vk_viewports);
- }
- for (i = 0; i < viewport_count; ++i)
+ for (i = 0; i < ARRAY_SIZE(vk_viewports); ++i)
{
+ if (i >= viewport_count)
+ {
+ vk_viewports[i].x = 0.0f;
+ vk_viewports[i].y = 0.0f;
+ vk_viewports[i].width = 1.0f;
+ vk_viewports[i].height = 1.0f;
+ vk_viewports[i].minDepth = 0.0f;
+ vk_viewports[i].maxDepth = 0.0f;
+ continue;
+ }
+
vk_viewports[i].x = viewports[i].TopLeftX;
vk_viewports[i].y = viewports[i].TopLeftY + viewports[i].Height;
vk_viewports[i].width = viewports[i].Width;
@@ -4245,7 +4253,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCo
}
vk_procs = &list->device->vk_procs;
- VK_CALL(vkCmdSetViewport(list->vk_command_buffer, 0, viewport_count, vk_viewports));
+ VK_CALL(vkCmdSetViewport(list->vk_command_buffer, 0, ARRAY_SIZE(vk_viewports), vk_viewports));
}
static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12GraphicsCommandList6 *iface,
@@ -4264,6 +4272,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12Graphic
rect_count = ARRAY_SIZE(vk_rects);
}
+ memset(vk_rects, 0, sizeof(vk_rects));
for (i = 0; i < rect_count; ++i)
{
vk_rects[i].offset.x = rects[i].left;
@@ -4273,7 +4282,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12Graphic
}
vk_procs = &list->device->vk_procs;
- VK_CALL(vkCmdSetScissor(list->vk_command_buffer, 0, rect_count, vk_rects));
+ VK_CALL(vkCmdSetScissor(list->vk_command_buffer, 0, ARRAY_SIZE(vk_rects), vk_rects));
}
static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12GraphicsCommandList6 *iface,
diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c
index b2636fd5585..67f84aafa29 100644
--- a/libs/vkd3d/libs/vkd3d/device.c
+++ b/libs/vkd3d/libs/vkd3d/device.c
@@ -5193,7 +5193,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommands(ID3D12Device
FIXME("iface %p, num_meta_commands %p, command_desc %p stub!\n", iface,
num_meta_commands, command_desc);
- return E_NOTIMPL;
+ if (!num_meta_commands)
+ return E_INVALIDARG;
+
+ *num_meta_commands = 0;
+
+ return S_OK;
}
static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommandParameters(ID3D12Device9 *iface,
diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c
index cb184986f2a..7946445ad07 100644
--- a/libs/vkd3d/libs/vkd3d/resource.c
+++ b/libs/vkd3d/libs/vkd3d/resource.c
@@ -310,6 +310,9 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_AddRef(ID3D12Heap *iface)
struct d3d12_heap *heap = impl_from_ID3D12Heap(iface);
unsigned int refcount = vkd3d_atomic_increment_u32(&heap->refcount);
+ if (refcount == 1)
+ vkd3d_atomic_increment_u32(&heap->internal_refcount);
+
TRACE("%p increasing refcount to %u.\n", heap, refcount);
VKD3D_ASSERT(!heap->is_private);
@@ -342,6 +345,12 @@ static void d3d12_heap_destroy(struct d3d12_heap *heap)
d3d12_device_release(device);
}
+static void d3d12_heap_decref(struct d3d12_heap *heap)
+{
+ if (!vkd3d_atomic_decrement_u32(&heap->internal_refcount))
+ d3d12_heap_destroy(heap);
+}
+
static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface)
{
struct d3d12_heap *heap = impl_from_ID3D12Heap(iface);
@@ -350,18 +359,12 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface)
TRACE("%p decreasing refcount to %u.\n", heap, refcount);
/* A heap must not be destroyed until all contained resources are destroyed. */
- if (!refcount && !heap->resource_count)
- d3d12_heap_destroy(heap);
+ if (!refcount)
+ d3d12_heap_decref(heap);
return refcount;
}
-static void d3d12_heap_resource_destroyed(struct d3d12_heap *heap)
-{
- if (!vkd3d_atomic_decrement_u32(&heap->resource_count) && (!heap->refcount || heap->is_private))
- d3d12_heap_destroy(heap);
-}
-
static HRESULT STDMETHODCALLTYPE d3d12_heap_GetPrivateData(ID3D12Heap *iface,
REFGUID guid, UINT *data_size, void *data)
{
@@ -487,7 +490,7 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
heap->ID3D12Heap_iface.lpVtbl = &d3d12_heap_vtbl;
heap->refcount = 1;
- heap->resource_count = 0;
+ heap->internal_refcount = 1;
heap->is_private = !!resource;
@@ -555,8 +558,6 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
heap->device = device;
if (!heap->is_private)
d3d12_device_add_ref(heap->device);
- else
- heap->resource_count = 1;
if (d3d12_heap_get_memory_property_flags(heap) & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
{
@@ -998,7 +999,7 @@ static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12
d3d12_resource_tile_info_cleanup(resource);
if (resource->heap)
- d3d12_heap_resource_destroyed(resource->heap);
+ d3d12_heap_decref(resource->heap);
}
static ULONG d3d12_resource_incref(struct d3d12_resource *resource)
@@ -2200,7 +2201,7 @@ static HRESULT vkd3d_bind_heap_memory(struct d3d12_device *device,
{
resource->heap = heap;
resource->heap_offset = heap_offset;
- vkd3d_atomic_increment_u32(&heap->resource_count);
+ vkd3d_atomic_increment_u32(&heap->internal_refcount);
}
else
{
@@ -2491,20 +2492,41 @@ static void descriptor_writes_free_object_refs(struct descriptor_writes *writes,
writes->held_ref_count = 0;
}
+static enum vkd3d_vk_descriptor_set_index vkd3d_vk_descriptor_set_index_from_vk_descriptor_type(
+ VkDescriptorType type)
+{
+ static const enum vkd3d_vk_descriptor_set_index table[] =
+ {
+ [VK_DESCRIPTOR_TYPE_SAMPLER] = VKD3D_SET_INDEX_SAMPLER,
+ [VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER] = VKD3D_SET_INDEX_COUNT,
+ [VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE] = VKD3D_SET_INDEX_SAMPLED_IMAGE,
+ [VK_DESCRIPTOR_TYPE_STORAGE_IMAGE] = VKD3D_SET_INDEX_STORAGE_IMAGE,
+ [VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER] = VKD3D_SET_INDEX_UNIFORM_TEXEL_BUFFER,
+ [VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER] = VKD3D_SET_INDEX_STORAGE_TEXEL_BUFFER,
+ [VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER] = VKD3D_SET_INDEX_UNIFORM_BUFFER,
+ };
+
+ VKD3D_ASSERT(type < ARRAY_SIZE(table));
+ VKD3D_ASSERT(table[type] < VKD3D_SET_INDEX_COUNT);
+
+ return table[type];
+}
+
static void d3d12_desc_write_vk_heap_null_descriptor(struct d3d12_descriptor_heap *descriptor_heap,
- uint32_t dst_array_element, struct descriptor_writes *writes, struct d3d12_device *device)
+ uint32_t dst_array_element, struct descriptor_writes *writes, struct d3d12_device *device,
+ VkDescriptorType type)
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
struct d3d12_descriptor_heap_vk_set *descriptor_set;
- enum vkd3d_vk_descriptor_set_index set, end;
+ enum vkd3d_vk_descriptor_set_index set;
unsigned int i = writes->count;
- end = device->vk_info.EXT_mutable_descriptor_type ? VKD3D_SET_INDEX_MUTABLE
- : VKD3D_SET_INDEX_STORAGE_IMAGE;
/* Binding a shader with the wrong null descriptor type works in Windows.
* To support that here we must write one to all applicable Vulkan sets. */
- for (set = VKD3D_SET_INDEX_UNIFORM_BUFFER; set <= end; ++set)
+ for (set = VKD3D_SET_INDEX_UNIFORM_BUFFER; set <= VKD3D_SET_INDEX_STORAGE_IMAGE; ++set)
{
+ if (device->vk_info.EXT_mutable_descriptor_type)
+ set = vkd3d_vk_descriptor_set_index_from_vk_descriptor_type(type);
descriptor_set = &descriptor_heap->vk_descriptor_sets[set];
writes->vk_descriptor_writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writes->vk_descriptor_writes[i].pNext = NULL;
@@ -2545,6 +2567,8 @@ static void d3d12_desc_write_vk_heap_null_descriptor(struct d3d12_descriptor_hea
VK_CALL(vkUpdateDescriptorSets(device->vk_device, i, writes->vk_descriptor_writes, 0, NULL));
descriptor_writes_free_object_refs(writes, device);
i = 0;
+ if (device->vk_info.EXT_mutable_descriptor_type)
+ break;
}
writes->count = i;
@@ -2609,7 +2633,7 @@ static void d3d12_desc_write_vk_heap(struct d3d12_descriptor_heap *descriptor_he
break;
}
if (is_null && device->vk_info.EXT_robustness2)
- return d3d12_desc_write_vk_heap_null_descriptor(descriptor_heap, dst_array_element, writes, device);
+ return d3d12_desc_write_vk_heap_null_descriptor(descriptor_heap, dst_array_element, writes, device, type);
++i;
if (u.header->magic == VKD3D_DESCRIPTOR_MAGIC_UAV && u.view->v.vk_counter_view)
@@ -4223,17 +4247,6 @@ static const struct ID3D12DescriptorHeapVtbl d3d12_descriptor_heap_vtbl =
d3d12_descriptor_heap_GetGPUDescriptorHandleForHeapStart,
};
-const enum vkd3d_vk_descriptor_set_index vk_descriptor_set_index_table[] =
-{
- VKD3D_SET_INDEX_SAMPLER,
- VKD3D_SET_INDEX_COUNT,
- VKD3D_SET_INDEX_SAMPLED_IMAGE,
- VKD3D_SET_INDEX_STORAGE_IMAGE,
- VKD3D_SET_INDEX_UNIFORM_TEXEL_BUFFER,
- VKD3D_SET_INDEX_STORAGE_TEXEL_BUFFER,
- VKD3D_SET_INDEX_UNIFORM_BUFFER,
-};
-
static HRESULT d3d12_descriptor_heap_create_descriptor_pool(struct d3d12_descriptor_heap *descriptor_heap,
struct d3d12_device *device, const D3D12_DESCRIPTOR_HEAP_DESC *desc)
{
diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c
index 819185796c0..413892789ba 100644
--- a/libs/vkd3d/libs/vkd3d/state.c
+++ b/libs/vkd3d/libs/vkd3d/state.c
@@ -2383,7 +2383,9 @@ static HRESULT create_shader_stage(struct d3d12_device *device,
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
struct vkd3d_shader_compile_info compile_info;
struct VkShaderModuleCreateInfo shader_desc;
+ struct vkd3d_shader_dxbc_desc dxbc_desc;
struct vkd3d_shader_code spirv = {0};
+ char source_name[33];
VkResult vr;
int ret;
@@ -2416,6 +2418,16 @@ static HRESULT create_shader_stage(struct d3d12_device *device,
compile_info.log_level = VKD3D_SHADER_LOG_NONE;
compile_info.source_name = NULL;
+ if ((ret = vkd3d_shader_parse_dxbc(&(struct vkd3d_shader_code){code->pShaderBytecode, code->BytecodeLength},
+ 0, &dxbc_desc, NULL)) >= 0)
+ {
+ sprintf(source_name, "%08x%08x%08x%08x", dxbc_desc.checksum[0],
+ dxbc_desc.checksum[1], dxbc_desc.checksum[2], dxbc_desc.checksum[3]);
+ vkd3d_shader_free_dxbc(&dxbc_desc);
+ TRACE("Compiling shader \"%s\".\n", source_name);
+ compile_info.source_name = source_name;
+ }
+
if ((ret = vkd3d_shader_parse_dxbc_source_type(&compile_info.source, &compile_info.source_type, NULL)) < 0
|| (ret = vkd3d_shader_compile(&compile_info, &spirv, NULL)) < 0)
{
@@ -3220,17 +3232,6 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
uint32_t mask;
HRESULT hr;
- static const DWORD default_ps_code[] =
- {
-#if 0
- ps_4_0
- ret
-#endif
- 0x43425844, 0x19cbf606, 0x18f562b9, 0xdaeed4db, 0xc324aa46, 0x00000001, 0x00000060, 0x00000003,
- 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
- 0x00000008, 0x00000000, 0x00000008, 0x52444853, 0x0000000c, 0x00000040, 0x00000003, 0x0100003e,
- };
- static const D3D12_SHADER_BYTECODE default_ps = {default_ps_code, sizeof(default_ps_code)};
static const struct
{
enum VkShaderStageFlagBits stage;
@@ -3389,11 +3390,10 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
if (!desc->ps.pShaderBytecode)
{
- if (FAILED(hr = create_shader_stage(device, &graphics->stages[graphics->stage_count],
- VK_SHADER_STAGE_FRAGMENT_BIT, &default_ps, NULL)))
- goto fail;
-
- ++graphics->stage_count;
+ for (i = 0; i < rt_count; i++)
+ {
+ graphics->blend_attachments[i].colorWriteMask = 0;
+ }
}
}
@@ -3971,9 +3971,9 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
.pNext = NULL,
.flags = 0,
- .viewportCount = 1,
+ .viewportCount = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE,
.pViewports = NULL,
- .scissorCount = 1,
+ .scissorCount = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE,
.pScissors = NULL,
};
static const VkDynamicState dynamic_states[] =
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
index 7e54738b19e..9fb6834158f 100644
--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
@@ -436,7 +436,7 @@ struct d3d12_heap
{
ID3D12Heap ID3D12Heap_iface;
unsigned int refcount;
- unsigned int resource_count;
+ unsigned int internal_refcount;
bool is_private;
D3D12_HEAP_DESC desc;
@@ -827,17 +827,6 @@ enum vkd3d_vk_descriptor_set_index
VKD3D_SET_INDEX_COUNT
};
-extern const enum vkd3d_vk_descriptor_set_index vk_descriptor_set_index_table[];
-
-static inline enum vkd3d_vk_descriptor_set_index vkd3d_vk_descriptor_set_index_from_vk_descriptor_type(
- VkDescriptorType type)
-{
- VKD3D_ASSERT(type <= VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
- VKD3D_ASSERT(vk_descriptor_set_index_table[type] < VKD3D_SET_INDEX_COUNT);
-
- return vk_descriptor_set_index_table[type];
-}
-
struct vkd3d_vk_descriptor_heap_layout
{
VkDescriptorType type;
--
2.50.1