Conor McCarthy : vkd3d-shader/sm4: Parse register precision modifiers.

Alexandre Julliard julliard at winehq.org
Tue Sep 28 16:01:44 CDT 2021


Module: vkd3d
Branch: master
Commit: a422e37953ffb7f96a49abafe8fcd165de627e73
URL:    https://source.winehq.org/git/vkd3d.git/?a=commit;h=a422e37953ffb7f96a49abafe8fcd165de627e73

Author: Conor McCarthy <cmccarthy at codeweavers.com>
Date:   Tue Sep 28 16:07:22 2021 +0200

vkd3d-shader/sm4: Parse register precision modifiers.

Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 libs/vkd3d-shader/dxbc.c                 | 27 +++++++++++++++++++-
 libs/vkd3d-shader/sm4.h                  | 12 +++++++++
 libs/vkd3d-shader/trace.c                | 44 ++++++++++++++++++++++++++++++++
 libs/vkd3d-shader/vkd3d_shader_private.h | 12 +++++++++
 4 files changed, 94 insertions(+), 1 deletion(-)

diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index 0d77f02..f325d9b 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -925,6 +925,16 @@ static const enum vkd3d_shader_register_type register_type_table[] =
     /* VKD3D_SM5_RT_DEPTHOUT_LESS_EQUAL */     VKD3DSPR_DEPTHOUTLE,
 };
 
+static const enum vkd3d_shader_register_precision register_precision_table[] =
+{
+    /* VKD3D_SM4_REGISTER_PRECISION_DEFAULT */      VKD3D_SHADER_REGISTER_PRECISION_DEFAULT,
+    /* VKD3D_SM4_REGISTER_PRECISION_MIN_FLOAT_16 */ VKD3D_SHADER_REGISTER_PRECISION_MIN_FLOAT_16,
+    /* VKD3D_SM4_REGISTER_PRECISION_MIN_FLOAT_10 */ VKD3D_SHADER_REGISTER_PRECISION_MIN_FLOAT_10,
+    /* UNKNOWN */                                   VKD3D_SHADER_REGISTER_PRECISION_INVALID,
+    /* VKD3D_SM4_REGISTER_PRECISION_MIN_INT_16 */   VKD3D_SHADER_REGISTER_PRECISION_MIN_INT_16,
+    /* VKD3D_SM4_REGISTER_PRECISION_MIN_UINT_16 */  VKD3D_SHADER_REGISTER_PRECISION_MIN_UINT_16,
+};
+
 static const struct vkd3d_sm4_opcode_info *get_opcode_info(enum vkd3d_sm4_opcode opcode)
 {
     unsigned int i;
@@ -1165,6 +1175,7 @@ static bool shader_sm4_read_param(struct vkd3d_sm4_data *priv, const DWORD **ptr
         enum vkd3d_data_type data_type, struct vkd3d_shader_register *param,
         enum vkd3d_shader_src_modifier *modifier)
 {
+    enum vkd3d_sm4_register_precision precision;
     enum vkd3d_sm4_register_type register_type;
     enum vkd3d_sm4_extended_operand_type type;
     enum vkd3d_sm4_register_modifier m;
@@ -1188,6 +1199,7 @@ static bool shader_sm4_read_param(struct vkd3d_sm4_data *priv, const DWORD **ptr
     {
         param->type = register_type_table[register_type];
     }
+    param->precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT;
     param->data_type = data_type;
 
     *modifier = VKD3DSPSM_NONE;
@@ -1225,7 +1237,20 @@ static bool shader_sm4_read_param(struct vkd3d_sm4_data *priv, const DWORD **ptr
                     break;
             }
 
-            extended &= ~(VKD3D_SM4_EXTENDED_OPERAND_TYPE_MASK | VKD3D_SM4_REGISTER_MODIFIER_MASK);
+            precision = (extended & VKD3D_SM4_REGISTER_PRECISION_MASK) >> VKD3D_SM4_REGISTER_PRECISION_SHIFT;
+            if (precision >= ARRAY_SIZE(register_precision_table)
+                    || register_precision_table[precision] == VKD3D_SHADER_REGISTER_PRECISION_INVALID)
+            {
+                FIXME("Unhandled register precision %#x.\n", precision);
+                param->precision = VKD3D_SHADER_REGISTER_PRECISION_INVALID;
+            }
+            else
+            {
+                param->precision = register_precision_table[precision];
+            }
+
+            extended &= ~(VKD3D_SM4_EXTENDED_OPERAND_TYPE_MASK | VKD3D_SM4_REGISTER_MODIFIER_MASK
+                    | VKD3D_SM4_REGISTER_PRECISION_MASK);
             if (extended)
                 FIXME("Skipping unhandled extended operand bits 0x%08x.\n", extended);
         }
diff --git a/libs/vkd3d-shader/sm4.h b/libs/vkd3d-shader/sm4.h
index d64a9ef..e811f19 100644
--- a/libs/vkd3d-shader/sm4.h
+++ b/libs/vkd3d-shader/sm4.h
@@ -101,6 +101,9 @@
 #define VKD3D_SM4_REGISTER_MODIFIER_SHIFT     6
 #define VKD3D_SM4_REGISTER_MODIFIER_MASK      (0xffu << VKD3D_SM4_REGISTER_MODIFIER_SHIFT)
 
+#define VKD3D_SM4_REGISTER_PRECISION_SHIFT    14
+#define VKD3D_SM4_REGISTER_PRECISION_MASK     (0x7u << VKD3D_SM4_REGISTER_PRECISION_SHIFT)
+
 #define VKD3D_SM4_ADDRESSING_SHIFT2           28
 #define VKD3D_SM4_ADDRESSING_MASK2            (0x3u << VKD3D_SM4_ADDRESSING_SHIFT2)
 
@@ -407,6 +410,15 @@ enum vkd3d_sm4_register_modifier
     VKD3D_SM4_REGISTER_MODIFIER_ABS_NEGATE = 0x03,
 };
 
+enum vkd3d_sm4_register_precision
+{
+    VKD3D_SM4_REGISTER_PRECISION_DEFAULT      = 0x0,
+    VKD3D_SM4_REGISTER_PRECISION_MIN_FLOAT_16 = 0x1,
+    VKD3D_SM4_REGISTER_PRECISION_MIN_FLOAT_10 = 0x2,
+    VKD3D_SM4_REGISTER_PRECISION_MIN_INT_16   = 0x4,
+    VKD3D_SM4_REGISTER_PRECISION_MIN_UINT_16  = 0x5,
+};
+
 enum vkd3d_sm4_output_primitive_type
 {
     VKD3D_SM4_OUTPUT_PT_POINTLIST     = 0x1,
diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c
index 1dca1ae..dba50d2 100644
--- a/libs/vkd3d-shader/trace.c
+++ b/libs/vkd3d-shader/trace.c
@@ -323,7 +323,9 @@ shader_input_sysval_semantic_names[] =
 struct vkd3d_d3d_asm_colours
 {
     const char *reset;
+    const char *error;
     const char *literal;
+    const char *modifier;
     const char *opcode;
     const char *reg;
     const char *swizzle;
@@ -1166,6 +1168,40 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
     }
 }
 
+static void shader_print_precision(struct vkd3d_d3d_asm_compiler *compiler, const struct vkd3d_shader_register *reg)
+{
+    struct vkd3d_string_buffer *buffer = &compiler->buffer;
+    const char *precision;
+
+    if (reg->precision == VKD3D_SHADER_REGISTER_PRECISION_DEFAULT)
+        return;
+
+    switch (reg->precision)
+    {
+        case VKD3D_SHADER_REGISTER_PRECISION_MIN_FLOAT_16:
+            precision = "min16f";
+            break;
+
+        case VKD3D_SHADER_REGISTER_PRECISION_MIN_FLOAT_10:
+            precision = "min2_8f";
+            break;
+
+        case VKD3D_SHADER_REGISTER_PRECISION_MIN_INT_16:
+            precision = "min16i";
+            break;
+
+        case VKD3D_SHADER_REGISTER_PRECISION_MIN_UINT_16:
+            precision = "min16u";
+            break;
+
+        default:
+            vkd3d_string_buffer_printf(buffer, " {%s<unhandled precision %#x>%s}",
+                    compiler->colours.error, reg->precision, compiler->colours.reset);
+            return;
+    }
+    vkd3d_string_buffer_printf(buffer, " {%s%s%s}", compiler->colours.modifier, precision, compiler->colours.reset);
+}
+
 static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
         const struct vkd3d_shader_dst_param *param, bool is_declaration)
 {
@@ -1192,6 +1228,8 @@ static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
             shader_addline(buffer, "%c", write_mask_chars[3]);
         shader_addline(buffer, "%s", compiler->colours.reset);
     }
+
+    shader_print_precision(compiler, &param->reg);
 }
 
 static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
@@ -1262,6 +1300,8 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
     }
     if (src_modifier == VKD3DSPSM_ABS || src_modifier == VKD3DSPSM_ABSNEG)
         shader_addline(buffer, "|");
+
+    shader_print_precision(compiler, &param->reg);
 }
 
 static void shader_dump_ins_modifiers(struct vkd3d_d3d_asm_compiler *compiler,
@@ -1786,7 +1826,9 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(struct vkd3d_shader_parser *parser,
     static const struct vkd3d_d3d_asm_colours no_colours =
     {
         .reset = "",
+        .error = "",
         .literal = "",
+        .modifier = "",
         .opcode = "",
         .reg = "",
         .swizzle = "",
@@ -1796,7 +1838,9 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(struct vkd3d_shader_parser *parser,
     static const struct vkd3d_d3d_asm_colours colours =
     {
         .reset = "\x1b[m",
+        .error = "\x1b[97;41m",
         .literal = "\x1b[95m",
+        .modifier = "\x1b[36m",
         .opcode = "\x1b[96;1m",
         .reg = "\x1b[96m",
         .swizzle = "\x1b[93m",
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index b02315a..b48b901 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -441,6 +441,17 @@ enum vkd3d_shader_register_type
     VKD3DSPR_INVALID = ~0u,
 };
 
+enum vkd3d_shader_register_precision
+{
+    VKD3D_SHADER_REGISTER_PRECISION_DEFAULT,
+    VKD3D_SHADER_REGISTER_PRECISION_MIN_FLOAT_16,
+    VKD3D_SHADER_REGISTER_PRECISION_MIN_FLOAT_10,
+    VKD3D_SHADER_REGISTER_PRECISION_MIN_INT_16,
+    VKD3D_SHADER_REGISTER_PRECISION_MIN_UINT_16,
+
+    VKD3D_SHADER_REGISTER_PRECISION_INVALID = ~0u,
+};
+
 enum vkd3d_data_type
 {
     VKD3D_DATA_FLOAT,
@@ -621,6 +632,7 @@ struct vkd3d_shader_register_index
 struct vkd3d_shader_register
 {
     enum vkd3d_shader_register_type type;
+    enum vkd3d_shader_register_precision precision;
     enum vkd3d_data_type data_type;
     struct vkd3d_shader_register_index idx[3];
     enum vkd3d_immconst_type immconst_type;




More information about the wine-cvs mailing list