From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
include/vkd3d_shader.h | 82 +++++++
libs/vkd3d-shader/dxbc.c | 319 +++++++++++++++++++++-----
libs/vkd3d-shader/vkd3d_shader.map | 2 +
libs/vkd3d-shader/vkd3d_shader_main.c | 35 +++
4 files changed, 382 insertions(+), 56 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 15a0b22d64dc..506d519ea630 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -216,6 +216,7 @@ struct vkd3d_shader_domain_shader_compile_arguments
enum vkd3d_tessellator_output_primitive partitioning;
};
+/* root signature 1.0 */
enum vkd3d_filter
{
VKD3D_FILTER_MIN_MAG_MIP_POINT = 0x0,
@@ -393,13 +394,86 @@ struct vkd3d_root_signature_desc
enum vkd3d_root_signature_flags flags;
};
+/* root signature 1.1 */
+enum vkd3d_root_descriptor_flags
+{
+ VKD3D_ROOT_DESCRIPTOR_FLAG_NONE = 0x0,
+ VKD3D_ROOT_DESCRIPTOR_FLAG_DATA_VOLATILE = 0x2,
+ VKD3D_ROOT_DESCRIPTOR_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
+ VKD3D_ROOT_DESCRIPTOR_FLAG_DATA_STATIC = 0x8,
+};
+
+enum vkd3d_descriptor_range_flags
+{
+ VKD3D_DESCRIPTOR_RANGE_FLAG_NONE = 0x0,
+ VKD3D_DESCRIPTOR_RANGE_FLAG_DESCRIPTORS_VOLATILE = 0x1,
+ VKD3D_DESCRIPTOR_RANGE_FLAG_DATA_VOLATILE = 0x2,
+ VKD3D_DESCRIPTOR_RANGE_FLAG_DATA_STATIC_WHILE_SET_AT_EXECUTE = 0x4,
+ VKD3D_DESCRIPTOR_RANGE_FLAG_DATA_STATIC = 0x8,
+};
+
+struct vkd3d_descriptor_range1
+{
+ enum vkd3d_descriptor_range_type range_type;
+ unsigned int descriptor_count;
+ unsigned int base_shader_register;
+ unsigned int register_space;
+ enum vkd3d_descriptor_range_flags flags;
+ unsigned int descriptor_table_offset;
+};
+
+struct vkd3d_root_descriptor_table1
+{
+ unsigned int descriptor_range_count;
+ const struct vkd3d_descriptor_range1 *descriptor_ranges;
+};
+
+struct vkd3d_root_descriptor1
+{
+ unsigned int shader_register;
+ unsigned int register_space;
+ enum vkd3d_root_descriptor_flags flags;
+};
+
+struct vkd3d_root_parameter1
+{
+ enum vkd3d_root_parameter_type parameter_type;
+ union
+ {
+ struct vkd3d_root_descriptor_table1 descriptor_table;
+ struct vkd3d_root_constants constants;
+ struct vkd3d_root_descriptor1 descriptor;
+ } u;
+ enum vkd3d_shader_visibility shader_visibility;
+};
+
+struct vkd3d_root_signature_desc1
+{
+ unsigned int parameter_count;
+ const struct vkd3d_root_parameter1 *parameters;
+ unsigned int static_sampler_count;
+ const struct vkd3d_static_sampler_desc *static_samplers;
+ enum vkd3d_root_signature_flags flags;
+};
+
enum vkd3d_root_signature_version
{
VKD3D_ROOT_SIGNATURE_VERSION_1_0 = 0x1,
+ VKD3D_ROOT_SIGNATURE_VERSION_1_1 = 0x2,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_ROOT_SIGNATURE_VERSION),
};
+struct vkd3d_versioned_root_signature_desc
+{
+ enum vkd3d_root_signature_version version;
+ union
+ {
+ struct vkd3d_root_signature_desc v_1_0;
+ struct vkd3d_root_signature_desc1 v_1_1;
+ } u;
+};
+
/* FIXME: Add support for 64 UAV bind slots. */
#define VKD3D_SHADER_MAX_UNORDERED_ACCESS_VIEWS 8
@@ -496,6 +570,10 @@ int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc,
struct vkd3d_root_signature_desc *root_signature);
void vkd3d_shader_free_root_signature(struct vkd3d_root_signature_desc *root_signature);
+int vkd3d_shader_parse_versioned_root_signature(const struct vkd3d_shader_code *dxbc,
+ struct vkd3d_versioned_root_signature_desc *root_signature);
+void vkd3d_shader_free_versioned_root_signature(struct vkd3d_versioned_root_signature_desc *root_signature);
+
/* FIXME: Add support for returning error messages (ID3DBlob). */
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);
@@ -525,6 +603,10 @@ typedef int (*PFN_vkd3d_shader_parse_root_signature)(const struct vkd3d_shader_c
struct vkd3d_root_signature_desc *root_signature);
typedef void (*PFN_vkd3d_shader_free_root_signature)(struct vkd3d_root_signature_desc *root_signature);
+typedef int (*PFN_vkd3d_shader_parse_versioned_root_signature)(const struct vkd3d_shader_code *dxbc,
+ struct vkd3d_versioned_root_signature_desc *root_signature);
+typedef void (*PFN_vkd3d_shader_free_versioned_root_signature)(struct vkd3d_versioned_root_signature_desc *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);
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index 996a7e544c1e..06812d0152b8 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -1799,6 +1799,11 @@ static void read_float(const char **ptr, float *f)
read_dword(ptr, (DWORD *)f);
}
+static void skip_dword(const char **ptr, unsigned int count)
+{
+ *ptr += count * sizeof(DWORD);
+}
+
static void skip_dword_unknown(const char **ptr, unsigned int count)
{
unsigned int i;
@@ -2087,18 +2092,28 @@ int shader_extract_from_dxbc(const void *dxbc, size_t dxbc_length,
return ret;
}
-static int shader_parse_descriptor_ranges(const char *data, DWORD data_size,
- DWORD offset, DWORD count, struct vkd3d_descriptor_range *ranges)
+/* root signatures */
+struct root_signature_parser_context
{
+ const char *data;
+ unsigned int data_size;
+
+ enum vkd3d_root_signature_version version;
+};
+
+static int shader_parse_descriptor_ranges(struct root_signature_parser_context *context,
+ unsigned int offset, unsigned int count, struct vkd3d_descriptor_range *ranges)
+{
+ unsigned int element_size = context->version >= VKD3D_ROOT_SIGNATURE_VERSION_1_1 ? 6: 5;
const char *ptr;
unsigned int i;
- if (!require_space(offset, 5 * count, sizeof(DWORD), data_size))
+ if (!require_space(offset, element_size * count, sizeof(DWORD), context->data_size))
{
- WARN("Invalid data size %#x (offset %u, count %u).\n", data_size, offset, count);
+ WARN("Invalid data size %#x (offset %u, count %u).\n", context->data_size, offset, count);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
- ptr = &data[offset];
+ ptr = &context->data[offset];
for (i = 0; i < count; ++i)
{
@@ -2106,6 +2121,8 @@ static int shader_parse_descriptor_ranges(const char *data, DWORD data_size,
read_dword(&ptr, &ranges[i].descriptor_count);
read_dword(&ptr, &ranges[i].base_shader_register);
read_dword(&ptr, &ranges[i].register_space);
+ if (context->version >= VKD3D_ROOT_SIGNATURE_VERSION_1_1)
+ skip_dword(&ptr, 1);
read_dword(&ptr, &ranges[i].descriptor_table_offset);
TRACE("Type %#x, descriptor count %u, base shader register %u, "
@@ -2118,19 +2135,52 @@ static int shader_parse_descriptor_ranges(const char *data, DWORD data_size,
return VKD3D_OK;
}
-static int shader_parse_descriptor_table(const char *data, DWORD data_size,
- DWORD offset, struct vkd3d_root_descriptor_table *table)
+static int shader_parse_descriptor_ranges1(struct root_signature_parser_context *context,
+ unsigned int offset, unsigned int count, struct vkd3d_descriptor_range1 *ranges)
+{
+ const char *ptr;
+ unsigned int i;
+
+ assert(context->version == VKD3D_ROOT_SIGNATURE_VERSION_1_1);
+ if (!require_space(offset, 6 * count, sizeof(uint32_t), context->data_size))
+ {
+ WARN("Invalid data size %#x (offset %u, count %u).\n", context->data_size, offset, count);
+ return VKD3D_ERROR_INVALID_ARGUMENT;
+ }
+ ptr = &context->data[offset];
+
+ for (i = 0; i < count; ++i)
+ {
+ read_dword(&ptr, &ranges[i].range_type);
+ read_dword(&ptr, &ranges[i].descriptor_count);
+ read_dword(&ptr, &ranges[i].base_shader_register);
+ read_dword(&ptr, &ranges[i].register_space);
+ read_dword(&ptr, &ranges[i].flags);
+ read_dword(&ptr, &ranges[i].descriptor_table_offset);
+
+ TRACE("Type %#x, descriptor count %u, base shader register %u, "
+ "register space %u, flags %#x, offset %u.\n",
+ ranges[i].range_type, ranges[i].descriptor_count,
+ ranges[i].base_shader_register, ranges[i].register_space,
+ ranges[i].flags, ranges[i].descriptor_table_offset);
+ }
+
+ return VKD3D_OK;
+}
+
+static int shader_parse_descriptor_table(struct root_signature_parser_context *context,
+ unsigned int offset, struct vkd3d_root_descriptor_table *table)
{
struct vkd3d_descriptor_range *ranges;
+ unsigned int count;
const char *ptr;
- DWORD count;
- if (!require_space(offset, 2, sizeof(DWORD), data_size))
+ if (!require_space(offset, 2, sizeof(DWORD), context->data_size))
{
- WARN("Invalid data size %#x (offset %u).\n", data_size, offset);
+ WARN("Invalid data size %#x (offset %u).\n", context->data_size, offset);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
- ptr = &data[offset];
+ ptr = &context->data[offset];
read_dword(&ptr, &count);
read_dword(&ptr, &offset);
@@ -2142,20 +2192,47 @@ static int shader_parse_descriptor_table(const char *data, DWORD data_size,
if (!(ranges = vkd3d_calloc(count, sizeof(*ranges))))
return VKD3D_ERROR_OUT_OF_MEMORY;
table->descriptor_ranges = ranges;
- return shader_parse_descriptor_ranges(data, data_size, offset, count, ranges);
+ return shader_parse_descriptor_ranges(context, offset, count, ranges);
}
-static int shader_parse_root_constants(const char *data, DWORD data_size,
- DWORD offset, struct vkd3d_root_constants *constants)
+static int shader_parse_descriptor_table1(struct root_signature_parser_context *context,
+ unsigned int offset, struct vkd3d_root_descriptor_table1 *table)
{
+ struct vkd3d_descriptor_range1 *ranges;
+ unsigned int count;
const char *ptr;
- if (!require_space(offset, 3, sizeof(DWORD), data_size))
+ if (!require_space(offset, 2, sizeof(DWORD), context->data_size))
{
- WARN("Invalid data size %#x (offset %u).\n", data_size, offset);
+ WARN("Invalid data size %#x (offset %u).\n", context->data_size, offset);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
- ptr = &data[offset];
+ ptr = &context->data[offset];
+
+ read_dword(&ptr, &count);
+ read_dword(&ptr, &offset);
+
+ TRACE("Descriptor range count %u.\n", count);
+
+ table->descriptor_range_count = count;
+
+ if (!(ranges = vkd3d_calloc(count, sizeof(*ranges))))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ table->descriptor_ranges = ranges;
+ return shader_parse_descriptor_ranges1(context, offset, count, ranges);
+}
+
+static int shader_parse_root_constants(struct root_signature_parser_context *context,
+ unsigned int offset, struct vkd3d_root_constants *constants)
+{
+ const char *ptr;
+
+ if (!require_space(offset, 3, sizeof(DWORD), context->data_size))
+ {
+ WARN("Invalid data size %#x (offset %u).\n", context->data_size, offset);
+ return VKD3D_ERROR_INVALID_ARGUMENT;
+ }
+ ptr = &context->data[offset];
read_dword(&ptr, &constants->shader_register);
read_dword(&ptr, &constants->register_space);
@@ -2167,20 +2244,23 @@ static int shader_parse_root_constants(const char *data, DWORD data_size,
return VKD3D_OK;
}
-static int shader_parse_root_descriptor(const char *data, DWORD data_size,
- DWORD offset, struct vkd3d_root_descriptor *descriptor)
+static int shader_parse_root_descriptor(struct root_signature_parser_context *context,
+ unsigned int offset, struct vkd3d_root_descriptor *descriptor)
{
+ unsigned int element_size = context->version >= VKD3D_ROOT_SIGNATURE_VERSION_1_1 ? 3: 2;
const char *ptr;
- if (!require_space(offset, 2, sizeof(DWORD), data_size))
+ if (!require_space(offset, element_size, sizeof(DWORD), context->data_size))
{
- WARN("Invalid data size %#x (offset %u).\n", data_size, offset);
+ WARN("Invalid data size %#x (offset %u).\n", context->data_size, offset);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
- ptr = &data[offset];
+ ptr = &context->data[offset];
read_dword(&ptr, &descriptor->shader_register);
read_dword(&ptr, &descriptor->register_space);
+ if (context->version >= VKD3D_ROOT_SIGNATURE_VERSION_1_1)
+ skip_dword(&ptr, 1);
TRACE("Shader register %u, register space %u.\n",
descriptor->shader_register, descriptor->register_space);
@@ -2188,19 +2268,90 @@ static int shader_parse_root_descriptor(const char *data, DWORD data_size,
return VKD3D_OK;
}
-static int shader_parse_root_parameters(const char *data, DWORD data_size,
- DWORD offset, DWORD count, struct vkd3d_root_parameter *parameters)
+static int shader_parse_root_descriptor1(struct root_signature_parser_context *context,
+ unsigned int offset, struct vkd3d_root_descriptor1 *descriptor)
+{
+ const char *ptr;
+
+ assert(context->version == VKD3D_ROOT_SIGNATURE_VERSION_1_1);
+ if (!require_space(offset, 3, sizeof(DWORD), context->data_size))
+ {
+ WARN("Invalid data size %#x (offset %u).\n", context->data_size, offset);
+ return VKD3D_ERROR_INVALID_ARGUMENT;
+ }
+ ptr = &context->data[offset];
+
+ read_dword(&ptr, &descriptor->shader_register);
+ read_dword(&ptr, &descriptor->register_space);
+ read_dword(&ptr, &descriptor->flags);
+
+ TRACE("Shader register %u, register space %u, flags %#x.\n",
+ descriptor->shader_register, descriptor->register_space, descriptor->flags);
+
+ return VKD3D_OK;
+}
+
+static int shader_parse_root_parameters(struct root_signature_parser_context *context,
+ unsigned int offset, unsigned int count, struct vkd3d_root_parameter *parameters)
+{
+ const char *ptr;
+ unsigned int i;
+ int ret;
+
+ if (!require_space(offset, 3 * count, sizeof(DWORD), context->data_size))
+ {
+ WARN("Invalid data size %#x (offset %u, count %u).\n", context->data_size, offset, count);
+ return VKD3D_ERROR_INVALID_ARGUMENT;
+ }
+ ptr = &context->data[offset];
+
+ for (i = 0; i < count; ++i)
+ {
+ read_dword(&ptr, ¶meters[i].parameter_type);
+ read_dword(&ptr, ¶meters[i].shader_visibility);
+ read_dword(&ptr, &offset);
+
+ TRACE("Type %#x, shader visibility %#x.\n",
+ parameters[i].parameter_type, parameters[i].shader_visibility);
+
+ switch (parameters[i].parameter_type)
+ {
+ case VKD3D_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE:
+ ret = shader_parse_descriptor_table(context, offset, ¶meters[i].u.descriptor_table);
+ break;
+ case VKD3D_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS:
+ ret = shader_parse_root_constants(context, offset, ¶meters[i].u.constants);
+ break;
+ case VKD3D_ROOT_PARAMETER_TYPE_CBV:
+ case VKD3D_ROOT_PARAMETER_TYPE_SRV:
+ case VKD3D_ROOT_PARAMETER_TYPE_UAV:
+ ret = shader_parse_root_descriptor(context, offset, ¶meters[i].u.descriptor);
+ break;
+ default:
+ FIXME("Unrecognized type %#x.\n", parameters[i].parameter_type);
+ return VKD3D_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (ret < 0)
+ return ret;
+ }
+
+ return VKD3D_OK;
+}
+
+static int shader_parse_root_parameters1(struct root_signature_parser_context *context,
+ DWORD offset, DWORD count, struct vkd3d_root_parameter1 *parameters)
{
const char *ptr;
unsigned int i;
int ret;
- if (!require_space(offset, 3 * count, sizeof(DWORD), data_size))
+ if (!require_space(offset, 3 * count, sizeof(DWORD), context->data_size))
{
- WARN("Invalid data size %#x (offset %u, count %u).\n", data_size, offset, count);
+ WARN("Invalid data size %#x (offset %u, count %u).\n", context->data_size, offset, count);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
- ptr = &data[offset];
+ ptr = &context->data[offset];
for (i = 0; i < count; ++i)
{
@@ -2214,15 +2365,15 @@ static int shader_parse_root_parameters(const char *data, DWORD data_size,
switch (parameters[i].parameter_type)
{
case VKD3D_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE:
- ret = shader_parse_descriptor_table(data, data_size, offset, ¶meters[i].u.descriptor_table);
+ ret = shader_parse_descriptor_table1(context, offset, ¶meters[i].u.descriptor_table);
break;
case VKD3D_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS:
- ret = shader_parse_root_constants(data, data_size, offset, ¶meters[i].u.constants);
+ ret = shader_parse_root_constants(context, offset, ¶meters[i].u.constants);
break;
case VKD3D_ROOT_PARAMETER_TYPE_CBV:
case VKD3D_ROOT_PARAMETER_TYPE_SRV:
case VKD3D_ROOT_PARAMETER_TYPE_UAV:
- ret = shader_parse_root_descriptor(data, data_size, offset, ¶meters[i].u.descriptor);
+ ret = shader_parse_root_descriptor1(context, offset, ¶meters[i].u.descriptor);
break;
default:
FIXME("Unrecognized type %#x.\n", parameters[i].parameter_type);
@@ -2236,18 +2387,18 @@ static int shader_parse_root_parameters(const char *data, DWORD data_size,
return VKD3D_OK;
}
-static int shader_parse_static_samplers(const char *data, DWORD data_size,
- DWORD offset, DWORD count, struct vkd3d_static_sampler_desc *sampler_descs)
+static int shader_parse_static_samplers(struct root_signature_parser_context *context,
+ unsigned int offset, unsigned int count, struct vkd3d_static_sampler_desc *sampler_descs)
{
const char *ptr;
unsigned int i;
- if (!require_space(offset, 13 * count, sizeof(DWORD), data_size))
+ if (!require_space(offset, 13 * count, sizeof(DWORD), context->data_size))
{
- WARN("Invalid data size %#x (offset %u, count %u).\n", data_size, offset, count);
+ WARN("Invalid data size %#x (offset %u, count %u).\n", context->data_size, offset, count);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
- ptr = &data[offset];
+ ptr = &context->data[offset];
for (i = 0; i < count; ++i)
{
@@ -2269,60 +2420,94 @@ static int shader_parse_static_samplers(const char *data, DWORD data_size,
return VKD3D_OK;
}
-static int shader_parse_root_signature(const char *data, DWORD data_size,
- struct vkd3d_root_signature_desc *desc)
+static int shader_parse_root_signature(const char *data, unsigned int data_size,
+ struct vkd3d_versioned_root_signature_desc *desc)
{
+ struct vkd3d_root_signature_desc *v_1_0 = &desc->u.v_1_0;
+ struct root_signature_parser_context context;
+ unsigned int count, offset, version;
const char *ptr = data;
- DWORD count, offset;
int ret;
+ context.data = data;
+ context.data_size = data_size;
+
if (!require_space(0, 6, sizeof(DWORD), data_size))
{
WARN("Invalid data size %#x.\n", data_size);
return VKD3D_ERROR_INVALID_ARGUMENT;
}
- skip_dword_unknown(&ptr, 1); /* It seems to always be 0x00000001. */
+ read_dword(&ptr, &version);
+ TRACE("Version %#x.\n", version);
+ if (version != VKD3D_ROOT_SIGNATURE_VERSION_1_0 && version != VKD3D_ROOT_SIGNATURE_VERSION_1_1)
+ {
+ FIXME("Unknown version %#x.\n", version);
+ return VKD3D_ERROR_INVALID_ARGUMENT;
+ }
+ context.version = version;
+ if (!desc->version)
+ desc->version = version;
read_dword(&ptr, &count);
read_dword(&ptr, &offset);
TRACE("Parameter count %u, offset %u.\n", count, offset);
- desc->parameter_count = count;
- if (desc->parameter_count)
+ if (desc->version == VKD3D_ROOT_SIGNATURE_VERSION_1_0)
{
- struct vkd3d_root_parameter *parameters;
- if (!(parameters = vkd3d_calloc(desc->parameter_count, sizeof(*parameters))))
- return VKD3D_ERROR_OUT_OF_MEMORY;
- desc->parameters = parameters;
- if ((ret = shader_parse_root_parameters(data, data_size, offset, count, parameters)) < 0)
- return ret;
+ v_1_0->parameter_count = count;
+ if (v_1_0->parameter_count)
+ {
+ struct vkd3d_root_parameter *parameters;
+ if (!(parameters = vkd3d_calloc(v_1_0->parameter_count, sizeof(*parameters))))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ v_1_0->parameters = parameters;
+ if ((ret = shader_parse_root_parameters(&context, offset, count, parameters)) < 0)
+ return ret;
+ }
+ }
+ else
+ {
+ struct vkd3d_root_signature_desc1 *v_1_1 = &desc->u.v_1_1;
+
+ assert(version == VKD3D_ROOT_SIGNATURE_VERSION_1_1);
+
+ v_1_1->parameter_count = count;
+ if (v_1_1->parameter_count)
+ {
+ struct vkd3d_root_parameter1 *parameters;
+ if (!(parameters = vkd3d_calloc(v_1_1->parameter_count, sizeof(*parameters))))
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ v_1_1->parameters = parameters;
+ if ((ret = shader_parse_root_parameters1(&context, offset, count, parameters)) < 0)
+ return ret;
+ }
}
read_dword(&ptr, &count);
read_dword(&ptr, &offset);
TRACE("Static sampler count %u, offset %u.\n", count, offset);
- desc->static_sampler_count = count;
- if (desc->static_sampler_count)
+ v_1_0->static_sampler_count = count;
+ if (v_1_0->static_sampler_count)
{
struct vkd3d_static_sampler_desc *samplers;
- if (!(samplers = vkd3d_calloc(desc->static_sampler_count, sizeof(*samplers))))
+ if (!(samplers = vkd3d_calloc(v_1_0->static_sampler_count, sizeof(*samplers))))
return VKD3D_ERROR_OUT_OF_MEMORY;
- desc->static_samplers = samplers;
- if ((ret = shader_parse_static_samplers(data, data_size, offset, count, samplers)) < 0)
+ v_1_0->static_samplers = samplers;
+ if ((ret = shader_parse_static_samplers(&context, offset, count, samplers)) < 0)
return ret;
}
- read_dword(&ptr, &desc->flags);
- TRACE("Flags %#x.\n", desc->flags);
+ read_dword(&ptr, &v_1_0->flags);
+ TRACE("Flags %#x.\n", v_1_0->flags);
return VKD3D_OK;
}
static int rts0_handler(const char *data, DWORD data_size, DWORD tag, void *context)
{
- struct vkd3d_root_signature_desc *desc = context;
+ struct vkd3d_versioned_root_signature_desc *desc = context;
if (tag != TAG_RTS0)
return VKD3D_OK;
@@ -2332,6 +2517,28 @@ static int rts0_handler(const char *data, DWORD data_size, DWORD tag, void *cont
int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc,
struct vkd3d_root_signature_desc *root_signature)
+{
+ struct vkd3d_versioned_root_signature_desc desc = {.version = VKD3D_ROOT_SIGNATURE_VERSION_1_0};
+ int ret;
+
+ TRACE("dxbc {%p, %zu}, root_signature %p.\n", dxbc->code, dxbc->size, root_signature);
+
+ memset(root_signature, 0, sizeof(*root_signature));
+ if ((ret = parse_dxbc(dxbc->code, dxbc->size, rts0_handler, &desc)) < 0)
+ {
+ vkd3d_shader_free_versioned_root_signature(&desc);
+ return ret;
+ }
+
+ assert(desc.version == VKD3D_ROOT_SIGNATURE_VERSION_1_0);
+
+ *root_signature = desc.u.v_1_0;
+
+ return VKD3D_OK;
+}
+
+int vkd3d_shader_parse_versioned_root_signature(const struct vkd3d_shader_code *dxbc,
+ struct vkd3d_versioned_root_signature_desc *root_signature)
{
int ret;
@@ -2340,7 +2547,7 @@ int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc,
memset(root_signature, 0, sizeof(*root_signature));
if ((ret = parse_dxbc(dxbc->code, dxbc->size, rts0_handler, root_signature)) < 0)
{
- vkd3d_shader_free_root_signature(root_signature);
+ vkd3d_shader_free_versioned_root_signature(root_signature);
return ret;
}
diff --git a/libs/vkd3d-shader/vkd3d_shader.map b/libs/vkd3d-shader/vkd3d_shader.map
index 92e4d06b0095..52ca4edcc50a 100644
--- a/libs/vkd3d-shader/vkd3d_shader.map
+++ b/libs/vkd3d-shader/vkd3d_shader.map
@@ -6,8 +6,10 @@ global:
vkd3d_shader_free_root_signature;
vkd3d_shader_free_shader_code;
vkd3d_shader_free_shader_signature;
+ vkd3d_shader_free_versioned_root_signature;
vkd3d_shader_parse_input_signature;
vkd3d_shader_parse_root_signature;
+ vkd3d_shader_parse_versioned_root_signature;
vkd3d_shader_scan_dxbc;
vkd3d_shader_serialize_root_signature;
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 55cb56c2e191..d56794105829 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -344,6 +344,41 @@ void vkd3d_shader_free_root_signature(struct vkd3d_root_signature_desc *root_sig
memset(root_signature, 0, sizeof(*root_signature));
}
+void vkd3d_shader_free_versioned_root_signature(struct vkd3d_versioned_root_signature_desc *desc)
+{
+ struct vkd3d_root_signature_desc1 *root_signature;
+ unsigned int i;
+
+ if (!desc->version)
+ return;
+
+ if (desc->version == VKD3D_ROOT_SIGNATURE_VERSION_1_0)
+ {
+ vkd3d_shader_free_root_signature(&desc->u.v_1_0);
+ return;
+ }
+
+ if (desc->version != VKD3D_ROOT_SIGNATURE_VERSION_1_1)
+ {
+ FIXME("Unknown version %#x.\n", desc->version);
+ return;
+ }
+
+ root_signature = &desc->u.v_1_1;
+
+ for (i = 0; i < root_signature->parameter_count; ++i)
+ {
+ const struct vkd3d_root_parameter1 *parameter = &root_signature->parameters[i];
+
+ if (parameter->parameter_type == VKD3D_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE)
+ vkd3d_free((void *)parameter->u.descriptor_table.descriptor_ranges);
+ }
+ vkd3d_free((void *)root_signature->parameters);
+ vkd3d_free((void *)root_signature->static_samplers);
+
+ memset(root_signature, 0, sizeof(*root_signature));
+}
+
int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
struct vkd3d_shader_signature *signature)
{
--
2.21.0