vkd3d-shader/fx: Add support for tx -> text output.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
This commit is contained in:
Nikolay Sivov
2025-06-12 00:38:10 +02:00
committed by Henri Verbeet
parent 586b2b5a79
commit 7281f4ed39
Notes: Henri Verbeet 2025-06-16 17:49:09 +02:00
Approved-by: Henri Verbeet (@hverbeet)
Merge-Request: https://gitlab.winehq.org/wine/vkd3d/-/merge_requests/1570
5 changed files with 71 additions and 2 deletions

View File

@@ -1431,6 +1431,11 @@ enum vkd3d_shader_source_type
* Input is a raw FX section without container. \since 1.14 * Input is a raw FX section without container. \since 1.14
*/ */
VKD3D_SHADER_SOURCE_FX, 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), 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_DXBC_TPF
* - VKD3D_SHADER_SOURCE_HLSL to VKD3D_SHADER_TARGET_FX * - VKD3D_SHADER_SOURCE_HLSL to VKD3D_SHADER_TARGET_FX
* - VKD3D_SHADER_SOURCE_FX to VKD3D_SHADER_TARGET_D3D_ASM * - 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 * Supported transformations can also be detected at runtime with the functions
* vkd3d_shader_get_supported_source_types() and * vkd3d_shader_get_supported_source_types() and

View File

@@ -3534,6 +3534,7 @@ int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
struct fx_parser struct fx_parser
{ {
enum vkd3d_shader_source_type source_type;
const uint8_t *ptr, *start, *end; const uint8_t *ptr, *start, *end;
struct vkd3d_shader_message_context *message_context; struct vkd3d_shader_message_context *message_context;
struct vkd3d_string_buffer buffer; 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; uint32_t ins_count;
size_t i, j; size_t i, j;
ins_count = fxlvm_read_u32(code);
parse_fx_start_indent(parser); 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) 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) struct vkd3d_shader_message_context *message_context)
{ {
memset(parser, 0, sizeof(*parser)); memset(parser, 0, sizeof(*parser));
parser->source_type = compile_info->source_type;
parser->start = compile_info->source.code; parser->start = compile_info->source.code;
parser->ptr = compile_info->source.code; parser->ptr = compile_info->source.code;
parser->end = (uint8_t *)compile_info->source.code + compile_info->source.size; 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_ERROR_INVALID_SHADER;
return VKD3D_OK; 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;
}

View File

@@ -1829,6 +1829,10 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
{ {
ret = fx_parse(compile_info, out, &message_context); 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 else
{ {
uint64_t config_flags = vkd3d_shader_init_config_flags(); 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_D3D_BYTECODE,
VKD3D_SHADER_SOURCE_DXBC_DXIL, VKD3D_SHADER_SOURCE_DXBC_DXIL,
VKD3D_SHADER_SOURCE_FX, VKD3D_SHADER_SOURCE_FX,
VKD3D_SHADER_SOURCE_TX,
}; };
TRACE("count %p.\n", count); 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, 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); TRACE("source_type %#x, count %p.\n", source_type, count);
switch (source_type) switch (source_type)
@@ -2125,6 +2135,10 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types(
*count = ARRAY_SIZE(fx_types); *count = ARRAY_SIZE(fx_types);
return fx_types; return fx_types;
case VKD3D_SHADER_SOURCE_TX:
*count = ARRAY_SIZE(tx_types);
return tx_types;
default: default:
*count = 0; *count = 0;
return NULL; return NULL;

View File

@@ -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); struct vkd3d_shader_message_context *message_context, struct vsir_program *program);
int fx_parse(const struct vkd3d_shader_compile_info *compile_info, int fx_parse(const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); 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); void free_dxbc_shader_desc(struct dxbc_shader_desc *desc);

View File

@@ -113,6 +113,9 @@ source_type_info[] =
{VKD3D_SHADER_SOURCE_FX, {VKD3D_SHADER_SOURCE_FX,
"fx", "Raw effect binary section. This type includes fx_2_0 and fx_4+ formats.\n", "fx", "Raw effect binary section. This type includes fx_2_0 and fx_4+ formats.\n",
true, VKD3D_SHADER_TARGET_D3D_ASM}, 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, {VKD3D_SHADER_SOURCE_FX,
"dxbc-fx", "An effect binary embedded in a DXBC container.\n", "dxbc-fx", "An effect binary embedded in a DXBC container.\n",
true, VKD3D_SHADER_TARGET_D3D_ASM, TAG_FX10}, 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); options.source_type = get_source_type_info(VKD3D_SHADER_SOURCE_D3D_BYTECODE);
else if ((token & 0xffff0000) == 0xfeff0000) else if ((token & 0xffff0000) == 0xfeff0000)
options.source_type = get_source_type_info(VKD3D_SHADER_SOURCE_FX); 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 else
options.source_type = get_source_type_info(VKD3D_SHADER_SOURCE_HLSL); options.source_type = get_source_type_info(VKD3D_SHADER_SOURCE_HLSL);
} }