From b751f52ca93f8fd64aff26d17227e6fcbe4b3d40 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 15 Apr 2025 08:45:19 +1000 Subject: [PATCH] Updated vkd3d to f02ea94c428f6b2f662f78fc78eae7f33428e9de. --- libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 205 ++++++-- libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 70 +-- libs/vkd3d/libs/vkd3d-shader/dxil.c | 4 +- libs/vkd3d/libs/vkd3d-shader/glsl.c | 68 ++- libs/vkd3d/libs/vkd3d-shader/hlsl.y | 63 +++ libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 23 +- libs/vkd3d/libs/vkd3d-shader/ir.c | 21 +- libs/vkd3d/libs/vkd3d-shader/msl.c | 463 ++++++++++++------ libs/vkd3d/libs/vkd3d-shader/spirv.c | 2 +- .../libs/vkd3d-shader/vkd3d_shader_main.c | 121 +++-- .../libs/vkd3d-shader/vkd3d_shader_private.h | 33 +- 11 files changed, 714 insertions(+), 359 deletions(-) diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c index 764f0888490..4521bfabd8e 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c @@ -687,7 +687,7 @@ static void shader_print_input_sysval_semantic(struct vkd3d_d3d_asm_compiler *co prefix, compiler->colours.error, semantic, compiler->colours.reset, suffix); } -static void shader_dump_resource_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_shader_resource_type type) +static void shader_print_resource_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_shader_resource_type type) { static const char *const resource_type_names[] = { @@ -707,10 +707,11 @@ static void shader_dump_resource_type(struct vkd3d_d3d_asm_compiler *compiler, e if (type < ARRAY_SIZE(resource_type_names)) vkd3d_string_buffer_printf(&compiler->buffer, "%s", resource_type_names[type]); else - vkd3d_string_buffer_printf(&compiler->buffer, "unknown"); + vkd3d_string_buffer_printf(&compiler->buffer, "%s%s", + compiler->colours.error, type, compiler->colours.reset); } -static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_data_type type) +static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_data_type type) { static const char *const data_type_names[] = { @@ -731,14 +732,11 @@ static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum [VKD3D_DATA_HALF ] = "half", }; - const char *name; - if (type < ARRAY_SIZE(data_type_names)) - name = data_type_names[type]; + vkd3d_string_buffer_printf(&compiler->buffer, "%s", data_type_names[type]); else - name = ""; - - vkd3d_string_buffer_printf(&compiler->buffer, "%s", name); + vkd3d_string_buffer_printf(&compiler->buffer, "%s%s", + compiler->colours.error, type, compiler->colours.reset); } static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vkd3d_data_type *type) @@ -750,7 +748,7 @@ static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compil for (i = 0; i < 4; i++) { vkd3d_string_buffer_printf(&compiler->buffer, "%s", i == 0 ? "" : ","); - shader_dump_data_type(compiler, type[i]); + shader_print_data_type(compiler, type[i]); } vkd3d_string_buffer_printf(&compiler->buffer, ")"); @@ -793,7 +791,7 @@ static void shader_print_dcl_usage(struct vkd3d_d3d_asm_compiler *compiler, if (semantic->resource.reg.reg.type == VKD3DSPR_RESOURCE) vkd3d_string_buffer_printf(buffer, "resource_"); - shader_dump_resource_type(compiler, semantic->resource_type); + shader_print_resource_type(compiler, semantic->resource_type); if (semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS || semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) { @@ -1294,7 +1292,7 @@ static void shader_print_reg_type(struct vkd3d_d3d_asm_compiler *compiler, dimension = "??"; vkd3d_string_buffer_printf(buffer, "%s <%s", prefix, dimension); - shader_dump_data_type(compiler, reg->data_type); + shader_print_data_type(compiler, reg->data_type); vkd3d_string_buffer_printf(buffer, ">%s", suffix); } @@ -1998,7 +1996,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, vkd3d_string_buffer_printf(buffer, "raw_"); if (ins->structured) vkd3d_string_buffer_printf(buffer, "structured_"); - shader_dump_resource_type(compiler, ins->resource_type); + shader_print_resource_type(compiler, ins->resource_type); if (ins->resource_stride) shader_print_uint_literal(compiler, ", stride=", ins->resource_stride, ""); vkd3d_string_buffer_printf(buffer, ")"); @@ -2202,10 +2200,80 @@ static enum vkd3d_result dump_dxbc_signatures(struct vkd3d_d3d_asm_compiler *com &program->patch_constant_signature)) < 0) return ret; - vkd3d_string_buffer_printf(&compiler->buffer, "%s.text%s\n", + return VKD3D_OK; +} + +static void shader_print_descriptor_name(struct vkd3d_d3d_asm_compiler *compiler, + enum vkd3d_shader_descriptor_type t, unsigned int id) +{ + const char *type = NULL; + + switch (t) + { + case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV: + type = shader_register_names[VKD3DSPR_RESOURCE]; + break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV: + type = shader_register_names[VKD3DSPR_UAV]; + break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: + type = shader_register_names[VKD3DSPR_CONSTBUFFER]; + break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER: + type = shader_register_names[VKD3DSPR_SAMPLER]; + break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_FORCE_32BIT: + break; + } + + if (type) + vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%u%s", + compiler->colours.reg, type, id, compiler->colours.reset); + else + vkd3d_string_buffer_printf(&compiler->buffer, "%s%u%s", + compiler->colours.error, t, id, compiler->colours.reset); +} + +static void shader_print_descriptors(struct vkd3d_d3d_asm_compiler *compiler, + const struct vkd3d_shader_scan_descriptor_info1 *descriptors) +{ + struct vkd3d_string_buffer *buffer = &compiler->buffer; + unsigned int i; + + vkd3d_string_buffer_printf(buffer, "%s.descriptors%s\n", compiler->colours.opcode, compiler->colours.reset); + for (i = 0; i < descriptors->descriptor_count; ++i) + { + const struct vkd3d_shader_descriptor_info1 *d = &descriptors->descriptors[i]; - return VKD3D_OK; + vkd3d_string_buffer_printf(buffer, "%s.descriptor%s ", compiler->colours.opcode, compiler->colours.reset); + shader_print_descriptor_name(compiler, d->type, d->register_id); + shader_print_subscript_range(compiler, d->register_index, + d->count == ~0u ? ~0u : d->register_index + d->count - 1); + shader_dump_register_space(compiler, d->register_space); + + if (d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SRV || d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) + { + vkd3d_string_buffer_printf(buffer, ", "); + shader_print_resource_type(compiler, d->resource_type); + vkd3d_string_buffer_printf(buffer, " resource_data_type); + if (d->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS + || d->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) + shader_print_uint_literal(compiler, ", ", d->sample_count, ""); + vkd3d_string_buffer_printf(buffer, ">"); + } + + if (d->buffer_size) + shader_print_hex_literal(compiler, ", size=", d->buffer_size, ""); + if (d->structure_stride) + shader_print_hex_literal(compiler, ", stride=", d->structure_stride, ""); + if (d->flags) + shader_print_hex_literal(compiler, ", flags=", d->flags, ""); + if (d->uav_flags) + shader_print_hex_literal(compiler, ", uav_flags=", d->uav_flags, ""); + vkd3d_string_buffer_printf(buffer, "\n"); + } } enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, @@ -2271,6 +2339,10 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, indent_str = " "; else indent_str = ""; + /* The signatures we emit only make sense for DXBC shaders. d3dbc doesn't + * even have an explicit concept of signature. */ + if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_IO_SIGNATURES && shader_version->major >= 4) + compiler.flags |= VSIR_ASM_FLAG_DUMP_SIGNATURES; buffer = &compiler.buffer; vkd3d_string_buffer_init(buffer); @@ -2281,17 +2353,19 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, shader_get_type_prefix(shader_version->type), shader_version->major, shader_version->minor, compiler.colours.reset); - /* The signatures we emit only make sense for DXBC shaders. D3DBC - * doesn't even have an explicit concept of signature. */ - if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_IO_SIGNATURES && shader_version->major >= 4) + if (compiler.flags & VSIR_ASM_FLAG_DUMP_SIGNATURES + && (result = dump_dxbc_signatures(&compiler, program)) < 0) { - if ((result = dump_dxbc_signatures(&compiler, program)) < 0) - { - vkd3d_string_buffer_cleanup(buffer); - return result; - } + vkd3d_string_buffer_cleanup(buffer); + return result; } + if (compiler.flags & VSIR_ASM_FLAG_DUMP_DESCRIPTORS) + shader_print_descriptors(&compiler, &program->descriptors); + + if (compiler.flags & (VSIR_ASM_FLAG_DUMP_SIGNATURES | VSIR_ASM_FLAG_DUMP_DESCRIPTORS)) + vkd3d_string_buffer_printf(buffer, "%s.text%s\n", compiler.colours.opcode, compiler.colours.reset); + indent = 0; for (i = 0; i < program->instructions.count; ++i) { @@ -2388,6 +2462,77 @@ static void trace_signature(const struct shader_signature *signature, const char vkd3d_string_buffer_cleanup(&buffer); } +static void shader_print_io_declaration(struct vkd3d_string_buffer *buffer, enum vkd3d_shader_register_type type) +{ + switch (type) + { +#define X(x) case VKD3DSPR_ ## x: vkd3d_string_buffer_printf(buffer, #x); return; + X(TEMP) + X(INPUT) + X(CONST) + X(ADDR) + X(TEXTURE) + X(RASTOUT) + X(ATTROUT) + X(TEXCRDOUT) + X(OUTPUT) + X(CONSTINT) + X(COLOROUT) + X(DEPTHOUT) + X(COMBINED_SAMPLER) + X(CONSTBOOL) + X(LOOP) + X(TEMPFLOAT16) + X(MISCTYPE) + X(LABEL) + X(PREDICATE) + X(IMMCONST) + X(IMMCONST64) + X(CONSTBUFFER) + X(IMMCONSTBUFFER) + X(PRIMID) + X(NULL) + X(SAMPLER) + X(RESOURCE) + X(UAV) + X(OUTPOINTID) + X(FORKINSTID) + X(JOININSTID) + X(INCONTROLPOINT) + X(OUTCONTROLPOINT) + X(PATCHCONST) + X(TESSCOORD) + X(GROUPSHAREDMEM) + X(THREADID) + X(THREADGROUPID) + X(LOCALTHREADID) + X(LOCALTHREADINDEX) + X(IDXTEMP) + X(STREAM) + X(FUNCTIONBODY) + X(FUNCTIONPOINTER) + X(COVERAGE) + X(SAMPLEMASK) + X(GSINSTID) + X(DEPTHOUTGE) + X(DEPTHOUTLE) + X(RASTERIZER) + X(OUTSTENCILREF) + X(UNDEF) + X(SSA) + X(WAVELANECOUNT) + X(WAVELANEINDEX) + X(PARAMETER) + X(POINT_COORD) +#undef X + case VKD3DSPR_INVALID: + case VKD3DSPR_COUNT: + break; + } + + vkd3d_string_buffer_printf(buffer, "", type); +} + static void trace_io_declarations(const struct vsir_program *program) { struct vkd3d_string_buffer buffer; @@ -2400,11 +2545,12 @@ static void trace_io_declarations(const struct vsir_program *program) for (i = 0; i < sizeof(program->io_dcls) * CHAR_BIT; ++i) { - if (bitmap_is_set(program->io_dcls, i)) - { - empty = false; - vkd3d_string_buffer_printf(&buffer, " %u", i); - } + if (!bitmap_is_set(program->io_dcls, i)) + continue; + + vkd3d_string_buffer_printf(&buffer, empty ? " " : " | "); + shader_print_io_declaration(&buffer, i); + empty = false; } if (empty) @@ -2417,7 +2563,8 @@ static void trace_io_declarations(const struct vsir_program *program) void vsir_program_trace(const struct vsir_program *program) { - const unsigned int flags = VSIR_ASM_FLAG_DUMP_TYPES | VSIR_ASM_FLAG_DUMP_ALL_INDICES; + const unsigned int flags = VSIR_ASM_FLAG_DUMP_TYPES | VSIR_ASM_FLAG_DUMP_ALL_INDICES + | VSIR_ASM_FLAG_DUMP_SIGNATURES | VSIR_ASM_FLAG_DUMP_DESCRIPTORS; struct vkd3d_shader_code code; const char *p, *q, *end; diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c index b49ef9865db..77498f26c7f 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -1491,7 +1491,8 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c } bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, const char *semantic_name, - unsigned int semantic_index, bool output, enum vkd3d_shader_register_type *type, unsigned int *reg) + unsigned int semantic_index, bool output, enum vkd3d_shader_sysval_semantic *sysval, + enum vkd3d_shader_register_type *type, unsigned int *reg) { unsigned int i; @@ -1501,42 +1502,43 @@ bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, bool output; enum vkd3d_shader_type shader_type; unsigned int major_version; + enum vkd3d_shader_sysval_semantic sysval; enum vkd3d_shader_register_type type; unsigned int offset; } register_table[] = { - {"color", false, VKD3D_SHADER_TYPE_PIXEL, 1, VKD3DSPR_INPUT}, - {"texcoord", false, VKD3D_SHADER_TYPE_PIXEL, 1, VKD3DSPR_TEXTURE}, - - {"color", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_COLOROUT}, - {"depth", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_DEPTHOUT}, - {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_DEPTHOUT}, - {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_COLOROUT}, - {"color", false, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_INPUT}, - {"texcoord", false, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_TEXTURE}, - - {"color", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_COLOROUT}, - {"depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_DEPTHOUT}, - {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_DEPTHOUT}, - {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_COLOROUT}, - {"sv_position", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_POSITION}, - {"vface", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_FACE}, - {"vpos", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_POSITION}, - - {"color", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_ATTROUT}, - {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_FOG}, - {"position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, - {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POINT_SIZE}, - {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, - {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_TEXCRDOUT}, - - {"color", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_ATTROUT}, - {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_FOG}, - {"position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, - {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POINT_SIZE}, - {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, - {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_TEXCRDOUT}, + {"color", false, VKD3D_SHADER_TYPE_PIXEL, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_INPUT}, + {"texcoord", false, VKD3D_SHADER_TYPE_PIXEL, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_TEXTURE}, + + {"color", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_TARGET, VKD3DSPR_COLOROUT}, + {"depth", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_DEPTH, VKD3DSPR_DEPTHOUT}, + {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_DEPTH, VKD3DSPR_DEPTHOUT}, + {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_TARGET, VKD3DSPR_COLOROUT}, + {"color", false, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_INPUT}, + {"texcoord", false, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_TEXTURE}, + + {"color", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_TARGET, VKD3DSPR_COLOROUT}, + {"depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_DEPTH, VKD3DSPR_DEPTHOUT}, + {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_DEPTH, VKD3DSPR_DEPTHOUT}, + {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_TARGET, VKD3DSPR_COLOROUT}, + {"sv_position", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_POSITION, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_POSITION}, + {"vface", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_IS_FRONT_FACE, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_FACE}, + {"vpos", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_POSITION, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_POSITION}, + + {"color", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_ATTROUT}, + {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_RASTOUT, VSIR_RASTOUT_FOG}, + {"position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_POSITION, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, + {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POINT_SIZE}, + {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_POSITION, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, + {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_TEXCRDOUT}, + + {"color", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_ATTROUT}, + {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_RASTOUT, VSIR_RASTOUT_FOG}, + {"position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_POSITION, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, + {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POINT_SIZE}, + {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_POSITION, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, + {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_TEXCRDOUT}, }; for (i = 0; i < ARRAY_SIZE(register_table); ++i) @@ -1546,6 +1548,8 @@ bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, && version->type == register_table[i].shader_type && version->major == register_table[i].major_version) { + if (sysval) + *sysval = register_table[i].sysval; *type = register_table[i].type; if (register_table[i].type == VKD3DSPR_MISCTYPE || register_table[i].type == VKD3DSPR_RASTOUT) *reg = register_table[i].offset; @@ -1997,7 +2001,7 @@ static void d3dbc_write_semantic_dcl(struct d3dbc_compiler *d3dbc, reg.reg.idx_count = 1; if (sm1_register_from_semantic_name(version, element->semantic_name, - element->semantic_index, output, ®.reg.type, ®.reg.idx[0].offset)) + element->semantic_index, output, NULL, ®.reg.type, ®.reg.idx[0].offset)) { usage = 0; usage_idx = 0; diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c index ac4828d6f59..a3813c39bf0 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c @@ -4382,7 +4382,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco dst_param_init(&dst_params[0]); dst_param_init(&dst_params[1]); register_init_ssa_scalar(&dst_params[index].reg, a->type, dst, sm6); - vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); + vsir_dst_param_init_null(&dst_params[index ^ 1]); dst->u.reg = dst_params[index].reg; } else @@ -5942,7 +5942,7 @@ static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_ dst_param_init(&dst_params[0]); dst_param_init(&dst_params[1]); register_init_ssa_scalar(&dst_params[index].reg, dst->type, dst, sm6); - vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); + vsir_dst_param_init_null(&dst_params[index ^ 1]); dst->u.reg = dst_params[index].reg; } diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c index a87ade5e467..e4497b9ac5b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c @@ -787,7 +787,6 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ unsigned int resource_id, resource_idx, resource_space, sample_count; const struct glsl_resource_type_info *resource_type_info; const struct vkd3d_shader_descriptor_info1 *d; - enum vkd3d_shader_component_type sampled_type; enum vkd3d_shader_resource_type resource_type; struct vkd3d_string_buffer *fetch; enum vkd3d_data_type data_type; @@ -810,8 +809,7 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ resource_type = d->resource_type; resource_space = d->register_space; sample_count = d->sample_count; - sampled_type = vkd3d_component_type_from_resource_data_type(d->resource_data_type); - data_type = vkd3d_data_type_from_component_type(sampled_type); + data_type = d->resource_data_type; } else { @@ -903,7 +901,6 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk unsigned int resource_id, resource_idx, resource_space; unsigned int sampler_id, sampler_idx, sampler_space; const struct vkd3d_shader_descriptor_info1 *d; - enum vkd3d_shader_component_type sampled_type; enum vkd3d_shader_resource_type resource_type; unsigned int component_idx, coord_size; struct vkd3d_string_buffer *sample; @@ -933,8 +930,7 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk { resource_type = d->resource_type; resource_space = d->register_space; - sampled_type = vkd3d_component_type_from_resource_data_type(d->resource_data_type); - data_type = vkd3d_data_type_from_component_type(sampled_type); + data_type = d->resource_data_type; } else { @@ -1053,11 +1049,11 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) { const struct glsl_resource_type_info *resource_type_info; - enum vkd3d_shader_component_type component_type; const struct vkd3d_shader_descriptor_info1 *d; enum vkd3d_shader_resource_type resource_type; unsigned int uav_id, uav_idx, uav_space; struct vkd3d_string_buffer *load; + enum vkd3d_data_type data_type; struct glsl_src coord; struct glsl_dst dst; uint32_t coord_mask; @@ -1072,7 +1068,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s { resource_type = d->resource_type; uav_space = d->register_space; - component_type = vkd3d_component_type_from_resource_data_type(d->resource_data_type); + data_type = d->resource_data_type; } else { @@ -1080,7 +1076,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); uav_space = 0; resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; - component_type = VKD3D_SHADER_COMPONENT_FLOAT; + data_type = VKD3D_DATA_FLOAT; } if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) @@ -1103,8 +1099,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s vkd3d_string_buffer_printf(load, ", %s)", coord.str->buffer); shader_glsl_print_swizzle(load, ins->src[1].swizzle, ins->dst[0].write_mask); - shader_glsl_print_assignment_ext(gen, &dst, - vkd3d_data_type_from_component_type(component_type), "%s", load->buffer); + shader_glsl_print_assignment_ext(gen, &dst, data_type, "%s", load->buffer); vkd3d_string_buffer_release(&gen->string_buffers, load); glsl_src_cleanup(&coord, &gen->string_buffers); @@ -1114,11 +1109,11 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) { const struct glsl_resource_type_info *resource_type_info; - enum vkd3d_shader_component_type component_type; const struct vkd3d_shader_descriptor_info1 *d; enum vkd3d_shader_resource_type resource_type; unsigned int uav_id, uav_idx, uav_space; struct vkd3d_string_buffer *image_data; + enum vkd3d_data_type data_type; struct glsl_src image_coord; uint32_t coord_mask; @@ -1132,7 +1127,7 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const { resource_type = d->resource_type; uav_space = d->register_space; - component_type = vkd3d_component_type_from_resource_data_type(d->resource_data_type); + data_type = d->resource_data_type; } else { @@ -1140,7 +1135,7 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); uav_space = 0; resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; - component_type = VKD3D_SHADER_COMPONENT_FLOAT; + data_type = VKD3D_DATA_FLOAT; } if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) @@ -1159,25 +1154,26 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const if (ins->src[1].reg.dimension == VSIR_DIMENSION_SCALAR) { - switch (component_type) + switch (data_type) { - case VKD3D_SHADER_COMPONENT_UINT: + case VKD3D_DATA_UINT: vkd3d_string_buffer_printf(image_data, "uvec4("); break; - case VKD3D_SHADER_COMPONENT_INT: + case VKD3D_DATA_INT: vkd3d_string_buffer_printf(image_data, "ivec4("); break; default: vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled component type %#x.", component_type); + "Internal compiler error: Unhandled data type %#x.", data_type); /* fall through */ - case VKD3D_SHADER_COMPONENT_FLOAT: + case VKD3D_DATA_FLOAT: + case VKD3D_DATA_UNORM: + case VKD3D_DATA_SNORM: vkd3d_string_buffer_printf(image_data, "vec4("); break; } } - shader_glsl_print_src(image_data, gen, &ins->src[1], VKD3DSP_WRITEMASK_ALL, - vkd3d_data_type_from_component_type(component_type)); + shader_glsl_print_src(image_data, gen, &ins->src[1], VKD3DSP_WRITEMASK_ALL, data_type); if (ins->src[1].reg.dimension == VSIR_DIMENSION_SCALAR) vkd3d_string_buffer_printf(image_data, ", 0, 0, 0)"); @@ -1735,7 +1731,6 @@ static void shader_glsl_generate_uav_declaration(struct vkd3d_glsl_generator *ge const struct vkd3d_shader_descriptor_binding *binding; const struct vkd3d_shader_descriptor_offset *offset; struct vkd3d_string_buffer *buffer = gen->buffer; - enum vkd3d_shader_component_type component_type; unsigned int binding_idx; if (uav->count != 1) @@ -1792,22 +1787,24 @@ static void shader_glsl_generate_uav_declaration(struct vkd3d_glsl_generator *ge image_type = ""; } - switch ((component_type = vkd3d_component_type_from_resource_data_type(uav->resource_data_type))) + switch (uav->resource_data_type) { - case VKD3D_SHADER_COMPONENT_UINT: + case VKD3D_DATA_UINT: image_type_prefix = "u"; read_format = "r32ui"; break; - case VKD3D_SHADER_COMPONENT_INT: + case VKD3D_DATA_INT: image_type_prefix = "i"; read_format = "r32i"; break; default: vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled component type %#x for UAV %u.", - component_type, uav->register_id); + "Internal compiler error: Unhandled data type %#x for UAV %u.", + uav->resource_data_type, uav->register_id); /* fall through */ - case VKD3D_SHADER_COMPONENT_FLOAT: + case VKD3D_DATA_FLOAT: + case VKD3D_DATA_UNORM: + case VKD3D_DATA_SNORM: image_type_prefix = ""; read_format = "r32f"; break; @@ -1962,7 +1959,6 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator const struct glsl_resource_type_info *resource_type_info; const struct vkd3d_shader_descriptor_binding *binding; struct vkd3d_string_buffer *buffer = gen->buffer; - enum vkd3d_shader_component_type component_type; const char *sampler_type, *sampler_type_prefix; enum vkd3d_shader_resource_type resource_type; unsigned int binding_idx; @@ -2020,21 +2016,23 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator sampler_type = ""; } - switch ((component_type = vkd3d_component_type_from_resource_data_type(srv->resource_data_type))) + switch (srv->resource_data_type) { - case VKD3D_SHADER_COMPONENT_UINT: + case VKD3D_DATA_UINT: sampler_type_prefix = "u"; break; - case VKD3D_SHADER_COMPONENT_INT: + case VKD3D_DATA_INT: sampler_type_prefix = "i"; break; - case VKD3D_SHADER_COMPONENT_FLOAT: + case VKD3D_DATA_FLOAT: + case VKD3D_DATA_UNORM: + case VKD3D_DATA_SNORM: sampler_type_prefix = ""; break; default: vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled component type %#x for combined resource/sampler " - "for resource %u, space %u and sampler %u, space %u.", component_type, + "Internal compiler error: Unhandled data type %#x for combined resource/sampler " + "for resource %u, space %u and sampler %u, space %u.", srv->resource_data_type, crs->resource_index, crs->resource_space, crs->sampler_index, crs->sampler_space); sampler_type_prefix = ""; break; diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y index ff3d58da8f4..6086d018fdc 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -6322,6 +6322,66 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru } } +static bool add_object_property_access(struct hlsl_ctx *ctx, + struct hlsl_block *block, struct hlsl_ir_node *object, const char *name, + const struct vkd3d_shader_location *loc) +{ + const struct hlsl_type *object_type = object->data_type; + struct hlsl_resource_load_params load_params; + struct hlsl_ir_node *zero; + unsigned int sampler_dim; + + if (!strcmp(name, "Length")) + { + if (object_type->class != HLSL_CLASS_TEXTURE && object_type->class != HLSL_CLASS_UAV) + return false; + + sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); + + switch (object_type->sampler_dim) + { + case HLSL_SAMPLER_DIM_1D: + case HLSL_SAMPLER_DIM_2D: + case HLSL_SAMPLER_DIM_3D: + case HLSL_SAMPLER_DIM_1DARRAY: + case HLSL_SAMPLER_DIM_2DARRAY: + case HLSL_SAMPLER_DIM_2DMS: + case HLSL_SAMPLER_DIM_2DMSARRAY: + break; + + case HLSL_SAMPLER_DIM_BUFFER: + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: + hlsl_fixme(ctx, loc, "'Length' property for buffers."); + block->value = ctx->error_instr; + return true; + + default: + return false; + } + + if (hlsl_version_lt(ctx, 4, 0)) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, + "'Length' property can only be used on profiles 4.0 or higher."); + block->value = ctx->error_instr; + return true; + } + + zero = hlsl_block_add_uint_constant(ctx, block, 0, loc); + + memset(&load_params, 0, sizeof(load_params)); + load_params.type = HLSL_RESOURCE_RESINFO; + load_params.resource = object; + load_params.lod = zero; + load_params.format = hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, sampler_dim); + hlsl_block_add_resource_load(ctx, block, &load_params, loc); + + return true; + } + + return false; +} + static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type *format, const struct vkd3d_shader_location *loc) { @@ -9122,6 +9182,9 @@ postfix_expr: $1->value = ctx->error_instr; } } + else if (add_object_property_access(ctx, $1, node, $3, &@2)) + { + } else if (node->data_type->class != HLSL_CLASS_ERROR) { hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid subscript \"%s\".", $3); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c index dc7607a1393..1c684e7b9c1 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -6368,7 +6368,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var return; builtin = sm1_register_from_semantic_name(&version, - var->semantic.name, var->semantic.index, output, &type, ®); + var->semantic.name, var->semantic.index, output, NULL, &type, ®); if (!builtin && !sm1_usage_from_semantic_name(var->semantic.name, var->semantic.index, &usage, &usage_idx)) { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, @@ -7763,7 +7763,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog return; if (!sm1_register_from_semantic_name(&program->shader_version, - var->semantic.name, var->semantic.index, output, &type, ®ister_index)) + var->semantic.name, var->semantic.index, output, &sysval, &type, ®ister_index)) { enum vkd3d_decl_usage usage; unsigned int usage_idx; @@ -7780,6 +7780,8 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog if (program->shader_version.type == VKD3D_SHADER_TYPE_VERTEX && output && usage == VKD3D_DECL_USAGE_POSITION) sysval = VKD3D_SHADER_SV_POSITION; + else + sysval = VKD3D_SHADER_SV_NONE; } mask = (1 << var->data_type->e.numeric.dimx) - 1; @@ -7826,7 +7828,12 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog element->mask = mask; element->used_mask = use_mask; if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output) - element->interpolation_mode = VKD3DSIM_LINEAR; + { + if (program->shader_version.major >= 4) + element->interpolation_mode = sm4_get_interpolation_mode(var->data_type, var->storage_modifiers); + else + element->interpolation_mode = VKD3DSIM_LINEAR; + } switch (var->data_type->e.numeric.type) { @@ -8880,7 +8887,7 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, register_index = 0; } else if (!sm1_register_from_semantic_name(&version, semantic_name, - deref->var->semantic.index, true, &type, ®ister_index)) + deref->var->semantic.index, true, NULL, &type, ®ister_index)) { VKD3D_ASSERT(reg.allocated); type = VKD3DSPR_OUTPUT; @@ -9006,7 +9013,7 @@ static void sm1_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx, version.minor = ctx->profile->minor_version; version.type = ctx->profile->type; if (sm1_register_from_semantic_name(&version, deref->var->semantic.name, - deref->var->semantic.index, false, &type, ®ister_index)) + deref->var->semantic.index, false, NULL, &type, ®ister_index)) { writemask = (1 << deref->var->data_type->e.numeric.dimx) - 1; } @@ -10012,8 +10019,8 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, static void sm4_generate_vsir_expr_with_two_destinations(struct hlsl_ctx *ctx, struct vsir_program *program, enum vkd3d_shader_opcode opcode, const struct hlsl_ir_expr *expr, unsigned int dst_idx) { - struct vkd3d_shader_dst_param *dst_param, *null_param; const struct hlsl_ir_node *instr = &expr->node; + struct vkd3d_shader_dst_param *dst_param; struct vkd3d_shader_instruction *ins; unsigned int i, src_count; @@ -10031,9 +10038,7 @@ static void sm4_generate_vsir_expr_with_two_destinations(struct hlsl_ctx *ctx, s dst_param = &ins->dst[dst_idx]; vsir_dst_from_hlsl_node(dst_param, ctx, instr); - null_param = &ins->dst[1 - dst_idx]; - vsir_dst_param_init(null_param, VKD3DSPR_NULL, VKD3D_DATA_FLOAT, 0); - null_param->reg.dimension = VSIR_DIMENSION_NONE; + vsir_dst_param_init_null(&ins->dst[1 - dst_idx]); for (i = 0; i < src_count; ++i) vsir_src_from_hlsl_node(&ins->src[i], ctx, expr->operands[i].node, dst_param->write_mask); diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c index 72cf53761e4..d25485ab004 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -312,6 +312,13 @@ static void vsir_dst_param_init_io(struct vkd3d_shader_dst_param *dst, enum vkd3 dst->write_mask = e->mask; } +void vsir_dst_param_init_null(struct vkd3d_shader_dst_param *dst) +{ + vsir_dst_param_init(dst, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); + dst->reg.dimension = VSIR_DIMENSION_NONE; + dst->write_mask = 0; +} + static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx) { vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1); @@ -763,7 +770,7 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog } else { - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); + vsir_dst_param_init_null(&ins->dst[0]); } if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_0) @@ -773,7 +780,7 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog } else { - vsir_dst_param_init(&ins->dst[1], VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); + vsir_dst_param_init_null(&ins->dst[1]); } /* Make the original instruction no-op */ @@ -1299,7 +1306,7 @@ static void remove_unread_output_components(const struct shader_signature *signa if (ins->dst_count == 1) vkd3d_shader_instruction_make_nop(ins); else - vsir_dst_param_init(dst, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); + vsir_dst_param_init_null(dst); } } @@ -8248,6 +8255,14 @@ static void vsir_validate_dst_param(struct validation_context *ctx, switch (dst->reg.type) { case VKD3DSPR_SSA: + if (dst->reg.dimension == VSIR_DIMENSION_VEC4 + && dst->write_mask != VKD3DSP_WRITEMASK_0 + && dst->write_mask != (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1) + && dst->write_mask != (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_2) + && dst->write_mask != VKD3DSP_WRITEMASK_ALL) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK, + "SSA register has invalid write mask %#x.", dst->write_mask); + if (dst->reg.idx[0].offset < ctx->program->ssa_count) { struct validation_context_ssa_data *data = &ctx->ssas[dst->reg.idx[0].offset]; diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c index d477bfa1c1b..def6f459f69 100644 --- a/libs/vkd3d/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d/libs/vkd3d-shader/msl.c @@ -46,6 +46,14 @@ struct msl_generator const struct vkd3d_shader_interface_info *interface_info; }; +struct msl_resource_type_info +{ + size_t read_coord_size; + bool array; + bool lod; + const char *type_suffix; +}; + static void VKD3D_PRINTF_FUNC(3, 4) msl_compiler_error(struct msl_generator *gen, enum vkd3d_shader_error error, const char *fmt, ...) { @@ -57,6 +65,30 @@ static void VKD3D_PRINTF_FUNC(3, 4) msl_compiler_error(struct msl_generator *gen gen->failed = true; } +static const struct msl_resource_type_info *msl_get_resource_type_info(enum vkd3d_shader_resource_type t) +{ + static const struct msl_resource_type_info info[] = + { + [VKD3D_SHADER_RESOURCE_NONE] = {0, false, false, "none"}, + [VKD3D_SHADER_RESOURCE_BUFFER] = {1, false, false, "_buffer"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_1D] = {1, false, false, "1d"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_2D] = {2, false, true, "2d"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_2DMS] = {2, false, false, "2d_ms"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_3D] = {3, false, true, "3d"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_CUBE] = {2, false, true, "cube"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY] = {1, true, false, "1d_array"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY] = {2, true, true, "2d_array"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY] = {2, true, false, "2d_ms_array"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY] = {2, true, true, "cube_array"}, + }; + + if (!t || t >= ARRAY_SIZE(info)) + return NULL; + + return &info[t]; +} + + static const char *msl_get_prefix(enum vkd3d_shader_type type) { switch (type) @@ -83,6 +115,30 @@ static void msl_print_indent(struct vkd3d_string_buffer *buffer, unsigned int in vkd3d_string_buffer_printf(buffer, "%*s", 4 * indent, ""); } +static void msl_print_resource_datatype(struct msl_generator *gen, + struct vkd3d_string_buffer *buffer, enum vkd3d_data_type data_type) +{ + switch (data_type) + { + case VKD3D_DATA_FLOAT: + case VKD3D_DATA_UNORM: + case VKD3D_DATA_SNORM: + vkd3d_string_buffer_printf(buffer, "float"); + break; + case VKD3D_DATA_INT: + vkd3d_string_buffer_printf(buffer, "int"); + break; + case VKD3D_DATA_UINT: + vkd3d_string_buffer_printf(buffer, "uint"); + break; + default: + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled resource datatype %#x.", data_type); + vkd3d_string_buffer_printf(buffer, "", data_type); + break; + } +} + static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, enum vkd3d_data_type data_type) { @@ -106,6 +162,111 @@ static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer, } } +static bool msl_check_shader_visibility(const struct msl_generator *gen, + enum vkd3d_shader_visibility visibility) +{ + enum vkd3d_shader_type t = gen->program->shader_version.type; + + switch (visibility) + { + case VKD3D_SHADER_VISIBILITY_ALL: + return true; + case VKD3D_SHADER_VISIBILITY_VERTEX: + return t == VKD3D_SHADER_TYPE_VERTEX; + case VKD3D_SHADER_VISIBILITY_HULL: + return t == VKD3D_SHADER_TYPE_HULL; + case VKD3D_SHADER_VISIBILITY_DOMAIN: + return t == VKD3D_SHADER_TYPE_DOMAIN; + case VKD3D_SHADER_VISIBILITY_GEOMETRY: + return t == VKD3D_SHADER_TYPE_GEOMETRY; + case VKD3D_SHADER_VISIBILITY_PIXEL: + return t == VKD3D_SHADER_TYPE_PIXEL; + case VKD3D_SHADER_VISIBILITY_COMPUTE: + return t == VKD3D_SHADER_TYPE_COMPUTE; + default: + WARN("Invalid shader visibility %#x.\n", visibility); + return false; + } +} + +static const struct vkd3d_shader_descriptor_binding *msl_get_cbv_binding(const struct msl_generator *gen, + unsigned int register_space, unsigned int register_idx) +{ + const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; + unsigned int i; + + if (!interface_info) + return NULL; + + for (i = 0; i < interface_info->binding_count; ++i) + { + const struct vkd3d_shader_resource_binding *binding = &interface_info->bindings[i]; + + if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_CBV) + continue; + if (binding->register_space != register_space) + continue; + if (binding->register_index != register_idx) + continue; + if (!msl_check_shader_visibility(gen, binding->shader_visibility)) + continue; + if (!(binding->flags & VKD3D_SHADER_BINDING_FLAG_BUFFER)) + continue; + + return &binding->binding; + } + + return NULL; +} + +static const struct vkd3d_shader_descriptor_binding *msl_get_srv_binding(const struct msl_generator *gen, + unsigned int register_space, unsigned int register_idx, enum vkd3d_shader_resource_type resource_type) +{ + const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; + enum vkd3d_shader_binding_flag resource_type_flag; + unsigned int i; + + if (!interface_info) + return NULL; + + resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER + ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; + + for (i = 0; i < interface_info->binding_count; ++i) + { + const struct vkd3d_shader_resource_binding *binding = &interface_info->bindings[i]; + + if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SRV) + continue; + if (binding->register_space != register_space) + continue; + if (binding->register_index != register_idx) + continue; + if (!msl_check_shader_visibility(gen, binding->shader_visibility)) + continue; + if (!(binding->flags & resource_type_flag)) + continue; + + return &binding->binding; + } + + return NULL; +} + +static void msl_print_cbv_name(struct vkd3d_string_buffer *buffer, unsigned int binding) +{ + vkd3d_string_buffer_printf(buffer, "descriptors[%u].buf()", binding); +} + +static void msl_print_srv_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, unsigned int binding, + const struct msl_resource_type_info *resource_type_info, enum vkd3d_data_type resource_data_type) +{ + vkd3d_string_buffer_printf(buffer, "descriptors[%u].textype_suffix); + msl_print_resource_datatype(gen, buffer, resource_data_type); + vkd3d_string_buffer_printf(buffer, ">>()"); +} + static void msl_print_register_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, const struct vkd3d_shader_register *reg) { @@ -220,23 +381,36 @@ static void msl_print_register_name(struct vkd3d_string_buffer *buffer, break; case VKD3DSPR_CONSTBUFFER: - if (reg->idx_count != 3) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled constant buffer register index count %u.", reg->idx_count); - vkd3d_string_buffer_printf(buffer, "", reg->type); - break; - } - if (reg->idx[0].rel_addr || reg->idx[2].rel_addr) { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled constant buffer register indirect addressing."); - vkd3d_string_buffer_printf(buffer, "", reg->type); + const struct vkd3d_shader_descriptor_binding *binding; + + if (reg->idx_count != 3) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled constant buffer register index count %u.", + reg->idx_count); + vkd3d_string_buffer_printf(buffer, "", reg->type); + break; + } + if (reg->idx[0].rel_addr || reg->idx[1].rel_addr || reg->idx[2].rel_addr) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled constant buffer register indirect addressing."); + vkd3d_string_buffer_printf(buffer, "", reg->type); + break; + } + if (!(binding = msl_get_cbv_binding(gen, 0, reg->idx[1].offset))) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, + "Cannot finding binding for CBV register %u.", reg->idx[0].offset); + vkd3d_string_buffer_printf(buffer, "", reg->type); + break; + } + msl_print_cbv_name(buffer, binding->binding); + vkd3d_string_buffer_printf(buffer, "[%u]", reg->idx[2].offset); + msl_print_register_datatype(buffer, gen, reg->data_type); break; } - vkd3d_string_buffer_printf(buffer, "descriptors.cb_%u[%u]", reg->idx[0].offset, reg->idx[2].offset); - msl_print_register_datatype(buffer, gen, reg->data_type); - break; default: msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, @@ -529,6 +703,96 @@ static void msl_else(struct msl_generator *gen) msl_begin_block(gen); } +static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + const struct msl_resource_type_info *resource_type_info; + unsigned int resource_id, resource_idx, resource_space; + const struct vkd3d_shader_descriptor_info1 *descriptor; + const struct vkd3d_shader_descriptor_binding *binding; + enum vkd3d_shader_resource_type resource_type; + struct msl_src coord, array_index, lod; + struct vkd3d_string_buffer *read; + enum vkd3d_data_type data_type; + uint32_t coord_mask; + struct msl_dst dst; + + if (vkd3d_shader_instruction_has_texel_offset(ins)) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled texel fetch offset."); + + if (ins->src[1].reg.idx[0].rel_addr || ins->src[1].reg.idx[1].rel_addr) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, + "Descriptor indexing is not supported."); + + resource_id = ins->src[1].reg.idx[0].offset; + resource_idx = ins->src[1].reg.idx[1].offset; + if ((descriptor = vkd3d_shader_find_descriptor(&gen->program->descriptors, + VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_id))) + { + resource_type = descriptor->resource_type; + resource_space = descriptor->register_space; + data_type = descriptor->resource_data_type; + } + else + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Undeclared resource descriptor %u.", resource_id); + resource_space = 0; + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; + data_type = VKD3D_DATA_FLOAT; + } + + if ((resource_type_info = msl_get_resource_type_info(resource_type))) + { + coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->read_coord_size); + } + else + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled resource type %#x.", resource_type); + coord_mask = vkd3d_write_mask_from_component_count(2); + } + + if (!(binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type))) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, + "Cannot finding binding for SRV register %u index %u space %u.", + resource_id, resource_idx, resource_space); + return; + } + + msl_dst_init(&dst, gen, ins, &ins->dst[0]); + msl_src_init(&coord, gen, &ins->src[0], coord_mask); + /* `coord_mask + 1` gives exactly the array index component mask if it is an array resource */ + /* Or it's simply unused, saving some branches */ + msl_src_init(&array_index, gen, &ins->src[0], coord_mask + 1); + msl_src_init(&lod, gen, &ins->src[0], VKD3DSP_WRITEMASK_3); + read = vkd3d_string_buffer_get(&gen->string_buffers); + + vkd3d_string_buffer_printf(read, "as_type("); + msl_print_srv_name(read, gen, binding->binding, resource_type_info, data_type); + vkd3d_string_buffer_printf(read, ".read("); + if (resource_type_info->read_coord_size > 1) + vkd3d_string_buffer_printf(read, "as_type(%s)", + resource_type_info->read_coord_size, coord.str->buffer); + else + vkd3d_string_buffer_printf(read, "as_type(%s)", coord.str->buffer); + if (resource_type_info->array) + vkd3d_string_buffer_printf(read, ", as_type(%s)", array_index.str->buffer); + if (resource_type_info->lod) + vkd3d_string_buffer_printf(read, ", as_type(%s)", lod.str->buffer); + vkd3d_string_buffer_printf(read, "))"); + msl_print_swizzle(read, ins->src[1].swizzle, ins->dst[0].write_mask); + + msl_print_assignment(gen, &dst, "%s", read->buffer); + + vkd3d_string_buffer_release(&gen->string_buffers, read); + msl_src_cleanup(&lod, &gen->string_buffers); + msl_src_cleanup(&array_index, &gen->string_buffers); + msl_src_cleanup(&coord, &gen->string_buffers); + msl_dst_cleanup(&dst, &gen->string_buffers); +} + static void msl_unary_op(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *op) { struct msl_src src; @@ -670,6 +934,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d case VKD3DSIH_UTOF: msl_cast(gen, ins, "float"); break; + case VKD3DSIH_LD: + msl_ld(gen, ins); + break; case VKD3DSIH_LOG: msl_intrinsic(gen, ins, "log2"); break; @@ -715,144 +982,6 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d } } -static bool msl_check_shader_visibility(const struct msl_generator *gen, - enum vkd3d_shader_visibility visibility) -{ - enum vkd3d_shader_type t = gen->program->shader_version.type; - - switch (visibility) - { - case VKD3D_SHADER_VISIBILITY_ALL: - return true; - case VKD3D_SHADER_VISIBILITY_VERTEX: - return t == VKD3D_SHADER_TYPE_VERTEX; - case VKD3D_SHADER_VISIBILITY_HULL: - return t == VKD3D_SHADER_TYPE_HULL; - case VKD3D_SHADER_VISIBILITY_DOMAIN: - return t == VKD3D_SHADER_TYPE_DOMAIN; - case VKD3D_SHADER_VISIBILITY_GEOMETRY: - return t == VKD3D_SHADER_TYPE_GEOMETRY; - case VKD3D_SHADER_VISIBILITY_PIXEL: - return t == VKD3D_SHADER_TYPE_PIXEL; - case VKD3D_SHADER_VISIBILITY_COMPUTE: - return t == VKD3D_SHADER_TYPE_COMPUTE; - default: - WARN("Invalid shader visibility %#x.\n", visibility); - return false; - } -} - -static bool msl_get_cbv_binding(const struct msl_generator *gen, - unsigned int register_space, unsigned int register_idx, unsigned int *binding_idx) -{ - const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; - const struct vkd3d_shader_resource_binding *binding; - unsigned int i; - - if (!interface_info) - return false; - - for (i = 0; i < interface_info->binding_count; ++i) - { - binding = &interface_info->bindings[i]; - - if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_CBV) - continue; - if (binding->register_space != register_space) - continue; - if (binding->register_index != register_idx) - continue; - if (!msl_check_shader_visibility(gen, binding->shader_visibility)) - continue; - if (!(binding->flags & VKD3D_SHADER_BINDING_FLAG_BUFFER)) - continue; - *binding_idx = i; - return true; - } - - return false; -} - -static void msl_generate_cbv_declaration(struct msl_generator *gen, - const struct vkd3d_shader_descriptor_info1 *cbv) -{ - const struct vkd3d_shader_descriptor_binding *binding; - struct vkd3d_string_buffer *buffer = gen->buffer; - unsigned int binding_idx; - size_t size; - - if (cbv->count != 1) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, - "Constant buffer %u has unsupported descriptor array size %u.", cbv->register_id, cbv->count); - return; - } - - if (!msl_get_cbv_binding(gen, cbv->register_space, cbv->register_index, &binding_idx)) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, - "No descriptor binding specified for constant buffer %u.", cbv->register_id); - return; - } - - binding = &gen->interface_info->bindings[binding_idx].binding; - - if (binding->set != 0) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, - "Unsupported binding set %u specified for constant buffer %u.", binding->set, cbv->register_id); - return; - } - - if (binding->count != 1) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, - "Unsupported binding count %u specified for constant buffer %u.", binding->count, cbv->register_id); - return; - } - - size = align(cbv->buffer_size, VKD3D_VEC4_SIZE * sizeof(uint32_t)); - size /= VKD3D_VEC4_SIZE * sizeof(uint32_t); - - vkd3d_string_buffer_printf(buffer, - "constant vkd3d_vec4 *cb_%u [[id(%u)]];", cbv->register_id, binding->binding); -}; - -static void msl_generate_descriptor_struct_declarations(struct msl_generator *gen) -{ - const struct vkd3d_shader_scan_descriptor_info1 *info = &gen->program->descriptors; - const struct vkd3d_shader_descriptor_info1 *descriptor; - struct vkd3d_string_buffer *buffer = gen->buffer; - unsigned int i; - - if (!info->descriptor_count) - return; - - vkd3d_string_buffer_printf(buffer, "struct vkd3d_%s_descriptors\n{\n", gen->prefix); - - for (i = 0; i < info->descriptor_count; ++i) - { - descriptor = &info->descriptors[i]; - - msl_print_indent(buffer, 1); - switch (descriptor->type) - { - case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: - msl_generate_cbv_declaration(gen, descriptor); - break; - - default: - vkd3d_string_buffer_printf(buffer, "/* */", descriptor->type); - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled descriptor type %#x.", descriptor->type); - break; - } - vkd3d_string_buffer_printf(buffer, "\n"); - } - - vkd3d_string_buffer_printf(buffer, "};\n\n"); -} - static void msl_generate_input_struct_declarations(struct msl_generator *gen) { const struct shader_signature *signature = &gen->program->input_signature; @@ -1175,7 +1304,7 @@ static void msl_generate_entrypoint(struct msl_generator *gen) msl_print_indent(gen->buffer, 2); /* TODO: Configurable argument buffer binding location. */ vkd3d_string_buffer_printf(gen->buffer, - "constant vkd3d_%s_descriptors& descriptors [[buffer(0)]],\n", gen->prefix); + "constant descriptor *descriptors [[buffer(0)]],\n"); } msl_print_indent(gen->buffer, 2); @@ -1211,7 +1340,8 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader MESSAGE("Generating a MSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n"); vkd3d_string_buffer_printf(gen->buffer, "/* Generated by %s. */\n\n", vkd3d_shader_get_version(NULL, NULL)); - vkd3d_string_buffer_printf(gen->buffer, "#include \n\n"); + vkd3d_string_buffer_printf(gen->buffer, "#include \n"); + vkd3d_string_buffer_printf(gen->buffer, "#include \n\n"); vkd3d_string_buffer_printf(gen->buffer, "using namespace metal;\n\n"); if (gen->program->global_flags) @@ -1223,7 +1353,28 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader vkd3d_string_buffer_printf(gen->buffer, " int4 i;\n"); vkd3d_string_buffer_printf(gen->buffer, " float4 f;\n};\n\n"); - msl_generate_descriptor_struct_declarations(gen); + if (gen->program->descriptors.descriptor_count > 0) + { + vkd3d_string_buffer_printf(gen->buffer, + "struct descriptor\n" + "{\n" + " const device void *ptr;\n" + "\n" + " template\n" + " constant T &tex() constant\n" + " {\n" + " return reinterpret_cast(this->ptr);\n" + " }\n" + "\n" + " template\n" + " const device T * constant &buf() constant\n" + " {\n" + " return reinterpret_cast(this->ptr);\n" + " }\n" + "};\n" + "\n"); + } + msl_generate_input_struct_declarations(gen); msl_generate_output_struct_declarations(gen); @@ -1234,7 +1385,7 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader if (gen->write_depth) vkd3d_string_buffer_printf(gen->buffer, ", thread float& o_depth"); if (gen->program->descriptors.descriptor_count) - vkd3d_string_buffer_printf(gen->buffer, ", constant vkd3d_%s_descriptors& descriptors", gen->prefix); + vkd3d_string_buffer_printf(gen->buffer, ", constant descriptor *descriptors"); vkd3d_string_buffer_printf(gen->buffer, ")\n{\n"); ++gen->indent; diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c index 91a6686eb0d..05cc0b9a55e 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c @@ -7124,7 +7124,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp return; } - sampled_type = vkd3d_component_type_from_resource_data_type(descriptor->resource_data_type); + sampled_type = vkd3d_component_type_from_data_type(descriptor->resource_data_type); if (!is_uav && spirv_compiler_has_combined_sampler_for_resource(compiler, range)) { diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c index 9191429c439..a0c24eaf18a 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c @@ -1063,7 +1063,7 @@ static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_cont static struct vkd3d_shader_descriptor_info1 *vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context, enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register *reg, const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type, - enum vkd3d_shader_resource_data_type resource_data_type) + enum vkd3d_data_type resource_data_type) { struct vkd3d_shader_scan_descriptor_info1 *info = context->scan_descriptor_info; struct vkd3d_shader_descriptor_info1 *d; @@ -1099,7 +1099,7 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc struct vkd3d_shader_descriptor_info1 *d; if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, - &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT))) + &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT))) return; d->buffer_size = cb->size; } @@ -1111,7 +1111,7 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte struct vkd3d_shader_descriptor_info1 *d; if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, - &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT))) + &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UINT))) return; if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE) @@ -1122,9 +1122,9 @@ static void vkd3d_shader_scan_combined_sampler_declaration( struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_semantic *semantic) { vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &semantic->resource.reg.reg, - &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT); + &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UINT); vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, &semantic->resource.reg.reg, - &semantic->resource.range, semantic->resource_type, VKD3D_SHADER_RESOURCE_DATA_FLOAT); + &semantic->resource.range, semantic->resource_type, VKD3D_DATA_FLOAT); } const struct vkd3d_shader_descriptor_info1 *vkd3d_shader_find_descriptor( @@ -1214,8 +1214,8 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, - enum vkd3d_shader_resource_data_type resource_data_type, - unsigned int sample_count, unsigned int structure_stride, bool raw, uint32_t flags) + enum vkd3d_data_type resource_data_type, unsigned int sample_count, + unsigned int structure_stride, bool raw, uint32_t flags) { struct vkd3d_shader_descriptor_info1 *d; enum vkd3d_shader_descriptor_type type; @@ -1239,59 +1239,16 @@ static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_sca const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_semantic *semantic = &instruction->declaration.semantic; - enum vkd3d_shader_resource_data_type resource_data_type; - if (semantic->resource_data_type[0] != semantic->resource_data_type[1] || - semantic->resource_data_type[0] != semantic->resource_data_type[2] || - semantic->resource_data_type[0] != semantic->resource_data_type[3]) - FIXME("Resource data types are different (%d, %d, %d, %d).\n", - semantic->resource_data_type[0], - semantic->resource_data_type[1], - semantic->resource_data_type[2], - semantic->resource_data_type[3]); + if (semantic->resource_data_type[0] != semantic->resource_data_type[1] + || semantic->resource_data_type[0] != semantic->resource_data_type[2] + || semantic->resource_data_type[0] != semantic->resource_data_type[3]) + FIXME("Resource data types are different (%#x, %#x, %#x, %#x).\n", + semantic->resource_data_type[0], semantic->resource_data_type[1], + semantic->resource_data_type[2], semantic->resource_data_type[3]); - switch (semantic->resource_data_type[0]) - { - case VKD3D_DATA_UNORM: - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_UNORM; - break; - case VKD3D_DATA_SNORM: - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_SNORM; - break; - case VKD3D_DATA_INT: - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_INT; - break; - case VKD3D_DATA_UINT: - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_UINT; - break; - case VKD3D_DATA_FLOAT: - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_FLOAT; - break; - case VKD3D_DATA_MIXED: - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_MIXED; - break; - case VKD3D_DATA_DOUBLE: - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_DOUBLE; - break; - case VKD3D_DATA_CONTINUED: - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_CONTINUED; - break; - default: - ERR("Invalid resource data type %#x.\n", semantic->resource_data_type[0]); - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_FLOAT; - break; - } - - if (context->api_version < VKD3D_SHADER_API_VERSION_1_3 - && resource_data_type >= VKD3D_SHADER_RESOURCE_DATA_MIXED) - { - ERR("Invalid resource data type %#x for API version %#x.\n", - semantic->resource_data_type[0], context->api_version); - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_FLOAT; - } - - vkd3d_shader_scan_resource_declaration(context, &semantic->resource, - semantic->resource_type, resource_data_type, semantic->sample_count, 0, false, instruction->flags); + vkd3d_shader_scan_resource_declaration(context, &semantic->resource, semantic->resource_type, + semantic->resource_data_type[0], semantic->sample_count, 0, false, instruction->flags); } static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *context, @@ -1327,12 +1284,12 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte case VKD3DSIH_DCL_RESOURCE_RAW: case VKD3DSIH_DCL_UAV_RAW: vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.raw_resource.resource, - VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, 0, true, instruction->flags); + VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, 0, true, instruction->flags); break; case VKD3DSIH_DCL_RESOURCE_STRUCTURED: case VKD3DSIH_DCL_UAV_STRUCTURED: vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.structured_resource.resource, - VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, + VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, instruction->declaration.structured_resource.byte_stride, false, instruction->flags); break; case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: @@ -1543,8 +1500,34 @@ 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) +static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_type(enum vkd3d_data_type data_type) +{ + switch (data_type) + { + case VKD3D_DATA_UNORM: + return VKD3D_SHADER_RESOURCE_DATA_UNORM; + case VKD3D_DATA_SNORM: + return VKD3D_SHADER_RESOURCE_DATA_SNORM; + case VKD3D_DATA_INT: + return VKD3D_SHADER_RESOURCE_DATA_INT; + case VKD3D_DATA_UINT: + return VKD3D_SHADER_RESOURCE_DATA_UINT; + case VKD3D_DATA_FLOAT: + return VKD3D_SHADER_RESOURCE_DATA_FLOAT; + case VKD3D_DATA_MIXED: + return VKD3D_SHADER_RESOURCE_DATA_MIXED; + case VKD3D_DATA_DOUBLE: + return VKD3D_SHADER_RESOURCE_DATA_DOUBLE; + case VKD3D_DATA_CONTINUED: + return VKD3D_SHADER_RESOURCE_DATA_CONTINUED; + default: + ERR("Invalid resource data type %#x.\n", data_type); + return VKD3D_SHADER_RESOURCE_DATA_FLOAT; + } +} + +static enum vkd3d_result convert_descriptor_info(struct vkd3d_shader_scan_context *context, + struct vkd3d_shader_scan_descriptor_info *info, const struct vkd3d_shader_scan_descriptor_info1 *info1) { unsigned int i; @@ -1560,9 +1543,17 @@ static enum vkd3d_result convert_descriptor_info(struct vkd3d_shader_scan_descri 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->resource_data_type = vkd3d_resource_data_type_from_data_type(src->resource_data_type); dst->flags = src->flags; dst->count = src->count; + + if (context->api_version < VKD3D_SHADER_API_VERSION_1_3 + && dst->resource_data_type >= VKD3D_SHADER_RESOURCE_DATA_MIXED) + { + ERR("Invalid resource data type %#x for API version %#x.\n", + src->resource_data_type, context->api_version); + dst->resource_data_type = VKD3D_SHADER_RESOURCE_DATA_FLOAT; + } } info->descriptor_count = info1->descriptor_count; @@ -1629,7 +1620,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh if (size) { if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, ®, - &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT))) + &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT))) d->buffer_size = size * 16; } } @@ -1647,7 +1638,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh } if (!ret && descriptor_info) - ret = convert_descriptor_info(descriptor_info, &program->descriptors); + ret = convert_descriptor_info(&context, descriptor_info, &program->descriptors); if (!ret && tessellation_info) { diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h index bf794d5e936..05ef8beeb9c 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -262,6 +262,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_MSL_INTERNAL = 10000, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND = 10001, + VKD3D_SHADER_ERROR_MSL_UNSUPPORTED = 10002, VKD3D_SHADER_ERROR_FX_NOT_IMPLEMENTED = 11000, VKD3D_SHADER_ERROR_FX_INVALID_VERSION = 11001, @@ -1005,6 +1006,7 @@ void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader enum vkd3d_data_type data_type, unsigned int idx_count); void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int idx_count); +void vsir_dst_param_init_null(struct vkd3d_shader_dst_param *dst); void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id); struct vkd3d_shader_index_range @@ -1429,7 +1431,7 @@ struct vkd3d_shader_descriptor_info1 unsigned int register_index; unsigned int register_id; enum vkd3d_shader_resource_type resource_type; - enum vkd3d_shader_resource_data_type resource_data_type; + enum vkd3d_data_type resource_data_type; unsigned int flags; unsigned int sample_count; unsigned int buffer_size; @@ -1562,6 +1564,8 @@ enum vsir_asm_flags VSIR_ASM_FLAG_NONE = 0, VSIR_ASM_FLAG_DUMP_TYPES = 0x1, VSIR_ASM_FLAG_DUMP_ALL_INDICES = 0x2, + VSIR_ASM_FLAG_DUMP_SIGNATURES = 0x4, + VSIR_ASM_FLAG_DUMP_DESCRIPTORS = 0x8, }; enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, @@ -1653,7 +1657,8 @@ void vkd3d_shader_trace_text_(const char *text, size_t size, const char *functio vkd3d_shader_trace_text_(text, size, __FUNCTION__) bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, const char *semantic_name, - unsigned int semantic_index, bool output, enum vkd3d_shader_register_type *type, unsigned int *reg); + unsigned int semantic_index, bool output, enum vkd3d_shader_sysval_semantic *sysval, + enum vkd3d_shader_register_type *type, unsigned int *reg); bool sm1_usage_from_semantic_name(const char *semantic_name, uint32_t semantic_index, enum vkd3d_decl_usage *usage, uint32_t *usage_idx); bool sm4_register_from_semantic_name(const struct vkd3d_shader_version *version, @@ -1764,30 +1769,6 @@ static inline enum vkd3d_data_type vkd3d_data_type_from_component_type( } } -static inline enum vkd3d_shader_component_type vkd3d_component_type_from_resource_data_type( - enum vkd3d_shader_resource_data_type data_type) -{ - switch (data_type) - { - case VKD3D_SHADER_RESOURCE_DATA_FLOAT: - case VKD3D_SHADER_RESOURCE_DATA_UNORM: - case VKD3D_SHADER_RESOURCE_DATA_SNORM: - return VKD3D_SHADER_COMPONENT_FLOAT; - case VKD3D_SHADER_RESOURCE_DATA_UINT: - return VKD3D_SHADER_COMPONENT_UINT; - case VKD3D_SHADER_RESOURCE_DATA_INT: - return VKD3D_SHADER_COMPONENT_INT; - case VKD3D_SHADER_RESOURCE_DATA_DOUBLE: - case VKD3D_SHADER_RESOURCE_DATA_CONTINUED: - return VKD3D_SHADER_COMPONENT_DOUBLE; - default: - FIXME("Unhandled data type %#x.\n", data_type); - /* fall-through */ - case VKD3D_SHADER_RESOURCE_DATA_MIXED: - return VKD3D_SHADER_COMPONENT_UINT; - } -} - static inline bool component_type_is_64_bit(enum vkd3d_shader_component_type component_type) { return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_UINT64; -- 2.47.2