From: Henri Verbeet hverbeet@codeweavers.com
--- include/vkd3d_shader.h | 31 ++++++++++++++++++++++++++++++ libs/vkd3d-shader/dxbc.c | 29 +++++++++++++++++++--------- libs/vkd3d-shader/vkd3d_shader.map | 1 + 3 files changed, 52 insertions(+), 9 deletions(-)
diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index e6f47a73..167b8338 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -1942,6 +1942,34 @@ VKD3D_SHADER_API void vkd3d_shader_free_dxbc(struct vkd3d_shader_dxbc_desc *dxbc VKD3D_SHADER_API int vkd3d_shader_parse_dxbc(const struct vkd3d_shader_code *dxbc, uint32_t flags, struct vkd3d_shader_dxbc_desc *desc, char **messages);
+/** + * Serialise a DXBC description into a blob stored in a vkd3d_shader_code + * structure. + * + * \param section_count The number of DXBC sections to serialise. + * + * \param sections An array of vkd3d_shader_dxbc_section_desc structures + * to serialise. + * + * \param dxbc A pointer to a vkd3d_shader_code structure in which the + * serialised blob will be stored. + * \n + * The output blob is allocated by vkd3d-shader and should be freed with + * vkd3d_shader_free_shader_code() when no longer needed. + * + * \param messages Optional output location for error or informational messages + * produced by the serialiser. + * \n + * This parameter behaves identically to the \a messages parameter of + * vkd3d_shader_compile(). + * + * \return A member of \ref vkd3d_result. + * + * \since 1.7 + */ +VKD3D_SHADER_API int vkd3d_shader_serialize_dxbc(size_t section_count, + const struct vkd3d_shader_dxbc_section_desc *sections, struct vkd3d_shader_code *dxbc, char **messages); + #endif /* VKD3D_SHADER_NO_PROTOTYPES */
/** Type of vkd3d_shader_get_version(). */ @@ -2003,6 +2031,9 @@ typedef void (*PFN_vkd3d_shader_free_dxbc)(struct vkd3d_shader_dxbc_desc *dxbc); /** Type of vkd3d_shader_parse_dxbc(). \since 1.7 */ typedef int (*PFN_vkd3d_shader_parse_dxbc)(const struct vkd3d_shader_code *dxbc, uint32_t flags, struct vkd3d_shader_dxbc_desc *desc, char **messages); +/** Type of vkd3d_shader_serialize_dxbc(). \since 1.7 */ +typedef int (*PFN_vkd3d_shader_serialize_dxbc)(size_t section_count, + const struct vkd3d_shader_dxbc_section_desc *sections, struct vkd3d_shader_code *dxbc, char **messages);
#ifdef __cplusplus } diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c index 8dfb9408..d8eef8a5 100644 --- a/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d-shader/dxbc.c @@ -43,12 +43,18 @@ void dxbc_writer_add_section(struct dxbc_writer *dxbc, uint32_t tag, const void section->data.size = size; }
-int dxbc_writer_write(struct dxbc_writer *dxbc, struct vkd3d_shader_code *out) +int vkd3d_shader_serialize_dxbc(size_t section_count, const struct vkd3d_shader_dxbc_section_desc *sections, + struct vkd3d_shader_code *dxbc, char **messages) { size_t size_position, offsets_position, checksum_position, i; struct vkd3d_bytecode_buffer buffer = {0}; uint32_t checksum[4];
+ TRACE("section_count %zu, sections %p, dxbc %p, messages %p.\n", section_count, sections, dxbc, messages); + + if (messages) + *messages = NULL; + put_u32(&buffer, TAG_DXBC);
checksum_position = bytecode_get_size(&buffer); @@ -57,18 +63,18 @@ int dxbc_writer_write(struct dxbc_writer *dxbc, struct vkd3d_shader_code *out)
put_u32(&buffer, 1); /* version */ size_position = put_u32(&buffer, 0); - put_u32(&buffer, dxbc->section_count); + put_u32(&buffer, section_count);
offsets_position = bytecode_get_size(&buffer); - for (i = 0; i < dxbc->section_count; ++i) + for (i = 0; i < section_count; ++i) put_u32(&buffer, 0);
- for (i = 0; i < dxbc->section_count; ++i) + for (i = 0; i < section_count; ++i) { set_u32(&buffer, offsets_position + i * sizeof(uint32_t), bytecode_get_size(&buffer)); - put_u32(&buffer, dxbc->sections[i].tag); - put_u32(&buffer, dxbc->sections[i].data.size); - bytecode_put_bytes(&buffer, dxbc->sections[i].data.code, dxbc->sections[i].data.size); + put_u32(&buffer, sections[i].tag); + put_u32(&buffer, sections[i].data.size); + bytecode_put_bytes(&buffer, sections[i].data.code, sections[i].data.size); } set_u32(&buffer, size_position, bytecode_get_size(&buffer));
@@ -78,12 +84,17 @@ int dxbc_writer_write(struct dxbc_writer *dxbc, struct vkd3d_shader_code *out)
if (!buffer.status) { - out->code = buffer.data; - out->size = buffer.size; + dxbc->code = buffer.data; + dxbc->size = buffer.size; } return buffer.status; }
+int dxbc_writer_write(struct dxbc_writer *dxbc, struct vkd3d_shader_code *out) +{ + return vkd3d_shader_serialize_dxbc(dxbc->section_count, dxbc->sections, out, NULL); +} + struct vkd3d_shader_src_param_entry { struct list entry; diff --git a/libs/vkd3d-shader/vkd3d_shader.map b/libs/vkd3d-shader/vkd3d_shader.map index 096cb848..6afc526a 100644 --- a/libs/vkd3d-shader/vkd3d_shader.map +++ b/libs/vkd3d-shader/vkd3d_shader.map @@ -18,6 +18,7 @@ global: vkd3d_shader_parse_root_signature; vkd3d_shader_preprocess; vkd3d_shader_scan; + vkd3d_shader_serialize_dxbc; vkd3d_shader_serialize_root_signature; vkd3d_shader_set_log_callback;