[PATCH vkd3d 1/4] vkd3d-shader/hlsl: Add support for sm4 instruction modifiers.

Francisco Casas fcasas at codeweavers.com
Fri Nov 26 09:40:55 CST 2021


Signed-off-by: Francisco Casas <fcasas at codeweavers.com>
---
 include/private/vkd3d_common.h | 24 +++++++++++++++
 libs/vkd3d-shader/hlsl_sm4.c   | 55 ++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+)

diff --git a/include/private/vkd3d_common.h b/include/private/vkd3d_common.h
index b7ce9ae4..2724a370 100644
--- a/include/private/vkd3d_common.h
+++ b/include/private/vkd3d_common.h
@@ -238,4 +238,28 @@ static inline void vkd3d_parse_version(const char *version, int *major, int *min
 
 HRESULT hresult_from_vkd3d_result(int vkd3d_result);
 
+
+/* Encode a signed integer using two's complement representation in the given number of bits.
+ * Assumes that the machine uses two's complement too.
+ * *out_overflow is set to 1 in case the signed integer is out of the range of representable values.
+ */
+static inline uint32_t encode_int(int32_t v, uint32_t n_bits, int *out_overflow)
+{
+    uint32_t mask, umask;
+    uint32_t enc = (uint32_t) v;
+
+    *out_overflow = 0;
+
+    if (n_bits < 32)
+    {
+        umask = (1 << (n_bits - 1)) - 1;
+        *out_overflow = (v >= 0)? !!(enc & ~umask) : !!(~enc & ~umask);
+
+        mask = (1 << n_bits) - 1;
+        enc = enc & mask;
+    }
+    return enc;
+}
+
+
 #endif  /* __VKD3D_COMMON_H */
diff --git a/libs/vkd3d-shader/hlsl_sm4.c b/libs/vkd3d-shader/hlsl_sm4.c
index c0c26f80..9c500f8e 100644
--- a/libs/vkd3d-shader/hlsl_sm4.c
+++ b/libs/vkd3d-shader/hlsl_sm4.c
@@ -727,6 +727,47 @@ static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_typ
     }
 }
 
+struct sm4_instruction_modifier
+{
+    enum vkd3d_sm4_instruction_modifier type;
+
+    union
+    {
+        struct
+        {
+            int u,v,w;
+        } aoffimmi;
+    };
+};
+
+static uint32_t sm4_encode_instruction_modifier(struct sm4_instruction_modifier imod)
+{
+    int overflow_u, overflow_v, overflow_w;
+    uint32_t word = 0;
+
+    word |= VKD3D_SM4_MODIFIER_MASK & imod.type;
+
+    switch (imod.type)
+    {
+        case VKD3D_SM4_MODIFIER_AOFFIMMI:
+            word |= encode_int(imod.aoffimmi.u, 4, &overflow_u) << VKD3D_SM4_AOFFIMMI_U_SHIFT;
+            word |= encode_int(imod.aoffimmi.v, 4, &overflow_v) << VKD3D_SM4_AOFFIMMI_V_SHIFT;
+            word |= encode_int(imod.aoffimmi.w, 4, &overflow_w) << VKD3D_SM4_AOFFIMMI_W_SHIFT;
+            if (overflow_u || overflow_v || overflow_w)
+                WARN("aoffimmi (%d,%d,%d) out of representable range -8 to 7.\n",
+                        imod.aoffimmi.u, imod.aoffimmi.v, imod.aoffimmi.w);
+        break;
+
+        default:
+            FIXME("Unhandled instruction modifier %#x.\n", imod.type);
+            return 0;
+        break;
+    }
+
+    return word;
+}
+
+
 struct sm4_register
 {
     enum vkd3d_sm4_register_type type;
@@ -741,6 +782,9 @@ struct sm4_instruction
 {
     enum vkd3d_sm4_opcode opcode;
 
+    struct sm4_instruction_modifier modifiers[4];
+    unsigned int modifier_count;
+
     struct
     {
         struct sm4_register reg;
@@ -901,6 +945,7 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st
     uint32_t token = instr->opcode;
     unsigned int size = 1, i, j;
 
+    size += instr->modifier_count;
     for (i = 0; i < instr->dst_count; ++i)
         size += sm4_register_order(&instr->dsts[i].reg);
     for (i = 0; i < instr->src_count; ++i)
@@ -908,8 +953,18 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st
     size += instr->idx_count;
 
     token |= (size << VKD3D_SM4_INSTRUCTION_LENGTH_SHIFT);
+
+    token |= ((0 < instr->modifier_count) << 31);
+
     put_u32(buffer, token);
 
+    for (i = 0; i < instr->modifier_count; i++)
+    {
+        token = sm4_encode_instruction_modifier(instr->modifiers[i]);
+        token |= ((i + 1 < instr->modifier_count) << 31);
+        put_u32(buffer, token);
+    }
+
     for (i = 0; i < instr->dst_count; ++i)
     {
         token = sm4_encode_register(&instr->dsts[i].reg);
-- 
2.25.1




More information about the wine-devel mailing list