[PATCH vkd3d 4/5] vkd3d-shader: Implement conversion between root signature 1.0 and 1.1.

Józef Kucia joseph.kucia at gmail.com
Fri Apr 12 10:13:20 CDT 2019


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

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 include/vkd3d_shader.h             |   6 +
 libs/vkd3d-shader/dxbc.c           | 262 +++++++++++++++++++++++++++++
 libs/vkd3d-shader/vkd3d_shader.map |   1 +
 3 files changed, 269 insertions(+)

diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 506d519ea630..7bf3bd5e4514 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -578,6 +578,9 @@ void vkd3d_shader_free_versioned_root_signature(struct vkd3d_versioned_root_sign
 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_convert_root_signature(struct vkd3d_versioned_root_signature_desc *dst,
+        enum vkd3d_root_signature_version version, const struct vkd3d_versioned_root_signature_desc *src);
+
 int vkd3d_shader_scan_dxbc(const struct vkd3d_shader_code *dxbc,
         struct vkd3d_shader_scan_info *scan_info);
 
@@ -610,6 +613,9 @@ typedef void (*PFN_vkd3d_shader_free_versioned_root_signature)(struct vkd3d_vers
 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_convert_root_signature)(struct vkd3d_versioned_root_signature_desc *dst,
+        enum vkd3d_root_signature_version version, const struct vkd3d_versioned_root_signature_desc *src);
+
 typedef int (*PFN_vkd3d_shader_scan_dxbc)(const struct vkd3d_shader_code *dxbc,
         struct vkd3d_shader_scan_info *scan_info);
 
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index 06812d0152b8..f232f5cd0b7e 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -2093,6 +2093,11 @@ int shader_extract_from_dxbc(const void *dxbc, size_t dxbc_length,
 }
 
 /* root signatures */
+#define VKD3D_ROOT_SIGNATURE_1_0_ROOT_DESCRIPTOR_FLAGS VKD3D_ROOT_DESCRIPTOR_FLAG_DATA_VOLATILE
+
+#define VKD3D_ROOT_SIGNATURE_1_0_DESCRIPTOR_RANGE_FLAGS \
+        (VKD3D_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE | VKD3D_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE)
+
 struct root_signature_parser_context
 {
     const char *data;
@@ -2848,3 +2853,260 @@ int vkd3d_shader_serialize_root_signature(const struct vkd3d_root_signature_desc
 
     return VKD3D_OK;
 }
+
+static int convert_root_parameters_to_v_1_0(struct vkd3d_root_parameter *dst,
+        const struct vkd3d_root_parameter1 *src, unsigned int count)
+{
+    const struct vkd3d_descriptor_range1 *ranges1;
+    struct vkd3d_descriptor_range *ranges;
+    unsigned int i, j;
+    int ret;
+
+    for (i = 0; i < count; ++i)
+    {
+        const struct vkd3d_root_parameter1 *p1 = &src[i];
+        struct vkd3d_root_parameter *p = &dst[i];
+
+        p->parameter_type = p1->parameter_type;
+        switch (p->parameter_type)
+        {
+            case VKD3D_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE:
+                ranges = NULL;
+                if ((p->u.descriptor_table.descriptor_range_count = p1->u.descriptor_table.descriptor_range_count))
+                {
+                    if (!(ranges = vkd3d_calloc(p->u.descriptor_table.descriptor_range_count, sizeof(*ranges))))
+                    {
+                        ret = VKD3D_ERROR_OUT_OF_MEMORY;
+                        goto fail;
+                    }
+                }
+                p->u.descriptor_table.descriptor_ranges = ranges;
+                ranges1 = p1->u.descriptor_table.descriptor_ranges;
+                for (j = 0; j < p1->u.descriptor_table.descriptor_range_count; ++j)
+                {
+                    ranges[j].range_type = ranges1[j].range_type;
+                    ranges[j].descriptor_count = ranges1[j].descriptor_count;
+                    ranges[j].base_shader_register = ranges1[j].base_shader_register;
+                    ranges[j].register_space = ranges1[j].register_space;
+                    ranges[j].descriptor_table_offset = ranges1[j].descriptor_table_offset;
+                }
+                break;
+            case VKD3D_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS:
+                p->u.constants = p1->u.constants;
+                break;
+            case VKD3D_ROOT_PARAMETER_TYPE_CBV:
+            case VKD3D_ROOT_PARAMETER_TYPE_SRV:
+            case VKD3D_ROOT_PARAMETER_TYPE_UAV:
+                p->u.descriptor.shader_register = p1->u.descriptor.shader_register;
+                p->u.descriptor.register_space = p1->u.descriptor.register_space;
+                break;
+            default:
+                WARN("Invalid root parameter type %#x.\n", p->parameter_type);
+                ret = VKD3D_ERROR_INVALID_ARGUMENT;
+                goto fail;
+
+        }
+        p->shader_visibility = p1->shader_visibility;
+    }
+
+    return VKD3D_OK;
+
+fail:
+    for (j = 0; j < i; ++j)
+    {
+        const struct vkd3d_root_parameter *p = &dst[j];
+        if (p->parameter_type == VKD3D_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE)
+            vkd3d_free((void *)p->u.descriptor_table.descriptor_ranges);
+    }
+    return ret;
+}
+
+static int convert_root_signature_to_v1_0(struct vkd3d_versioned_root_signature_desc *dst,
+        const struct vkd3d_versioned_root_signature_desc *src)
+{
+    const struct vkd3d_root_signature_desc1 *src_desc = &src->u.v_1_1;
+    struct vkd3d_root_signature_desc *dst_desc = &dst->u.v_1_0;
+    struct vkd3d_static_sampler_desc *samplers = NULL;
+    struct vkd3d_root_parameter *parameters = NULL;
+    int ret;
+
+    if ((dst_desc->parameter_count = src_desc->parameter_count))
+    {
+        if (!(parameters = vkd3d_calloc(dst_desc->parameter_count, sizeof(*parameters))))
+        {
+            ret = VKD3D_ERROR_OUT_OF_MEMORY;
+            goto fail;
+        }
+        if ((ret = convert_root_parameters_to_v_1_0(parameters, src_desc->parameters, src_desc->parameter_count)) < 0)
+            goto fail;
+    }
+    dst_desc->parameters = parameters;
+    if ((dst_desc->static_sampler_count = src_desc->static_sampler_count))
+    {
+        if (!(samplers = vkd3d_calloc(dst_desc->static_sampler_count, sizeof(*samplers))))
+        {
+            ret = VKD3D_ERROR_OUT_OF_MEMORY;
+            goto fail;
+        }
+        memcpy(samplers, src_desc->static_samplers, src_desc->static_sampler_count * sizeof(*samplers));
+    }
+    dst_desc->static_samplers = samplers;
+    dst_desc->flags = src_desc->flags;
+
+    return VKD3D_OK;
+
+fail:
+    vkd3d_free(parameters);
+    vkd3d_free(samplers);
+    return ret;
+}
+
+static int convert_root_parameters_to_v_1_1(struct vkd3d_root_parameter1 *dst,
+        const struct vkd3d_root_parameter *src, unsigned int count)
+{
+    const struct vkd3d_descriptor_range *ranges;
+    struct vkd3d_descriptor_range1 *ranges1;
+    unsigned int i, j;
+    int ret;
+
+    for (i = 0; i < count; ++i)
+    {
+        const struct vkd3d_root_parameter *p = &src[i];
+        struct vkd3d_root_parameter1 *p1 = &dst[i];
+
+        p1->parameter_type = p->parameter_type;
+        switch (p1->parameter_type)
+        {
+            case VKD3D_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE:
+                ranges1 = NULL;
+                if ((p1->u.descriptor_table.descriptor_range_count = p->u.descriptor_table.descriptor_range_count))
+                {
+                    if (!(ranges1 = vkd3d_calloc(p1->u.descriptor_table.descriptor_range_count, sizeof(*ranges1))))
+                    {
+                        ret = VKD3D_ERROR_OUT_OF_MEMORY;
+                        goto fail;
+                    }
+                }
+                p1->u.descriptor_table.descriptor_ranges = ranges1;
+                ranges = p->u.descriptor_table.descriptor_ranges;
+                for (j = 0; j < p->u.descriptor_table.descriptor_range_count; ++j)
+                {
+                    ranges1[j].range_type = ranges[j].range_type;
+                    ranges1[j].descriptor_count = ranges[j].descriptor_count;
+                    ranges1[j].base_shader_register = ranges[j].base_shader_register;
+                    ranges1[j].register_space = ranges[j].register_space;
+                    ranges1[j].flags = VKD3D_ROOT_SIGNATURE_1_0_DESCRIPTOR_RANGE_FLAGS;
+                    ranges1[j].descriptor_table_offset = ranges[j].descriptor_table_offset;
+                }
+                break;
+            case VKD3D_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS:
+                p1->u.constants = p->u.constants;
+                break;
+            case VKD3D_ROOT_PARAMETER_TYPE_CBV:
+            case VKD3D_ROOT_PARAMETER_TYPE_SRV:
+            case VKD3D_ROOT_PARAMETER_TYPE_UAV:
+                p1->u.descriptor.shader_register = p->u.descriptor.shader_register;
+                p1->u.descriptor.register_space = p->u.descriptor.register_space;
+                p1->u.descriptor.flags = VKD3D_ROOT_SIGNATURE_1_0_ROOT_DESCRIPTOR_FLAGS;
+                break;
+            default:
+                WARN("Invalid root parameter type %#x.\n", p1->parameter_type);
+                ret = VKD3D_ERROR_INVALID_ARGUMENT;
+                goto fail;
+
+        }
+        p1->shader_visibility = p->shader_visibility;
+    }
+
+    return VKD3D_OK;
+
+fail:
+    for (j = 0; j < i; ++j)
+    {
+        const struct vkd3d_root_parameter1 *p = &dst[j];
+        if (p->parameter_type == VKD3D_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE)
+            vkd3d_free((void *)p->u.descriptor_table.descriptor_ranges);
+    }
+    return ret;
+}
+
+static int convert_root_signature_to_v1_1(struct vkd3d_versioned_root_signature_desc *dst,
+        const struct vkd3d_versioned_root_signature_desc *src)
+{
+    const struct vkd3d_root_signature_desc *src_desc = &src->u.v_1_0;
+    struct vkd3d_root_signature_desc1 *dst_desc = &dst->u.v_1_1;
+    struct vkd3d_static_sampler_desc *samplers = NULL;
+    struct vkd3d_root_parameter1 *parameters = NULL;
+    int ret;
+
+    if ((dst_desc->parameter_count = src_desc->parameter_count))
+    {
+        if (!(parameters = vkd3d_calloc(dst_desc->parameter_count, sizeof(*parameters))))
+        {
+            ret = VKD3D_ERROR_OUT_OF_MEMORY;
+            goto fail;
+        }
+        if ((ret = convert_root_parameters_to_v_1_1(parameters, src_desc->parameters, src_desc->parameter_count)) < 0)
+            goto fail;
+    }
+    dst_desc->parameters = parameters;
+    if ((dst_desc->static_sampler_count = src_desc->static_sampler_count))
+    {
+        if (!(samplers = vkd3d_calloc(dst_desc->static_sampler_count, sizeof(*samplers))))
+        {
+            ret = VKD3D_ERROR_OUT_OF_MEMORY;
+            goto fail;
+        }
+        memcpy(samplers, src_desc->static_samplers, src_desc->static_sampler_count * sizeof(*samplers));
+    }
+    dst_desc->static_samplers = samplers;
+    dst_desc->flags = src_desc->flags;
+
+    return VKD3D_OK;
+
+fail:
+    vkd3d_free(parameters);
+    vkd3d_free(samplers);
+    return ret;
+}
+
+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)
+{
+    int ret;
+
+    TRACE("dst %p, version %#x, src %p.\n", dst, version, src);
+
+    if (src->version == version)
+    {
+        WARN("Nothing to convert.\n");
+        return VKD3D_ERROR_INVALID_ARGUMENT;
+    }
+
+    if (version != VKD3D_ROOT_SIGNATURE_VERSION_1_0 && version != VKD3D_ROOT_SIGNATURE_VERSION_1_1)
+    {
+        WARN("Root signature version %#x not supported.\n", version);
+        return VKD3D_ERROR_INVALID_ARGUMENT;
+    }
+
+    if (src->version != VKD3D_ROOT_SIGNATURE_VERSION_1_0 && src->version != VKD3D_ROOT_SIGNATURE_VERSION_1_1)
+    {
+        WARN("Root signature version %#x not supported.\n", src->version);
+        return VKD3D_ERROR_INVALID_ARGUMENT;
+    }
+
+    memset(dst, 0, sizeof(*dst));
+    dst->version = version;
+
+    if (version == VKD3D_ROOT_SIGNATURE_VERSION_1_0)
+    {
+        ret = convert_root_signature_to_v1_0(dst, src);
+    }
+    else
+    {
+        assert(version == VKD3D_ROOT_SIGNATURE_VERSION_1_1);
+        ret = convert_root_signature_to_v1_1(dst, src);
+    }
+
+    return ret;
+}
diff --git a/libs/vkd3d-shader/vkd3d_shader.map b/libs/vkd3d-shader/vkd3d_shader.map
index 52ca4edcc50a..e1f1f1c179a2 100644
--- a/libs/vkd3d-shader/vkd3d_shader.map
+++ b/libs/vkd3d-shader/vkd3d_shader.map
@@ -2,6 +2,7 @@ VKD3D_1_0
 {
 global:
     vkd3d_shader_compile_dxbc;
+    vkd3d_shader_convert_root_signature;
     vkd3d_shader_find_signature_element;
     vkd3d_shader_free_root_signature;
     vkd3d_shader_free_shader_code;
-- 
2.21.0




More information about the wine-devel mailing list