[PATCH 2/5] vkd3d-shader: Implement serialization for versioned root signatures.

Józef Kucia joseph.kucia at gmail.com
Mon Apr 22 03:58:33 CDT 2019


From: Józef Kucia <jkucia at codeweavers.com>

---
 include/vkd3d_shader.h             |   6 +
 libs/vkd3d-shader/dxbc.c           | 193 +++++++++++++++++++++++++----
 libs/vkd3d-shader/vkd3d_shader.map |   1 +
 3 files changed, 174 insertions(+), 26 deletions(-)

diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index ae315e66d4db..4d2f8c2f2983 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -575,6 +575,9 @@ void vkd3d_shader_free_root_signature(struct vkd3d_root_signature_desc *root_sig
 int vkd3d_shader_serialize_root_signature(const struct vkd3d_root_signature_desc *root_signature,
         enum vkd3d_root_signature_version version, struct vkd3d_shader_code *dxbc);
 
+int vkd3d_shader_serialize_versioned_root_signature(const struct vkd3d_versioned_root_signature_desc *root_signature,
+        struct vkd3d_shader_code *dxbc);
+
 int vkd3d_shader_convert_root_signature(struct vkd3d_versioned_root_signature_desc *dst,
         enum vkd3d_root_signature_version version, const struct vkd3d_versioned_root_signature_desc *src);
 
@@ -607,6 +610,9 @@ typedef void (*PFN_vkd3d_shader_free_root_signature)(struct vkd3d_root_signature
 typedef int (*PFN_vkd3d_shader_serialize_root_signature)(const struct vkd3d_root_signature_desc *root_signature,
         enum vkd3d_root_signature_version version, struct vkd3d_shader_code *dxbc);
 
+typedef int (*PFN_vkd3d_shader_serialize_versioned_root_signature)(
+        const struct vkd3d_versioned_root_signature_desc *root_signature, struct vkd3d_shader_code *dxbc);
+
 typedef int (*PFN_vkd3d_shader_convert_root_signature)(struct vkd3d_versioned_root_signature_desc *dst,
         enum vkd3d_root_signature_version version, const struct vkd3d_versioned_root_signature_desc *src);
 
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index 5903ed8ae155..fdf711d65615 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -2520,6 +2520,66 @@ int vkd3d_shader_parse_versioned_root_signature(const struct vkd3d_shader_code *
     return VKD3D_OK;
 }
 
+static unsigned int versioned_root_signature_get_parameter_count(const struct vkd3d_versioned_root_signature_desc *desc)
+{
+    if (desc->version == VKD3D_ROOT_SIGNATURE_VERSION_1_0)
+        return desc->u.v_1_0.parameter_count;
+    else
+        return desc->u.v_1_1.parameter_count;
+}
+
+static enum vkd3d_root_parameter_type versioned_root_signature_get_parameter_type(
+        const struct vkd3d_versioned_root_signature_desc *desc, unsigned int i)
+{
+    if (desc->version == VKD3D_ROOT_SIGNATURE_VERSION_1_0)
+        return desc->u.v_1_0.parameters[i].parameter_type;
+    else
+        return desc->u.v_1_1.parameters[i].parameter_type;
+}
+
+static enum vkd3d_shader_visibility versioned_root_signature_get_parameter_shader_visibility(
+        const struct vkd3d_versioned_root_signature_desc *desc, unsigned int i)
+{
+    if (desc->version == VKD3D_ROOT_SIGNATURE_VERSION_1_0)
+        return desc->u.v_1_0.parameters[i].shader_visibility;
+    else
+        return desc->u.v_1_1.parameters[i].shader_visibility;
+}
+
+static const struct vkd3d_root_constants *versioned_root_signature_get_root_constants(
+        const struct vkd3d_versioned_root_signature_desc *desc, unsigned int i)
+{
+    if (desc->version == VKD3D_ROOT_SIGNATURE_VERSION_1_0)
+        return &desc->u.v_1_0.parameters[i].u.constants;
+    else
+        return &desc->u.v_1_1.parameters[i].u.constants;
+}
+
+static unsigned int versioned_root_signature_get_static_sampler_count(const struct vkd3d_versioned_root_signature_desc *desc)
+{
+    if (desc->version == VKD3D_ROOT_SIGNATURE_VERSION_1_0)
+        return desc->u.v_1_0.static_sampler_count;
+    else
+        return desc->u.v_1_1.static_sampler_count;
+}
+
+static const struct vkd3d_static_sampler_desc *versioned_root_signature_get_static_samplers(
+        const struct vkd3d_versioned_root_signature_desc *desc)
+{
+    if (desc->version == VKD3D_ROOT_SIGNATURE_VERSION_1_0)
+        return desc->u.v_1_0.static_samplers;
+    else
+        return desc->u.v_1_1.static_samplers;
+}
+
+static unsigned int versioned_root_signature_get_flags(const struct vkd3d_versioned_root_signature_desc *desc)
+{
+    if (desc->version == VKD3D_ROOT_SIGNATURE_VERSION_1_0)
+        return desc->u.v_1_0.flags;
+    else
+        return desc->u.v_1_1.flags;
+}
+
 struct root_signature_writer_context
 {
     DWORD *data;
@@ -2619,6 +2679,31 @@ static int shader_write_descriptor_ranges(struct root_signature_writer_context *
     return VKD3D_OK;
 }
 
+static int shader_write_descriptor_ranges1(struct root_signature_writer_context *context,
+        const struct vkd3d_root_descriptor_table1 *table)
+{
+    const struct vkd3d_descriptor_range1 *ranges = table->descriptor_ranges;
+    unsigned int i;
+
+    for (i = 0; i < table->descriptor_range_count; ++i)
+    {
+        if (!write_dword(context, ranges[i].range_type))
+            return VKD3D_ERROR_OUT_OF_MEMORY;
+        if (!write_dword(context, ranges[i].descriptor_count))
+            return VKD3D_ERROR_OUT_OF_MEMORY;
+        if (!write_dword(context, ranges[i].base_shader_register))
+            return VKD3D_ERROR_OUT_OF_MEMORY;
+        if (!write_dword(context, ranges[i].register_space))
+            return VKD3D_ERROR_OUT_OF_MEMORY;
+        if (!write_dword(context, ranges[i].flags))
+            return VKD3D_ERROR_OUT_OF_MEMORY;
+        if (!write_dword(context, ranges[i].descriptor_table_offset))
+            return VKD3D_ERROR_OUT_OF_MEMORY;
+    }
+
+    return VKD3D_OK;
+}
+
 static int shader_write_descriptor_table(struct root_signature_writer_context *context,
         const struct vkd3d_root_descriptor_table *table)
 {
@@ -2630,6 +2715,17 @@ static int shader_write_descriptor_table(struct root_signature_writer_context *c
     return shader_write_descriptor_ranges(context, table);
 }
 
+static int shader_write_descriptor_table1(struct root_signature_writer_context *context,
+        const struct vkd3d_root_descriptor_table1 *table)
+{
+    if (!write_dword(context, table->descriptor_range_count))
+        return VKD3D_ERROR_OUT_OF_MEMORY;
+    if (!write_dword(context, get_chunk_offset(context) + sizeof(DWORD))) /* offset */
+        return VKD3D_ERROR_OUT_OF_MEMORY;
+
+    return shader_write_descriptor_ranges1(context, table);
+}
+
 static int shader_write_root_constants(struct root_signature_writer_context *context,
         const struct vkd3d_root_constants *constants)
 {
@@ -2654,44 +2750,63 @@ static int shader_write_root_descriptor(struct root_signature_writer_context *co
     return VKD3D_OK;
 }
 
+static int shader_write_root_descriptor1(struct root_signature_writer_context *context,
+        const struct vkd3d_root_descriptor1 *descriptor)
+{
+    if (!write_dword(context, descriptor->shader_register))
+        return VKD3D_ERROR_OUT_OF_MEMORY;
+    if (!write_dword(context, descriptor->register_space))
+        return VKD3D_ERROR_OUT_OF_MEMORY;
+    if (!write_dword(context, descriptor->flags))
+        return VKD3D_ERROR_OUT_OF_MEMORY;
+
+    return VKD3D_OK;
+}
+
 static int shader_write_root_parameters(struct root_signature_writer_context *context,
-        const struct vkd3d_root_signature_desc *desc)
+        const struct vkd3d_versioned_root_signature_desc *desc)
 {
-    const struct vkd3d_root_parameter *parameters = desc->parameters;
+    unsigned int parameter_count = versioned_root_signature_get_parameter_count(desc);
     size_t parameters_position;
     unsigned int i;
     int ret;
 
     parameters_position = context->position;
-    for (i = 0; i < desc->parameter_count; ++i)
+    for (i = 0; i < parameter_count; ++i)
     {
-        if (!write_dword(context, parameters[i].parameter_type))
+        if (!write_dword(context, versioned_root_signature_get_parameter_type(desc, i)))
             return VKD3D_ERROR_OUT_OF_MEMORY;
-        if (!write_dword(context, parameters[i].shader_visibility))
+        if (!write_dword(context, versioned_root_signature_get_parameter_shader_visibility(desc, i)))
             return VKD3D_ERROR_OUT_OF_MEMORY;
         if (!write_dword(context, 0xffffffff)) /* offset */
             return VKD3D_ERROR_OUT_OF_MEMORY;
     }
 
-    for (i = 0; i < desc->parameter_count; ++i)
+    for (i = 0; i < parameter_count; ++i)
     {
         context->data[parameters_position + 3 * i + 2] = get_chunk_offset(context); /* offset */
 
-        switch (parameters[i].parameter_type)
+        switch (versioned_root_signature_get_parameter_type(desc, i))
         {
             case VKD3D_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE:
-                ret = shader_write_descriptor_table(context, &parameters[i].u.descriptor_table);
+                if (desc->version == VKD3D_ROOT_SIGNATURE_VERSION_1_0)
+                    ret = shader_write_descriptor_table(context, &desc->u.v_1_0.parameters[i].u.descriptor_table);
+                else
+                    ret = shader_write_descriptor_table1(context, &desc->u.v_1_1.parameters[i].u.descriptor_table);
                 break;
             case VKD3D_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS:
-                ret = shader_write_root_constants(context, &parameters[i].u.constants);
+                ret = shader_write_root_constants(context, versioned_root_signature_get_root_constants(desc, i));
                 break;
             case VKD3D_ROOT_PARAMETER_TYPE_CBV:
             case VKD3D_ROOT_PARAMETER_TYPE_SRV:
             case VKD3D_ROOT_PARAMETER_TYPE_UAV:
-                ret = shader_write_root_descriptor(context, &parameters[i].u.descriptor);
+                if (desc->version == VKD3D_ROOT_SIGNATURE_VERSION_1_0)
+                    ret = shader_write_root_descriptor(context, &desc->u.v_1_0.parameters[i].u.descriptor);
+                else
+                    ret = shader_write_root_descriptor1(context, &desc->u.v_1_1.parameters[i].u.descriptor);
                 break;
             default:
-                FIXME("Unrecognized type %#x.\n", parameters[i].parameter_type);
+                FIXME("Unrecognized type %#x.\n", versioned_root_signature_get_parameter_type(desc, i));
                 return VKD3D_ERROR_INVALID_ARGUMENT;
         }
 
@@ -2703,12 +2818,12 @@ static int shader_write_root_parameters(struct root_signature_writer_context *co
 }
 
 static int shader_write_static_samplers(struct root_signature_writer_context *context,
-        const struct vkd3d_root_signature_desc *desc)
+        const struct vkd3d_versioned_root_signature_desc *desc)
 {
-    const struct vkd3d_static_sampler_desc *samplers = desc->static_samplers;
+    const struct vkd3d_static_sampler_desc *samplers = versioned_root_signature_get_static_samplers(desc);
     unsigned int i;
 
-    for (i = 0; i < desc->static_sampler_count; ++i)
+    for (i = 0; i < versioned_root_signature_get_static_sampler_count(desc); ++i)
     {
         if (!write_dword(context, samplers[i].filter))
             return VKD3D_ERROR_OUT_OF_MEMORY;
@@ -2742,26 +2857,26 @@ static int shader_write_static_samplers(struct root_signature_writer_context *co
 }
 
 static int shader_write_root_signature(struct root_signature_writer_context *context,
-        const struct vkd3d_root_signature_desc *desc)
+        const struct vkd3d_versioned_root_signature_desc *desc)
 {
     size_t samplers_offset_position;
     int ret;
 
-    if (!write_dword(context, 0x00000001))
+    if (!write_dword(context, desc->version))
         return VKD3D_ERROR_OUT_OF_MEMORY;
 
-    if (!write_dword(context, desc->parameter_count))
+    if (!write_dword(context, versioned_root_signature_get_parameter_count(desc)))
         return VKD3D_ERROR_OUT_OF_MEMORY;
     if (!write_dword(context, get_chunk_offset(context) + 4 * sizeof(DWORD))) /* offset */
         return VKD3D_ERROR_OUT_OF_MEMORY;
 
-    if (!write_dword(context, desc->static_sampler_count))
+    if (!write_dword(context, versioned_root_signature_get_static_sampler_count(desc)))
         return VKD3D_ERROR_OUT_OF_MEMORY;
     samplers_offset_position = context->position;
     if (!write_dword(context, 0xffffffff)) /* offset */
         return VKD3D_ERROR_OUT_OF_MEMORY;
 
-    if (!write_dword(context, desc->flags))
+    if (!write_dword(context, versioned_root_signature_get_flags(desc)))
         return VKD3D_ERROR_OUT_OF_MEMORY;
 
     if ((ret = shader_write_root_parameters(context, desc)) < 0)
@@ -2771,20 +2886,19 @@ static int shader_write_root_signature(struct root_signature_writer_context *con
     return shader_write_static_samplers(context, desc);
 }
 
-int vkd3d_shader_serialize_root_signature(const struct vkd3d_root_signature_desc *root_signature,
-        enum vkd3d_root_signature_version version, struct vkd3d_shader_code *dxbc)
+static int shader_serialize_root_signature(const struct vkd3d_versioned_root_signature_desc *root_signature,
+        struct vkd3d_shader_code *dxbc)
 {
     struct root_signature_writer_context context;
     size_t total_size, chunk_size;
     uint32_t checksum[4];
     int ret;
 
-    TRACE("root_signature %p, version %#x, dxbc %p.\n", root_signature, version, dxbc);
-
-    if (version != VKD3D_ROOT_SIGNATURE_VERSION_1_0)
+    if (root_signature->version != VKD3D_ROOT_SIGNATURE_VERSION_1_0
+            && root_signature->version != VKD3D_ROOT_SIGNATURE_VERSION_1_1)
     {
-        FIXME("Root signature version %#x not supported.\n", version);
-        return VKD3D_ERROR_NOT_IMPLEMENTED;
+        WARN("Root signature version %#x not supported.\n", root_signature->version);
+        return VKD3D_ERROR_INVALID_ARGUMENT;
     }
 
     memset(dxbc, 0, sizeof(*dxbc));
@@ -2815,6 +2929,33 @@ int vkd3d_shader_serialize_root_signature(const struct vkd3d_root_signature_desc
     return VKD3D_OK;
 }
 
+int vkd3d_shader_serialize_root_signature(const struct vkd3d_root_signature_desc *root_signature,
+        enum vkd3d_root_signature_version version, struct vkd3d_shader_code *dxbc)
+{
+    struct vkd3d_versioned_root_signature_desc versioned_root_signature;
+
+    TRACE("root_signature %p, version %#x, dxbc %p.\n", root_signature, version, dxbc);
+
+    if (version != VKD3D_ROOT_SIGNATURE_VERSION_1_0)
+    {
+        WARN("Unexpected Root signature version %#x.\n", version);
+        return VKD3D_ERROR_INVALID_ARGUMENT;
+    }
+
+    versioned_root_signature.version = VKD3D_ROOT_SIGNATURE_VERSION_1_0;
+    versioned_root_signature.u.v_1_0 = *root_signature;
+
+    return shader_serialize_root_signature(&versioned_root_signature, dxbc);
+}
+
+int vkd3d_shader_serialize_versioned_root_signature(const struct vkd3d_versioned_root_signature_desc *root_signature,
+        struct vkd3d_shader_code *dxbc)
+{
+    TRACE("root_signature %p, dxbc %p.\n", root_signature, dxbc);
+
+    return shader_serialize_root_signature(root_signature, dxbc);
+}
+
 static void free_descriptor_ranges(const struct vkd3d_root_parameter *parameters, unsigned int count)
 {
     unsigned int i;
diff --git a/libs/vkd3d-shader/vkd3d_shader.map b/libs/vkd3d-shader/vkd3d_shader.map
index 2959c5756223..30c2c76f6866 100644
--- a/libs/vkd3d-shader/vkd3d_shader.map
+++ b/libs/vkd3d-shader/vkd3d_shader.map
@@ -12,6 +12,7 @@ global:
     vkd3d_shader_parse_versioned_root_signature;
     vkd3d_shader_scan_dxbc;
     vkd3d_shader_serialize_root_signature;
+    vkd3d_shader_serialize_versioned_root_signature;
 
 local: *;
 };
-- 
2.21.0




More information about the wine-devel mailing list