[PATCH vkd3d 3/9] vkd3d-shader: Add 64-bit immediate constant register type.

Conor McCarthy cmccarthy at codeweavers.com
Sun Jun 13 22:26:37 CDT 2021


Based on vkd3d-proton patches.
From: Joshua Ashton <joshua at froggi.es>

Signed-off-by: Conor McCarthy <cmccarthy at codeweavers.com>
---
 libs/vkd3d-shader/dxbc.c                 | 15 +++--
 libs/vkd3d-shader/spirv.c                | 75 +++++++++++++++++++-----
 libs/vkd3d-shader/trace.c                | 43 +++++++++++++-
 libs/vkd3d-shader/vkd3d_shader_private.h |  4 ++
 4 files changed, 116 insertions(+), 21 deletions(-)

diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index cd90354a..782aed13 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -329,6 +329,7 @@ enum vkd3d_sm4_register_type
     VKD3D_SM4_RT_OUTPUT                  = 0x02,
     VKD3D_SM4_RT_INDEXABLE_TEMP          = 0x03,
     VKD3D_SM4_RT_IMMCONST                = 0x04,
+    VKD3D_SM4_RT_IMMCONST64              = 0x05,
     VKD3D_SM4_RT_SAMPLER                 = 0x06,
     VKD3D_SM4_RT_RESOURCE                = 0x07,
     VKD3D_SM4_RT_CONSTBUFFER             = 0x08,
@@ -1244,7 +1245,7 @@ static const enum vkd3d_shader_register_type register_type_table[] =
     /* VKD3D_SM4_RT_OUTPUT */                  VKD3DSPR_OUTPUT,
     /* VKD3D_SM4_RT_INDEXABLE_TEMP */          VKD3DSPR_IDXTEMP,
     /* VKD3D_SM4_RT_IMMCONST */                VKD3DSPR_IMMCONST,
-    /* UNKNOWN */                              ~0u,
+    /* VKD3D_SM4_RT_IMMCONST64 */              VKD3DSPR_IMMCONST64,
     /* VKD3D_SM4_RT_SAMPLER */                 VKD3DSPR_SAMPLER,
     /* VKD3D_SM4_RT_RESOURCE */                VKD3DSPR_RESOURCE,
     /* VKD3D_SM4_RT_CONSTBUFFER */             VKD3DSPR_CONSTBUFFER,
@@ -1618,21 +1619,23 @@ static bool shader_sm4_read_param(struct vkd3d_sm4_data *priv, const DWORD **ptr
         return false;
     }
 
-    if (register_type == VKD3D_SM4_RT_IMMCONST)
+    if (register_type == VKD3D_SM4_RT_IMMCONST || register_type == VKD3D_SM4_RT_IMMCONST64)
     {
         enum vkd3d_sm4_dimension dimension = (token & VKD3D_SM4_DIMENSION_MASK) >> VKD3D_SM4_DIMENSION_SHIFT;
+        unsigned int dword_count;
 
         switch (dimension)
         {
             case VKD3D_SM4_DIMENSION_SCALAR:
                 param->immconst_type = VKD3D_IMMCONST_SCALAR;
-                if (end - *ptr < 1)
+                dword_count = 1 + (register_type == VKD3D_SM4_RT_IMMCONST64);
+                if (end - *ptr < dword_count)
                 {
                     WARN("Invalid ptr %p, end %p.\n", *ptr, end);
                     return false;
                 }
-                memcpy(param->u.immconst_uint, *ptr, 1 * sizeof(DWORD));
-                *ptr += 1;
+                memcpy(param->u.immconst_uint, *ptr, dword_count * sizeof(DWORD));
+                *ptr += dword_count;
                 break;
 
             case VKD3D_SM4_DIMENSION_VEC4:
@@ -1707,7 +1710,7 @@ static bool shader_sm4_read_src_param(struct vkd3d_sm4_data *priv, const DWORD *
         return false;
     }
 
-    if (src_param->reg.type == VKD3DSPR_IMMCONST)
+    if (src_param->reg.type == VKD3DSPR_IMMCONST || src_param->reg.type == VKD3DSPR_IMMCONST64)
     {
         src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
     }
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index ca523cb5..bdbd688d 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -1118,19 +1118,18 @@ static uint32_t vkd3d_spirv_get_op_type_pointer(struct vkd3d_spirv_builder *buil
             vkd3d_spirv_build_op_type_pointer);
 }
 
-/* Types larger than 32-bits are not supported. */
 static uint32_t vkd3d_spirv_build_op_constant(struct vkd3d_spirv_builder *builder,
-        uint32_t result_type, uint32_t value)
+        uint32_t result_type, const uint32_t *values, unsigned int value_count)
 {
-    return vkd3d_spirv_build_op_tr1(builder, &builder->global_stream,
-            SpvOpConstant, result_type, value);
+    return vkd3d_spirv_build_op_trv(builder, &builder->global_stream,
+            SpvOpConstant, result_type, values, value_count);
 }
 
 static uint32_t vkd3d_spirv_get_op_constant(struct vkd3d_spirv_builder *builder,
-        uint32_t result_type, uint32_t value)
+        uint32_t result_type, const uint32_t *values, unsigned int value_count)
 {
-    return vkd3d_spirv_build_once2(builder, SpvOpConstant, result_type, value,
-            vkd3d_spirv_build_op_constant);
+    return vkd3d_spirv_build_once1v(builder, SpvOpConstant, result_type, values,
+            value_count, vkd3d_spirv_build_op_constant);
 }
 
 static uint32_t vkd3d_spirv_build_op_constant_composite(struct vkd3d_spirv_builder *builder,
@@ -2608,18 +2607,35 @@ static void vkd3d_dxbc_compiler_put_symbol(struct vkd3d_dxbc_compiler *compiler,
     }
 }
 
+static unsigned int vkd3d_spirv_get_component_value_count(enum vkd3d_shader_component_type component_type)
+{
+    switch (component_type)
+    {
+        case VKD3D_SHADER_COMPONENT_UINT:
+        case VKD3D_SHADER_COMPONENT_INT:
+        case VKD3D_SHADER_COMPONENT_FLOAT:
+            return 1;
+        case VKD3D_SHADER_COMPONENT_DOUBLE:
+            return 2;
+        default:
+            ERR("Invalid shader component type %u.\n", component_type);
+            return 1;
+    }
+}
+
 static uint32_t vkd3d_dxbc_compiler_get_constant(struct vkd3d_dxbc_compiler *compiler,
         enum vkd3d_shader_component_type component_type, unsigned int component_count, const uint32_t *values)
 {
     uint32_t type_id, scalar_type_id, component_ids[VKD3D_VEC4_SIZE];
     struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
-    unsigned int i;
+    unsigned int i, value_count;
 
     assert(0 < component_count && component_count <= VKD3D_VEC4_SIZE);
     type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
 
     switch (component_type)
     {
+        case VKD3D_SHADER_COMPONENT_DOUBLE:
         case VKD3D_SHADER_COMPONENT_UINT:
         case VKD3D_SHADER_COMPONENT_INT:
         case VKD3D_SHADER_COMPONENT_FLOAT:
@@ -2629,15 +2645,17 @@ static uint32_t vkd3d_dxbc_compiler_get_constant(struct vkd3d_dxbc_compiler *com
             return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id);
     }
 
+    value_count = vkd3d_spirv_get_component_value_count(component_type);
+
     if (component_count == 1)
     {
-        return vkd3d_spirv_get_op_constant(builder, type_id, *values);
+        return vkd3d_spirv_get_op_constant(builder, type_id, values, value_count);
     }
     else
     {
         scalar_type_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
         for (i = 0; i < component_count; ++i)
-            component_ids[i] = vkd3d_spirv_get_op_constant(builder, scalar_type_id, values[i]);
+            component_ids[i] = vkd3d_spirv_get_op_constant(builder, scalar_type_id, &values[i * value_count], value_count);
         return vkd3d_spirv_get_op_constant_composite(builder, type_id, component_ids, component_count);
     }
 }
@@ -3011,7 +3029,7 @@ static bool vkd3d_dxbc_compiler_get_register_info(const struct vkd3d_dxbc_compil
     struct vkd3d_symbol reg_symbol, *symbol;
     struct rb_entry *entry;
 
-    assert(reg->type != VKD3DSPR_IMMCONST);
+    assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64);
 
     if (reg->type == VKD3DSPR_TEMP)
     {
@@ -3255,6 +3273,33 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_constant(struct vkd3d_dxbc_compile
             vkd3d_component_type_from_data_type(reg->data_type), component_count, values);
 }
 
+static uint32_t vkd3d_dxbc_compiler_emit_load_constant64(struct vkd3d_dxbc_compiler *compiler,
+        const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask)
+{
+    unsigned int component_count = vkd3d_write_mask_component_count_typed(write_mask, VKD3D_DATA_DOUBLE);
+    uint64_t values[2] = {0};
+    unsigned int i, j;
+
+    assert(reg->type == VKD3DSPR_IMMCONST64);
+
+    if (reg->immconst_type == VKD3D_IMMCONST_SCALAR)
+    {
+        for (i = 0; i < component_count; ++i)
+            values[i] = reg->u.immconst_uint64[0];
+    }
+    else
+    {
+        for (i = 0, j = 0; i < VKD3D_DVEC2_SIZE; ++i)
+        {
+            if (write_mask & (VKD3DSP_WRITEMASK_0 << (i * 2)))
+                values[j++] = reg->u.immconst_uint64[vkd3d_swizzle_get_component(swizzle, i * 2) / 2u];
+        }
+    }
+
+    return vkd3d_dxbc_compiler_get_constant(compiler,
+            vkd3d_component_type_from_data_type(reg->data_type), component_count, (const uint32_t*)values);
+}
+
 static uint32_t vkd3d_dxbc_compiler_emit_load_scalar(struct vkd3d_dxbc_compiler *compiler,
         const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask,
         const struct vkd3d_shader_register_info *reg_info)
@@ -3265,7 +3310,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_scalar(struct vkd3d_dxbc_compiler
     enum vkd3d_shader_component_type component_type;
     unsigned int skipped_component_mask;
 
-    assert(reg->type != VKD3DSPR_IMMCONST);
+    assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64);
     assert(vkd3d_write_mask_component_count(write_mask) == 1);
 
     component_idx = vkd3d_write_mask_get_component_idx(write_mask);
@@ -3314,6 +3359,8 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co
 
     if (reg->type == VKD3DSPR_IMMCONST)
         return vkd3d_dxbc_compiler_emit_load_constant(compiler, reg, swizzle, write_mask);
+    else if (reg->type == VKD3DSPR_IMMCONST64)
+        return vkd3d_dxbc_compiler_emit_load_constant64(compiler, reg, swizzle, write_mask);
 
     component_count = vkd3d_write_mask_component_count(write_mask);
     component_type = vkd3d_component_type_from_data_type(reg->data_type);
@@ -3526,7 +3573,7 @@ static void vkd3d_dxbc_compiler_emit_store_reg(struct vkd3d_dxbc_compiler *compi
     struct vkd3d_shader_register_info reg_info;
     uint32_t type_id;
 
-    assert(reg->type != VKD3DSPR_IMMCONST);
+    assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64);
 
     if (!vkd3d_dxbc_compiler_get_register_info(compiler, reg, &reg_info))
         return;
@@ -6637,7 +6684,7 @@ static void vkd3d_dxbc_compiler_emit_mov(struct vkd3d_dxbc_compiler *compiler,
     uint32_t components[VKD3D_VEC4_SIZE];
     unsigned int i, component_count;
 
-    if (src->reg.type == VKD3DSPR_IMMCONST || dst->modifiers || src->modifiers)
+    if (src->reg.type == VKD3DSPR_IMMCONST || src->reg.type == VKD3DSPR_IMMCONST64 || dst->modifiers || src->modifiers)
         goto general_implementation;
 
     vkd3d_dxbc_compiler_get_register_info(compiler, &dst->reg, &dst_reg_info);
diff --git a/libs/vkd3d-shader/trace.c b/libs/vkd3d-shader/trace.c
index 4e355118..859c428c 100644
--- a/libs/vkd3d-shader/trace.c
+++ b/libs/vkd3d-shader/trace.c
@@ -869,6 +869,10 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
             shader_addline(buffer, "l");
             break;
 
+        case VKD3DSPR_IMMCONST64:
+            shader_addline(buffer, "d");
+            break;
+
         case VKD3DSPR_CONSTBUFFER:
             shader_addline(buffer, "cb");
             break;
@@ -1038,6 +1042,42 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const
         }
         shader_addline(buffer, ")");
     }
+    else if (reg->type == VKD3DSPR_IMMCONST64)
+    {
+        shader_addline(buffer, "(");
+        switch (reg->immconst_type)
+        {
+            case VKD3D_IMMCONST_SCALAR:
+                switch (reg->data_type)
+                {
+                    case VKD3D_DATA_DOUBLE:
+                        shader_addline(buffer, "%f", reg->u.immconst_double[0]);
+                        break;
+                    default:
+                        shader_addline(buffer, "<unhandled data type %#x>", reg->data_type);
+                        break;
+                }
+                break;
+
+            case VKD3D_IMMCONST_VEC4:
+                switch (reg->data_type)
+                {
+                    case VKD3D_DATA_DOUBLE:
+                        shader_addline(buffer, "%f, %f",
+                                reg->u.immconst_double[0], reg->u.immconst_double[1]);
+                        break;
+                    default:
+                        shader_addline(buffer, "<unhandled data type %#x>", reg->data_type);
+                        break;
+                }
+                break;
+
+            default:
+                shader_addline(buffer, "<unhandled immconst_type %#x>", reg->immconst_type);
+                break;
+        }
+        shader_addline(buffer, ")");
+    }
     else if (reg->type != VKD3DSPR_RASTOUT
             && reg->type != VKD3DSPR_MISCTYPE
             && reg->type != VKD3DSPR_NULL)
@@ -1148,7 +1188,8 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
         default:                  shader_addline(buffer, "_unknown_modifier(%#x)", src_modifier);
     }
 
-    if (param->reg.type != VKD3DSPR_IMMCONST && param->reg.type != VKD3DSPR_SAMPLER)
+    if (param->reg.type != VKD3DSPR_IMMCONST && param->reg.type != VKD3DSPR_IMMCONST64
+            && param->reg.type != VKD3DSPR_SAMPLER)
     {
         static const char swizzle_chars[] = "xyzw";
         DWORD swizzle_x = (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(0)) & VKD3D_SHADER_SWIZZLE_MASK;
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 03bc2e1b..f56ca183 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -58,6 +58,7 @@
 #include <string.h>
 
 #define VKD3D_VEC4_SIZE 4
+#define VKD3D_DVEC2_SIZE 2
 
 enum vkd3d_shader_error
 {
@@ -381,6 +382,7 @@ enum vkd3d_shader_register_type
     VKD3DSPR_LABEL = 18,
     VKD3DSPR_PREDICATE = 19,
     VKD3DSPR_IMMCONST,
+    VKD3DSPR_IMMCONST64,
     VKD3DSPR_CONSTBUFFER,
     VKD3DSPR_IMMCONSTBUFFER,
     VKD3DSPR_PRIMID,
@@ -611,6 +613,8 @@ struct vkd3d_shader_register
     {
         DWORD immconst_uint[VKD3D_VEC4_SIZE];
         float immconst_float[VKD3D_VEC4_SIZE];
+        uint64_t immconst_uint64[VKD3D_DVEC2_SIZE];
+        double immconst_double[VKD3D_DVEC2_SIZE];
         unsigned fp_body_idx;
     } u;
 };
-- 
2.31.1




More information about the wine-devel mailing list