From: Zebediah Figura zfigura@codeweavers.com
--- include/vkd3d_shader.h | 102 +++++++++++++++++++++++++- libs/vkd3d-shader/vkd3d_shader_main.c | 71 +++++++++++++++--- 2 files changed, 158 insertions(+), 15 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index d6653d18..83c39bc8 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -90,6 +90,11 @@ enum vkd3d_shader_structure_type * \since 1.9 */ VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO, + /** + * The structure is a vkd3d_shader_scan_descriptor_info1 structure. + * \since 1.9 + */ + VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO1,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE), }; @@ -1253,7 +1258,7 @@ struct vkd3d_shader_versioned_root_signature_desc
/** * The type of a shader resource, returned as part of struct - * vkd3d_shader_descriptor_info. + * vkd3d_shader_descriptor_info and struct vkd3d_shader_scan_descriptor_info1. */ enum vkd3d_shader_resource_type { @@ -1288,7 +1293,8 @@ enum vkd3d_shader_resource_type
/** * The type of the data contained in a shader resource, returned as part of - * struct vkd3d_shader_descriptor_info. All formats are 32-bit. + * struct vkd3d_shader_descriptor_info and + * struct vkd3d_shader_scan_descriptor_info1. All formats are 32-bit. */ enum vkd3d_shader_resource_data_type { @@ -1318,7 +1324,7 @@ enum vkd3d_shader_resource_data_type
/** * Additional flags describing a shader descriptor, returned as part of struct - * vkd3d_shader_descriptor_info. + * vkd3d_shader_descriptor_info and struct vkd3d_shader_scan_descriptor_info1. */ enum vkd3d_shader_descriptor_info_flag { @@ -1341,6 +1347,9 @@ enum vkd3d_shader_descriptor_info_flag /** * Describes a single shader descriptor; returned as part of * struct vkd3d_shader_scan_descriptor_info. + * + * struct vkd3d_shader_descriptor_info1 is an updated version of this + * structure which returns more information. */ struct vkd3d_shader_descriptor_info { @@ -1369,11 +1378,45 @@ struct vkd3d_shader_descriptor_info unsigned int count; };
+/** + * Describes a single shader descriptor; returned as part of + * struct vkd3d_shader_scan_descriptor_info1. + */ +struct vkd3d_shader_descriptor_info1 +{ + /** Type of the descriptor (for example, SRV, CBV, UAV, or sampler). */ + enum vkd3d_shader_descriptor_type type; + /** + * Register space of the resource, or 0 if the shader does not + * support multiple register spaces. + */ + unsigned int register_space; + /** Binding (register) index of the descriptor. */ + unsigned int register_index; + /** Resource type, if applicable, including its dimension. */ + enum vkd3d_shader_resource_type resource_type; + /** Data type contained in the resource (for example, float or integer). */ + enum vkd3d_shader_resource_data_type resource_data_type; + /** + * Bitwise combination of zero or more members of + * \ref vkd3d_shader_descriptor_info_flag. + */ + unsigned int flags; + /** + * Size of this descriptor array, or 1 if a single descriptor. + * For an unbounded array this value is ~0u. + */ + unsigned int count; +}; + /** * A chained structure enumerating the descriptors declared by a shader. * * This structure extends vkd3d_shader_compile_info. * + * struct vkd3d_shader_scan_descriptor_info1 is an updated version of this + * structure which returns more information. + * * When scanning a legacy Direct3D shader, vkd3d-shader enumerates each * constant register set used by the shader as a single constant buffer * descriptor, as follows: @@ -1403,6 +1446,42 @@ struct vkd3d_shader_scan_descriptor_info unsigned int descriptor_count; };
+/** + * A chained structure enumerating the descriptors declared by a shader. + * + * This structure extends vkd3d_shader_compile_info. + * + * When scanning a legacy Direct3D shader, vkd3d-shader enumerates each + * constant register set used by the shader as a single constant buffer + * descriptor, as follows: + * - The \ref vkd3d_shader_descriptor_info.type field is set to + * VKD3D_SHADER_DESCRIPTOR_TYPE_CBV. + * - The \ref vkd3d_shader_descriptor_info.register_space field is set to zero. + * - The \ref vkd3d_shader_descriptor_info.register_index field is set to a + * member of enum vkd3d_shader_d3dbc_constant_register denoting which set + * is used. + * - The \ref vkd3d_shader_descriptor_info.count field is set to one. + * + * In summary, there may be up to three such descriptors, one for each register + * set used by the shader: float, integer, and boolean. + * + * \since 1.9 + */ +struct vkd3d_shader_scan_descriptor_info1 +{ + /** + * Input; must be set to VKD3D_SHADER_STRUCTURE_TYPE_SCAN_DESCRIPTOR_INFO1. + */ + enum vkd3d_shader_structure_type type; + /** Input; optional pointer to a structure containing further parameters. */ + const void *next; + + /** Output; returns a pointer to an array of descriptors. */ + struct vkd3d_shader_descriptor_info1 *descriptors; + /** Output; size, in elements, of \ref descriptors. */ + unsigned int descriptor_count; +}; + /** * Data type of a shader varying, returned as part of struct * vkd3d_shader_signature_element. @@ -1750,6 +1829,7 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported * following chained structures: * - vkd3d_shader_interface_info * - vkd3d_shader_scan_descriptor_info + * - vkd3d_shader_scan_descriptor_info1 * - vkd3d_shader_scan_signature_info * - vkd3d_shader_spirv_domain_shader_target_info * - vkd3d_shader_spirv_target_info @@ -1937,6 +2017,7 @@ VKD3D_SHADER_API int vkd3d_shader_convert_root_signature(struct vkd3d_shader_ver * \n * The DXBC_TPF scanner supports the following chained structures: * - vkd3d_shader_scan_descriptor_info + * - vkd3d_shader_scan_descriptor_info1 * - vkd3d_shader_scan_signature_info * \n * Although the \a compile_info parameter is read-only, chained structures @@ -1961,8 +2042,9 @@ VKD3D_SHADER_API int vkd3d_shader_convert_root_signature(struct vkd3d_shader_ver * \return A member of \ref vkd3d_result. */ VKD3D_SHADER_API int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char **messages); + /** - * Free members of struct vkd3d_shader_scan_descriptor_info() allocated by + * Free members of struct vkd3d_shader_scan_descriptor_info allocated by * vkd3d_shader_scan(). * * This function may free members of vkd3d_shader_scan_descriptor_info, but @@ -1973,6 +2055,18 @@ VKD3D_SHADER_API int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *c VKD3D_SHADER_API void vkd3d_shader_free_scan_descriptor_info( struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info);
+/** + * Free members of struct vkd3d_shader_scan_descriptor_info1 allocated by + * vkd3d_shader_scan(). + * + * This function may free members of vkd3d_shader_scan_descriptor_info1, but + * does not free the structure itself. + * + * \param scan_descriptor_info Descriptor information to free. + */ +VKD3D_SHADER_API void vkd3d_shader_free_scan_descriptor_info1( + struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info); + /** * Read the input signature of a compiled DXBC shader, returning a structural * description which can be easily parsed by C code. diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index f7c8c6f8..60aea24c 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -579,7 +579,7 @@ static bool vkd3d_shader_signature_from_shader_signature(struct vkd3d_shader_sig
struct vkd3d_shader_scan_context { - struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info; + struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info; size_t descriptors_size;
struct vkd3d_shader_message_context *message_context; @@ -612,7 +612,7 @@ struct vkd3d_shader_scan_context
static void vkd3d_shader_scan_context_init(struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info, + struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info, struct vkd3d_shader_message_context *message_context) { unsigned int i; @@ -769,8 +769,8 @@ static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *c enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_resource_data_type resource_data_type, unsigned int flags) { - struct vkd3d_shader_scan_descriptor_info *info = context->scan_descriptor_info; - struct vkd3d_shader_descriptor_info *d; + struct vkd3d_shader_scan_descriptor_info1 *info = context->scan_descriptor_info; + struct vkd3d_shader_descriptor_info1 *d;
if (!vkd3d_array_reserve((void **)&info->descriptors, &context->descriptors_size, info->descriptor_count + 1, sizeof(*info->descriptors))) @@ -1104,24 +1104,57 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte return VKD3D_OK; }
+static enum vkd3d_result convert_descriptor_info(struct vkd3d_shader_scan_descriptor_info *info, + const struct vkd3d_shader_scan_descriptor_info1 *info1) +{ + unsigned int i; + + if (!(info->descriptors = vkd3d_malloc(info1->descriptor_count * sizeof(*info->descriptors)))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + for (i = 0; i < info1->descriptor_count; ++i) + { + const struct vkd3d_shader_descriptor_info1 *src = &info1->descriptors[i]; + struct vkd3d_shader_descriptor_info *dst = &info->descriptors[i]; + + dst->type = src->type; + dst->register_space = src->register_space; + dst->register_index = src->register_index; + dst->resource_type = src->resource_type; + dst->resource_data_type = src->resource_data_type; + dst->flags = src->flags; + dst->count = src->count; + } + info->descriptor_count = info1->descriptor_count; + + return VKD3D_OK; +} + static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser *parser) { - struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info; + struct vkd3d_shader_scan_descriptor_info1 *descriptor_info1, local_descriptor_info1 = {0}; + struct vkd3d_shader_scan_descriptor_info *descriptor_info; struct vkd3d_shader_scan_signature_info *signature_info; struct vkd3d_shader_instruction *instruction; struct vkd3d_shader_scan_context context; int ret = VKD3D_OK; unsigned int i;
- if ((scan_descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO))) + descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO); + descriptor_info1 = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO1); + if (descriptor_info1) { - scan_descriptor_info->descriptors = NULL; - scan_descriptor_info->descriptor_count = 0; + descriptor_info1->descriptors = NULL; + descriptor_info1->descriptor_count = 0; + } + else if (descriptor_info) + { + descriptor_info1 = &local_descriptor_info1; } signature_info = vkd3d_find_struct(compile_info->next, SCAN_SIGNATURE_INFO);
- vkd3d_shader_scan_context_init(&context, compile_info, scan_descriptor_info, message_context); + vkd3d_shader_scan_context_init(&context, compile_info, descriptor_info1, message_context);
if (TRACE_ON()) { @@ -1156,13 +1189,22 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info } }
+ if (!ret && descriptor_info) + ret = convert_descriptor_info(descriptor_info, descriptor_info1); + if (ret < 0) { - if (scan_descriptor_info) - vkd3d_shader_free_scan_descriptor_info(scan_descriptor_info); + if (descriptor_info) + vkd3d_shader_free_scan_descriptor_info(descriptor_info); + if (descriptor_info1) + vkd3d_shader_free_scan_descriptor_info1(descriptor_info1); if (signature_info) vkd3d_shader_free_scan_signature_info(signature_info); } + else + { + vkd3d_shader_free_scan_descriptor_info1(&local_descriptor_info1); + } vkd3d_shader_scan_context_cleanup(&context); return ret; } @@ -1451,6 +1493,13 @@ void vkd3d_shader_free_scan_descriptor_info(struct vkd3d_shader_scan_descriptor_ vkd3d_free(scan_descriptor_info->descriptors); }
+void vkd3d_shader_free_scan_descriptor_info1(struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info) +{ + TRACE("scan_descriptor_info %p.\n", scan_descriptor_info); + + vkd3d_free(scan_descriptor_info->descriptors); +} + void vkd3d_shader_free_scan_signature_info(struct vkd3d_shader_scan_signature_info *info) { TRACE("info %p.\n", info);