[PATCH vkd3d 5/5] vkd3d-shader: Implement DEQ instruction.

Conor McCarthy cmccarthy at codeweavers.com
Fri Jul 9 10:31:38 CDT 2021


Source modifiers and immediate constants are not supported.

Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
 libs/vkd3d-shader/dxbc.c                 |  7 +++++++
 libs/vkd3d-shader/spirv.c                | 19 ++++++++++++++-----
 libs/vkd3d-shader/trace.c                |  1 +
 libs/vkd3d-shader/vkd3d_shader_private.h | 14 ++++++++++++++
 tests/d3d12.c                            |  4 ++--
 5 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index b81ac976..37b8a4a9 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -310,6 +310,7 @@ enum vkd3d_sm4_opcode
     VKD3D_SM5_OP_IMM_ATOMIC_UMAX                  = 0xbc,
     VKD3D_SM5_OP_IMM_ATOMIC_UMIN                  = 0xbd,
     VKD3D_SM5_OP_SYNC                             = 0xbe,
+    VKD3D_SM5_OP_DEQ                              = 0xc3,
     VKD3D_SM5_OP_EVAL_SAMPLE_INDEX                = 0xcc,
     VKD3D_SM5_OP_EVAL_CENTROID                    = 0xcd,
     VKD3D_SM5_OP_DCL_GS_INSTANCES                 = 0xce,
@@ -1018,6 +1019,7 @@ static void shader_sm5_read_sync(struct vkd3d_shader_instruction *ins,
  * R -> VKD3D_DATA_RESOURCE
  * S -> VKD3D_DATA_SAMPLER
  * U -> VKD3D_DATA_UAV
+ * d -> VKD3D_DATA_DOUBLE
  */
 static const struct vkd3d_sm4_opcode_info opcode_table[] =
 {
@@ -1247,6 +1249,7 @@ static const struct vkd3d_sm4_opcode_info opcode_table[] =
     {VKD3D_SM5_OP_IMM_ATOMIC_UMIN,                  VKD3DSIH_IMM_ATOMIC_UMIN,                  "uU",   "iu"},
     {VKD3D_SM5_OP_SYNC,                             VKD3DSIH_SYNC,                             "",     "",
             shader_sm5_read_sync},
+    {VKD3D_SM5_OP_DEQ,                              VKD3DSIH_DEQ,                              "u",    "dd"},
     {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,                 "",     "",
@@ -1352,6 +1355,8 @@ static enum vkd3d_data_type map_data_type(char t)
             return VKD3D_DATA_SAMPLER;
         case 'U':
             return VKD3D_DATA_UAV;
+        case 'd':
+            return VKD3D_DATA_DOUBLE;
         default:
             ERR("Invalid data type '%c'.\n", t);
             return VKD3D_DATA_FLOAT;
@@ -1799,6 +1804,8 @@ static bool shader_sm4_read_dst_param(struct vkd3d_sm4_data *priv, const DWORD *
     }
 
     dst_param->write_mask = (token & VKD3D_SM4_WRITEMASK_MASK) >> VKD3D_SM4_WRITEMASK_SHIFT;
+    if (data_type == VKD3D_DATA_DOUBLE)
+        dst_param->write_mask = vkd3d_write_mask_64_from_32(dst_param->write_mask);
     /* Scalar registers are declared with no write mask in shader bytecode. */
     if (!dst_param->write_mask && shader_sm4_is_scalar_register(&dst_param->reg))
         dst_param->write_mask = VKD3DSP_WRITEMASK_0;
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index ee09c223..8b02dbd8 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -3379,6 +3379,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co
     enum vkd3d_shader_component_type component_type;
     struct vkd3d_shader_register_info reg_info;
     unsigned int component_count;
+    unsigned int write_mask32;
     uint32_t type_id, val_id;
 
     if (reg->type == VKD3DSPR_IMMCONST)
@@ -3391,14 +3392,17 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co
         type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
         return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id);
     }
+    assert(reg_info.component_type != VKD3D_SHADER_COMPONENT_DOUBLE);
     vkd3d_dxbc_compiler_emit_dereference_register(compiler, reg, &reg_info);
 
+    write_mask32 = (reg->data_type == VKD3D_DATA_DOUBLE) ? vkd3d_write_mask_32_from_64(write_mask) : write_mask;
+
     /* Intermediate value (no storage class). */
     if (reg_info.storage_class == SpvStorageClassMax)
     {
         val_id = reg_info.id;
     }
-    else if (component_count == 1)
+    else if (vkd3d_write_mask_component_count(write_mask32) == 1)
     {
         return vkd3d_dxbc_compiler_emit_load_scalar(compiler, reg, swizzle, write_mask, &reg_info);
     }
@@ -3410,7 +3414,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co
     }
 
     val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler,
-            val_id, reg_info.write_mask, reg_info.component_type, swizzle, write_mask);
+            val_id, reg_info.write_mask, reg_info.component_type, swizzle, write_mask32);
 
     if (component_type != reg_info.component_type)
     {
@@ -3592,6 +3596,7 @@ static void vkd3d_dxbc_compiler_emit_store_reg(struct vkd3d_dxbc_compiler *compi
     struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
     enum vkd3d_shader_component_type component_type;
     struct vkd3d_shader_register_info reg_info;
+    unsigned int src_write_mask = write_mask;
     uint32_t type_id;
 
     assert(reg->type != VKD3DSPR_IMMCONST);
@@ -3603,14 +3608,16 @@ static void vkd3d_dxbc_compiler_emit_store_reg(struct vkd3d_dxbc_compiler *compi
     component_type = vkd3d_component_type_from_data_type(reg->data_type);
     if (component_type != reg_info.component_type)
     {
-        unsigned int component_count = vkd3d_write_mask_component_count(write_mask);
-        type_id = vkd3d_spirv_get_type_id(builder, reg_info.component_type, component_count);
+        if (reg->data_type == VKD3D_DATA_DOUBLE)
+            src_write_mask = vkd3d_write_mask_32_from_64(write_mask);
+        type_id = vkd3d_spirv_get_type_id(builder, reg_info.component_type,
+                vkd3d_write_mask_component_count(src_write_mask));
         val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id);
         component_type = reg_info.component_type;
     }
 
     vkd3d_dxbc_compiler_emit_store(compiler,
-            reg_info.id, reg_info.write_mask, component_type, reg_info.storage_class, write_mask, val_id);
+            reg_info.id, reg_info.write_mask, component_type, reg_info.storage_class, src_write_mask, val_id);
 }
 
 static uint32_t vkd3d_dxbc_compiler_emit_sat(struct vkd3d_dxbc_compiler *compiler,
@@ -7233,6 +7240,7 @@ static void vkd3d_dxbc_compiler_emit_comparison_instruction(struct vkd3d_dxbc_co
 
     switch (instruction->handler_idx)
     {
+        case VKD3DSIH_DEQ:
         case VKD3DSIH_EQ:  op = SpvOpFOrdEqual; break;
         case VKD3DSIH_GE:  op = SpvOpFOrdGreaterThanEqual; break;
         case VKD3DSIH_IEQ: op = SpvOpIEqual; break;
@@ -9454,6 +9462,7 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler,
         case VKD3DSIH_UDIV:
             vkd3d_dxbc_compiler_emit_udiv(compiler, instruction);
             break;
+        case VKD3DSIH_DEQ:
         case VKD3DSIH_EQ:
         case VKD3DSIH_GE:
         case VKD3DSIH_IEQ:
diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c
index c21cb3e2..556654ec 100644
--- a/libs/vkd3d-shader/trace.c
+++ b/libs/vkd3d-shader/trace.c
@@ -103,6 +103,7 @@ static const char * const shader_opcode_names[] =
     /* VKD3DSIH_DEFAULT                          */ "default",
     /* VKD3DSIH_DEFB                             */ "defb",
     /* VKD3DSIH_DEFI                             */ "defi",
+    /* VKD3DSIH_DEQ                              */ "deq",
     /* VKD3DSIH_DIV                              */ "div",
     /* VKD3DSIH_DP2                              */ "dp2",
     /* VKD3DSIH_DP2ADD                           */ "dp2add",
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 23d8f07b..5f32d462 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -191,6 +191,7 @@ enum vkd3d_shader_opcode
     VKD3DSIH_DEFAULT,
     VKD3DSIH_DEFB,
     VKD3DSIH_DEFI,
+    VKD3DSIH_DEQ,
     VKD3DSIH_DIV,
     VKD3DSIH_DP2,
     VKD3DSIH_DP2ADD,
@@ -1033,6 +1034,19 @@ static inline unsigned int vkd3d_write_mask_from_component_count(unsigned int co
     return (VKD3DSP_WRITEMASK_0 << component_count) - 1;
 }
 
+static inline unsigned int vkd3d_write_mask_64_from_32(DWORD write_mask32)
+{
+    unsigned int write_mask64 = write_mask32 | (write_mask32 >> 1);
+    return (write_mask64 & VKD3DSP_WRITEMASK_0) | ((write_mask64 & VKD3DSP_WRITEMASK_2) >> 1);
+}
+
+static inline unsigned int vkd3d_write_mask_32_from_64(unsigned int write_mask64)
+{
+    unsigned int write_mask32 = (write_mask64 | (write_mask64 << 1))
+            & (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_2);
+    return write_mask32 | (write_mask32 << 1);
+}
+
 static inline unsigned int vkd3d_swizzle_get_component(DWORD swizzle,
         unsigned int idx)
 {
diff --git a/tests/d3d12.c b/tests/d3d12.c
index c613ff4d..6e45858b 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -9879,8 +9879,8 @@ static void test_shader_instructions(void)
         {&ps_dmovc,     {.d = {{1.5, 0.0}}},  {.d = {1.5, 0.0}}, true, true},
         {&ps_dmodifier, {.d = {{1.5, 0.0}}},  {.d = {1.5f, 2.5f}}, true, true},
         {&ps_dmodifier, {.d = {{-1.5, 0.0}}}, {.d = {1.5f, 1.5f}}, true, true},
-        {&ps_deq, {.d = {{0.0, 0.0}}}, {{0xffffffff}}, true, true},
-        {&ps_deq, {.d = {{1.0, 0.0}}}, {{0x00000000}}, true, true},
+        {&ps_deq, {.d = {{0.0, 0.0}}}, {{0xffffffff}}, true, false},
+        {&ps_deq, {.d = {{1.0, 0.0}}}, {{0x00000000}}, true, false},
         {&ps_dne, {.d = {{0.0, 0.0}}}, {{0x00000000}}, true, true},
         {&ps_dne, {.d = {{1.0, 0.0}}}, {{0xffffffff}}, true, true},
         {&ps_dtou, {.d = {{     -NAN}}}, {{ 0,  0 }}, true, true},
-- 
2.31.1




More information about the wine-devel mailing list