From 7281f4ed39935c401c69333ca10f5ac7b7c5371e Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Thu, 12 Jun 2025 00:38:10 +0200 Subject: [PATCH] vkd3d-shader/fx: Add support for tx -> text output. Signed-off-by: Nikolay Sivov --- include/vkd3d_shader.h | 6 ++++ libs/vkd3d-shader/fx.c | 46 ++++++++++++++++++++++-- libs/vkd3d-shader/vkd3d_shader_main.c | 14 ++++++++ libs/vkd3d-shader/vkd3d_shader_private.h | 2 ++ programs/vkd3d-compiler/main.c | 5 +++ 5 files changed, 71 insertions(+), 2 deletions(-) diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 30b6a0700..b50271ce9 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -1431,6 +1431,11 @@ enum vkd3d_shader_source_type * Input is a raw FX section without container. \since 1.14 */ VKD3D_SHADER_SOURCE_FX, + /** + * A D3DX texture shader. This is the format used for the 'tx_1_0' HLSL + * target profile. \since 1.17 + */ + VKD3D_SHADER_SOURCE_TX, VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SOURCE_TYPE), }; @@ -2761,6 +2766,7 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported * - VKD3D_SHADER_SOURCE_HLSL to VKD3D_SHADER_TARGET_DXBC_TPF * - VKD3D_SHADER_SOURCE_HLSL to VKD3D_SHADER_TARGET_FX * - VKD3D_SHADER_SOURCE_FX to VKD3D_SHADER_TARGET_D3D_ASM + * - VKD3D_SHADER_SOURCE_TX to VKD3D_SHADER_TARGET_D3D_ASM * * Supported transformations can also be detected at runtime with the functions * vkd3d_shader_get_supported_source_types() and diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index 36eefc1e5..95a172fd8 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -3534,6 +3534,7 @@ int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) struct fx_parser { + enum vkd3d_shader_source_type source_type; const uint8_t *ptr, *start, *end; struct vkd3d_shader_message_context *message_context; struct vkd3d_string_buffer buffer; @@ -5012,9 +5013,14 @@ static void fx_parse_fxlvm_expression(struct fx_parser *parser, struct fxlvm_cod uint32_t ins_count; size_t i, j; - ins_count = fxlvm_read_u32(code); - parse_fx_start_indent(parser); + if (parser->source_type == VKD3D_SHADER_SOURCE_TX) + { + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "tx_1_0\n"); + } + + ins_count = fxlvm_read_u32(code); for (i = 0; i < ins_count; ++i) { @@ -5635,6 +5641,7 @@ static void fx_parser_init(struct fx_parser *parser, const struct vkd3d_shader_c struct vkd3d_shader_message_context *message_context) { memset(parser, 0, sizeof(*parser)); + parser->source_type = compile_info->source_type; parser->start = compile_info->source.code; parser->ptr = compile_info->source.code; parser->end = (uint8_t *)compile_info->source.code + compile_info->source.size; @@ -5695,3 +5702,38 @@ int fx_parse(const struct vkd3d_shader_compile_info *compile_info, return VKD3D_ERROR_INVALID_SHADER; return VKD3D_OK; } + +int tx_parse(const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) +{ + struct fx_parser parser; + uint32_t version; + + fx_parser_init(&parser, compile_info, message_context); + + if (parser.end - parser.start < sizeof(version)) + { + fx_parser_error(&parser, VKD3D_SHADER_ERROR_FX_INVALID_SIZE, + "Source size %zu is smaller than the TX header size.", compile_info->source.size); + return VKD3D_ERROR_INVALID_SHADER; + } + version = *(uint32_t *)parser.ptr; + + switch (version) + { + case 0x54580100: + fx_2_parse_fxlvm_expression(&parser, (const uint32_t *)parser.ptr, parser.end - parser.ptr); + break; + default: + fx_parser_error(&parser, VKD3D_SHADER_ERROR_FX_INVALID_VERSION, + "Invalid texture shader binary version value 0x%08x.", version); + break; + } + + vkd3d_shader_code_from_string_buffer(out, &parser.buffer); + fx_parser_cleanup(&parser); + + if (parser.failed) + return VKD3D_ERROR_INVALID_SHADER; + return VKD3D_OK; +} diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 2b86f6262..bff9ebbc2 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -1829,6 +1829,10 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, { ret = fx_parse(compile_info, out, &message_context); } + else if (compile_info->source_type == VKD3D_SHADER_SOURCE_TX) + { + ret = tx_parse(compile_info, out, &message_context); + } else { uint64_t config_flags = vkd3d_shader_init_config_flags(); @@ -2037,6 +2041,7 @@ const enum vkd3d_shader_source_type *vkd3d_shader_get_supported_source_types(uns VKD3D_SHADER_SOURCE_D3D_BYTECODE, VKD3D_SHADER_SOURCE_DXBC_DXIL, VKD3D_SHADER_SOURCE_FX, + VKD3D_SHADER_SOURCE_TX, }; TRACE("count %p.\n", count); @@ -2101,6 +2106,11 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( VKD3D_SHADER_TARGET_D3D_ASM, }; + static const enum vkd3d_shader_target_type tx_types[] = + { + VKD3D_SHADER_TARGET_D3D_ASM, + }; + TRACE("source_type %#x, count %p.\n", source_type, count); switch (source_type) @@ -2125,6 +2135,10 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( *count = ARRAY_SIZE(fx_types); return fx_types; + case VKD3D_SHADER_SOURCE_TX: + *count = ARRAY_SIZE(tx_types); + return tx_types; + default: *count = 0; return NULL; diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 59e07b6e6..f806a191e 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1683,6 +1683,8 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con struct vkd3d_shader_message_context *message_context, struct vsir_program *program); int fx_parse(const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); +int tx_parse(const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); void free_dxbc_shader_desc(struct dxbc_shader_desc *desc); diff --git a/programs/vkd3d-compiler/main.c b/programs/vkd3d-compiler/main.c index 5bf243f92..e1fd6a7ce 100644 --- a/programs/vkd3d-compiler/main.c +++ b/programs/vkd3d-compiler/main.c @@ -113,6 +113,9 @@ source_type_info[] = {VKD3D_SHADER_SOURCE_FX, "fx", "Raw effect binary section. This type includes fx_2_0 and fx_4+ formats.\n", true, VKD3D_SHADER_TARGET_D3D_ASM}, + {VKD3D_SHADER_SOURCE_TX, + "tx", "A D3DX texture shader. This is the format used for the 'tx_1_0' HLSL target profile.\n", + true, VKD3D_SHADER_TARGET_D3D_ASM}, {VKD3D_SHADER_SOURCE_FX, "dxbc-fx", "An effect binary embedded in a DXBC container.\n", true, VKD3D_SHADER_TARGET_D3D_ASM, TAG_FX10}, @@ -868,6 +871,8 @@ int main(int argc, char **argv) options.source_type = get_source_type_info(VKD3D_SHADER_SOURCE_D3D_BYTECODE); else if ((token & 0xffff0000) == 0xfeff0000) options.source_type = get_source_type_info(VKD3D_SHADER_SOURCE_FX); + else if ((token & 0xffff0000) == 0x54580000) + options.source_type = get_source_type_info(VKD3D_SHADER_SOURCE_TX); else options.source_type = get_source_type_info(VKD3D_SHADER_SOURCE_HLSL); }