From 72a24faa48be8d8a3b396a94fb8e028b7eaf6898 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 20 Sep 2024 07:31:45 +1000 Subject: [PATCH] Updated vkd3d to 32ced3bd8f52e19d184c8191f420dcb7badbbad2. --- libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 35 +- libs/vkd3d/libs/vkd3d-shader/glsl.c | 334 +++++++++++++++++- libs/vkd3d/libs/vkd3d-shader/msl.c | 146 ++++++++ libs/vkd3d/libs/vkd3d-shader/tpf.c | 18 +- .../libs/vkd3d-shader/vkd3d_shader_main.c | 3 +- .../libs/vkd3d-shader/vkd3d_shader_private.h | 6 +- 6 files changed, 506 insertions(+), 36 deletions(-) diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c index 9c7be1f08bb..10f2e5e5e6d 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -104,6 +104,19 @@ enum vkd3d_sm1_resource_type VKD3D_SM1_RESOURCE_TEXTURE_3D = 0x4, }; +enum vkd3d_sm1_misc_register +{ + VKD3D_SM1_MISC_POSITION = 0x0, + VKD3D_SM1_MISC_FACE = 0x1, +}; + +enum vkd3d_sm1_rastout_register +{ + VKD3D_SM1_RASTOUT_POSITION = 0x0, + VKD3D_SM1_RASTOUT_FOG = 0x1, + VKD3D_SM1_RASTOUT_POINT_SIZE = 0x2, +}; + enum vkd3d_sm1_opcode { VKD3D_SM1_OP_NOP = 0x00, @@ -1385,22 +1398,22 @@ bool hlsl_sm1_register_from_semantic(const struct vkd3d_shader_version *version, {"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, D3DSMO_POSITION}, - {"vface", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, D3DSMO_FACE}, - {"vpos", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, D3DSMO_POSITION}, + {"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, D3DSRO_FOG}, - {"position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, D3DSRO_POSITION}, - {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, D3DSRO_POINT_SIZE}, - {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, D3DSRO_POSITION}, + {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_FOG}, + {"position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POSITION}, + {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POINT_SIZE}, + {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VKD3D_SM1_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, D3DSRO_FOG}, - {"position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, D3DSRO_POSITION}, - {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, D3DSRO_POINT_SIZE}, - {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, D3DSRO_POSITION}, + {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_FOG}, + {"position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POSITION}, + {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POINT_SIZE}, + {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VKD3D_SM1_RASTOUT_POSITION}, {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_TEXCRDOUT}, }; diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c index f8fec6ac2bc..ac101d44214 100644 --- a/libs/vkd3d/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c @@ -48,6 +48,10 @@ struct vkd3d_glsl_generator } limits; bool interstage_input; bool interstage_output; + + const struct vkd3d_shader_interface_info *interface_info; + const struct vkd3d_shader_descriptor_offset_info *offset_info; + const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info; }; static void VKD3D_PRINTF_FUNC(3, 4) vkd3d_glsl_compiler_error( @@ -133,6 +137,40 @@ static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer, vkd3d_string_buffer_printf(buffer, "%s_out[%u]", gen->prefix, reg->idx[0].offset); break; + case VKD3DSPR_IMMCONST: + switch (reg->dimension) + { + case VSIR_DIMENSION_SCALAR: + vkd3d_string_buffer_printf(buffer, "%#xu", reg->u.immconst_u32[0]); + break; + + default: + vkd3d_string_buffer_printf(buffer, "", reg->dimension); + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled dimension %#x.", reg->dimension); + break; + } + break; + + case VKD3DSPR_CONSTBUFFER: + if (reg->idx_count != 3) + { + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_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) + { + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled constant buffer register indirect addressing."); + vkd3d_string_buffer_printf(buffer, "", reg->type); + break; + } + vkd3d_string_buffer_printf(buffer, "%s_cb_%u[%u]", + gen->prefix, reg->idx[0].offset, reg->idx[2].offset); + break; + default: vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled register type %#x.", reg->type); @@ -172,23 +210,86 @@ static void glsl_src_cleanup(struct glsl_src *src, struct vkd3d_string_buffer_ca vkd3d_string_buffer_release(cache, src->str); } +static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vkd3d_glsl_generator *gen, + const char *src, enum vkd3d_data_type dst_data_type, enum vkd3d_data_type src_data_type) +{ + if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM) + dst_data_type = VKD3D_DATA_FLOAT; + if (src_data_type == VKD3D_DATA_UNORM || src_data_type == VKD3D_DATA_SNORM) + src_data_type = VKD3D_DATA_FLOAT; + + if (dst_data_type == src_data_type) + { + vkd3d_string_buffer_printf(dst, "%s", src); + return; + } + + if (src_data_type == VKD3D_DATA_FLOAT && dst_data_type == VKD3D_DATA_UINT) + { + vkd3d_string_buffer_printf(dst, "floatBitsToUint(%s)", src); + return; + } + + if (src_data_type == VKD3D_DATA_UINT && dst_data_type == VKD3D_DATA_FLOAT) + { + vkd3d_string_buffer_printf(dst, "uintBitsToFloat(%s)", src); + return; + } + + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled bitcast from %#x to %#x.", + src_data_type, dst_data_type); + vkd3d_string_buffer_printf(dst, "%s", src); +} + static void glsl_src_init(struct glsl_src *glsl_src, struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_src_param *vsir_src, uint32_t mask) { const struct vkd3d_shader_register *reg = &vsir_src->reg; + struct vkd3d_string_buffer *register_name, *str; + enum vkd3d_data_type src_data_type; glsl_src->str = vkd3d_string_buffer_get(&gen->string_buffers); + register_name = vkd3d_string_buffer_get(&gen->string_buffers); if (reg->non_uniform) vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled 'non-uniform' modifier."); - if (vsir_src->modifiers) - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); - shader_glsl_print_register_name(glsl_src->str, gen, reg); + if (reg->type == VKD3DSPR_IMMCONST) + src_data_type = VKD3D_DATA_UINT; + else + src_data_type = VKD3D_DATA_FLOAT; + + shader_glsl_print_register_name(register_name, gen, reg); + + if (!vsir_src->modifiers) + str = glsl_src->str; + else + str = vkd3d_string_buffer_get(&gen->string_buffers); + + shader_glsl_print_bitcast(str, gen, register_name->buffer, reg->data_type, src_data_type); if (reg->dimension == VSIR_DIMENSION_VEC4) - shader_glsl_print_swizzle(glsl_src->str, vsir_src->swizzle, mask); + shader_glsl_print_swizzle(str, vsir_src->swizzle, mask); + + switch (vsir_src->modifiers) + { + case VKD3DSPSM_NONE: + break; + case VKD3DSPSM_ABS: + vkd3d_string_buffer_printf(glsl_src->str, "abs(%s)", str->buffer); + break; + default: + vkd3d_string_buffer_printf(glsl_src->str, "(%s)", + vsir_src->modifiers, str->buffer); + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); + break; + } + + if (str != glsl_src->str) + vkd3d_string_buffer_release(&gen->string_buffers, str); + vkd3d_string_buffer_release(&gen->string_buffers, register_name); } static void glsl_dst_cleanup(struct glsl_dst *dst, struct vkd3d_string_buffer_cache *cache) @@ -222,6 +323,9 @@ static uint32_t glsl_dst_init(struct glsl_dst *glsl_dst, struct vkd3d_glsl_gener static void VKD3D_PRINTF_FUNC(3, 4) shader_glsl_print_assignment( struct vkd3d_glsl_generator *gen, struct glsl_dst *dst, const char *format, ...) { + const struct vkd3d_shader_register *dst_reg = &dst->vsir->reg; + struct vkd3d_string_buffer *buffer = gen->buffer; + bool close = true; va_list args; if (dst->vsir->shift) @@ -231,14 +335,28 @@ static void VKD3D_PRINTF_FUNC(3, 4) shader_glsl_print_assignment( vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled destination modifier(s) %#x.", dst->vsir->modifiers); - shader_glsl_print_indent(gen->buffer, gen->indent); - vkd3d_string_buffer_printf(gen->buffer, "%s%s = ", dst->register_name->buffer, dst->mask->buffer); + shader_glsl_print_indent(buffer, gen->indent); + vkd3d_string_buffer_printf(buffer, "%s%s = ", dst->register_name->buffer, dst->mask->buffer); + + switch (dst_reg->data_type) + { + default: + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled destination register data type %#x.", dst_reg->data_type); + /* fall through */ + case VKD3D_DATA_FLOAT: + close = false; + break; + case VKD3D_DATA_UINT: + vkd3d_string_buffer_printf(buffer, "uintBitsToFloat("); + break; + } va_start(args, format); - vkd3d_string_buffer_vprintf(gen->buffer, format, args); + vkd3d_string_buffer_vprintf(buffer, format, args); va_end(args); - vkd3d_string_buffer_printf(gen->buffer, ";\n"); + vkd3d_string_buffer_printf(buffer, "%s;\n", close ? ")" : ""); } static void shader_glsl_unhandled(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) @@ -249,6 +367,24 @@ static void shader_glsl_unhandled(struct vkd3d_glsl_generator *gen, const struct "Internal compiler error: Unhandled instruction %#x.", ins->opcode); } +static void shader_glsl_binop(struct vkd3d_glsl_generator *gen, + const struct vkd3d_shader_instruction *ins, const char *op) +{ + struct glsl_src src[2]; + struct glsl_dst dst; + uint32_t mask; + + mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); + glsl_src_init(&src[0], gen, &ins->src[0], mask); + glsl_src_init(&src[1], gen, &ins->src[1], mask); + + shader_glsl_print_assignment(gen, &dst, "%s %s %s", src[0].str->buffer, op, src[1].str->buffer); + + glsl_src_cleanup(&src[1], &gen->string_buffers); + glsl_src_cleanup(&src[0], &gen->string_buffers); + glsl_dst_cleanup(&dst, &gen->string_buffers); +} + static void shader_glsl_mov(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) { struct glsl_src src; @@ -267,11 +403,12 @@ static void shader_glsl_mov(struct vkd3d_glsl_generator *gen, const struct vkd3d static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen, enum vkd3d_shader_sysval_semantic sysval, unsigned int idx) { + const struct vkd3d_shader_version *version = &gen->program->shader_version; + switch (sysval) { case VKD3D_SHADER_SV_POSITION: - if (gen->program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL - || gen->program->shader_version.type == VKD3D_SHADER_TYPE_COMPUTE) + if (version->type == VKD3D_SHADER_TYPE_PIXEL || version->type == VKD3D_SHADER_TYPE_COMPUTE) { vkd3d_string_buffer_printf(buffer, "", sysval); vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, @@ -286,6 +423,13 @@ static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, st } break; + case VKD3D_SHADER_SV_TARGET: + if (version->type != VKD3D_SHADER_TYPE_PIXEL) + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled SV_TARGET in shader type #%x.", version->type); + vkd3d_string_buffer_printf(buffer, "shader_out_%u", idx); + break; + default: vkd3d_string_buffer_printf(buffer, "", sysval); vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, @@ -400,6 +544,12 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, switch (ins->opcode) { + case VKD3DSIH_ADD: + shader_glsl_binop(gen, ins, "+"); + break; + case VKD3DSIH_AND: + shader_glsl_binop(gen, ins, "&"); + break; case VKD3DSIH_DCL_INPUT: case VKD3DSIH_DCL_OUTPUT: case VKD3DSIH_DCL_OUTPUT_SIV: @@ -417,6 +567,151 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, } } +static bool shader_glsl_check_shader_visibility(const struct vkd3d_glsl_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 shader_glsl_get_cbv_binding(const struct vkd3d_glsl_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 (!shader_glsl_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 shader_glsl_generate_cbv_declaration(struct vkd3d_glsl_generator *gen, + const struct vkd3d_shader_descriptor_info1 *cbv) +{ + const struct vkd3d_shader_descriptor_binding *binding; + const struct vkd3d_shader_descriptor_offset *offset; + struct vkd3d_string_buffer *buffer = gen->buffer; + const char *prefix = gen->prefix; + unsigned int binding_idx; + size_t size; + + if (cbv->count != 1) + { + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND, + "Constant buffer %u has unsupported descriptor array size %u.", cbv->register_id, cbv->count); + return; + } + + if (!shader_glsl_get_cbv_binding(gen, cbv->register_space, cbv->register_index, &binding_idx)) + { + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_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) + { + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND, + "Unsupported binding set %u specified for constant buffer %u.", binding->set, cbv->register_id); + return; + } + + if (binding->count != 1) + { + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND, + "Unsupported binding count %u specified for constant buffer %u.", binding->count, cbv->register_id); + return; + } + + if (gen->offset_info && gen->offset_info->binding_offsets) + { + offset = &gen->offset_info->binding_offsets[binding_idx]; + if (offset->static_offset || offset->dynamic_offset_index != ~0u) + { + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled descriptor offset specified for constant buffer %u.", + 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, + "layout(std140, binding = %u) uniform block_%s_cb_%u { vec4 %s_cb_%u[%zu]; };\n", + binding->binding, prefix, cbv->register_id, prefix, cbv->register_id, size); +} + +static void shader_glsl_generate_descriptor_declarations(struct vkd3d_glsl_generator *gen) +{ + const struct vkd3d_shader_scan_descriptor_info1 *info = gen->descriptor_info; + const struct vkd3d_shader_descriptor_info1 *descriptor; + unsigned int i; + + for (i = 0; i < info->descriptor_count; ++i) + { + descriptor = &info->descriptors[i]; + + switch (descriptor->type) + { + case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: + shader_glsl_generate_cbv_declaration(gen, descriptor); + break; + + default: + vkd3d_string_buffer_printf(gen->buffer, "/* */\n", descriptor->type); + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled descriptor type %#x.", descriptor->type); + break; + } + } + if (info->descriptor_count) + vkd3d_string_buffer_printf(gen->buffer, "\n"); +} + static void shader_glsl_generate_interface_block(struct vkd3d_string_buffer *buffer, const char *type, unsigned int count) { @@ -545,6 +840,7 @@ static void shader_glsl_generate_declarations(struct vkd3d_glsl_generator *gen) const struct vsir_program *program = gen->program; struct vkd3d_string_buffer *buffer = gen->buffer; + shader_glsl_generate_descriptor_declarations(gen); shader_glsl_generate_input_declarations(gen); shader_glsl_generate_output_declarations(gen); @@ -634,7 +930,9 @@ static void shader_glsl_init_limits(struct vkd3d_glsl_generator *gen, const stru } static void vkd3d_glsl_generator_init(struct vkd3d_glsl_generator *gen, - struct vsir_program *program, struct vkd3d_shader_message_context *message_context) + struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, + const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info, + struct vkd3d_shader_message_context *message_context) { enum vkd3d_shader_type type = program->shader_version.type; @@ -642,6 +940,7 @@ static void vkd3d_glsl_generator_init(struct vkd3d_glsl_generator *gen, gen->program = program; vkd3d_string_buffer_cache_init(&gen->string_buffers); gen->buffer = vkd3d_string_buffer_get(&gen->string_buffers); + gen->location.source_name = compile_info->source_name; gen->message_context = message_context; if (!(gen->prefix = shader_glsl_get_prefix(type))) { @@ -652,11 +951,16 @@ static void vkd3d_glsl_generator_init(struct vkd3d_glsl_generator *gen, shader_glsl_init_limits(gen, &program->shader_version); gen->interstage_input = type != VKD3D_SHADER_TYPE_VERTEX; gen->interstage_output = type != VKD3D_SHADER_TYPE_PIXEL; + + gen->interface_info = vkd3d_find_struct(compile_info->next, INTERFACE_INFO); + gen->offset_info = vkd3d_find_struct(compile_info->next, DESCRIPTOR_OFFSET_INFO); + gen->descriptor_info = descriptor_info; } int glsl_compile(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, - struct vkd3d_shader_message_context *message_context) + const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info, + const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) { struct vkd3d_glsl_generator generator; int ret; @@ -664,7 +968,7 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags, if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0) return ret; - vkd3d_glsl_generator_init(&generator, program, message_context); + vkd3d_glsl_generator_init(&generator, program, compile_info, descriptor_info, message_context); ret = vkd3d_glsl_generator_generate(&generator, out); vkd3d_glsl_generator_cleanup(&generator); diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c index 2923494feed..7d2e713cddc 100644 --- a/libs/vkd3d/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d/libs/vkd3d-shader/msl.c @@ -18,6 +18,18 @@ #include "vkd3d_shader_private.h" +struct msl_src +{ + struct vkd3d_string_buffer *str; +}; + +struct msl_dst +{ + const struct vkd3d_shader_dst_param *vsir; + struct vkd3d_string_buffer *register_name; + struct vkd3d_string_buffer *mask; +}; + struct msl_generator { struct vsir_program *program; @@ -43,6 +55,113 @@ 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_register_name(struct vkd3d_string_buffer *buffer, + struct msl_generator *gen, const struct vkd3d_shader_register *reg) +{ + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled register type %#x.", reg->type); + vkd3d_string_buffer_printf(buffer, "", reg->type); +} + +static void msl_print_swizzle(struct vkd3d_string_buffer *buffer, uint32_t swizzle, uint32_t mask) +{ + const char swizzle_chars[] = "xyzw"; + unsigned int i; + + vkd3d_string_buffer_printf(buffer, "."); + for (i = 0; i < VKD3D_VEC4_SIZE; ++i) + { + if (mask & (VKD3DSP_WRITEMASK_0 << i)) + vkd3d_string_buffer_printf(buffer, "%c", swizzle_chars[vsir_swizzle_get_component(swizzle, i)]); + } +} + +static void msl_print_write_mask(struct vkd3d_string_buffer *buffer, uint32_t write_mask) +{ + vkd3d_string_buffer_printf(buffer, "."); + if (write_mask & VKD3DSP_WRITEMASK_0) + vkd3d_string_buffer_printf(buffer, "x"); + if (write_mask & VKD3DSP_WRITEMASK_1) + vkd3d_string_buffer_printf(buffer, "y"); + if (write_mask & VKD3DSP_WRITEMASK_2) + vkd3d_string_buffer_printf(buffer, "z"); + if (write_mask & VKD3DSP_WRITEMASK_3) + vkd3d_string_buffer_printf(buffer, "w"); +} + +static void msl_src_cleanup(struct msl_src *src, struct vkd3d_string_buffer_cache *cache) +{ + vkd3d_string_buffer_release(cache, src->str); +} + +static void msl_src_init(struct msl_src *msl_src, struct msl_generator *gen, + const struct vkd3d_shader_src_param *vsir_src, uint32_t mask) +{ + const struct vkd3d_shader_register *reg = &vsir_src->reg; + + msl_src->str = vkd3d_string_buffer_get(&gen->string_buffers); + + if (reg->non_uniform) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled 'non-uniform' modifier."); + if (vsir_src->modifiers) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); + + msl_print_register_name(msl_src->str, gen, reg); + if (reg->dimension == VSIR_DIMENSION_VEC4) + msl_print_swizzle(msl_src->str, vsir_src->swizzle, mask); +} + +static void msl_dst_cleanup(struct msl_dst *dst, struct vkd3d_string_buffer_cache *cache) +{ + vkd3d_string_buffer_release(cache, dst->mask); + vkd3d_string_buffer_release(cache, dst->register_name); +} + +static uint32_t msl_dst_init(struct msl_dst *msl_dst, struct msl_generator *gen, + const struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_dst_param *vsir_dst) +{ + uint32_t write_mask = vsir_dst->write_mask; + + if (ins->flags & VKD3DSI_PRECISE_XYZW) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled 'precise' modifier."); + if (vsir_dst->reg.non_uniform) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled 'non-uniform' modifier."); + + msl_dst->vsir = vsir_dst; + msl_dst->register_name = vkd3d_string_buffer_get(&gen->string_buffers); + msl_dst->mask = vkd3d_string_buffer_get(&gen->string_buffers); + + msl_print_register_name(msl_dst->register_name, gen, &vsir_dst->reg); + msl_print_write_mask(msl_dst->mask, write_mask); + + return write_mask; +} + +static void VKD3D_PRINTF_FUNC(3, 4) msl_print_assignment( + struct msl_generator *gen, struct msl_dst *dst, const char *format, ...) +{ + va_list args; + + if (dst->vsir->shift) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled destination shift %#x.", dst->vsir->shift); + if (dst->vsir->modifiers) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled destination modifier(s) %#x.", dst->vsir->modifiers); + + msl_print_indent(gen->buffer, gen->indent); + vkd3d_string_buffer_printf(gen->buffer, "%s%s = ", dst->register_name->buffer, dst->mask->buffer); + + va_start(args, format); + vkd3d_string_buffer_vprintf(gen->buffer, format, args); + va_end(args); + + vkd3d_string_buffer_printf(gen->buffer, ";\n"); +} static void msl_unhandled(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) { @@ -52,6 +171,27 @@ static void msl_unhandled(struct msl_generator *gen, const struct vkd3d_shader_i "Internal compiler error: Unhandled instruction %#x.", ins->opcode); } +static void msl_mov(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + struct msl_src src; + struct msl_dst dst; + uint32_t mask; + + mask = msl_dst_init(&dst, gen, ins, &ins->dst[0]); + msl_src_init(&src, gen, &ins->src[0], mask); + + msl_print_assignment(gen, &dst, "%s", src.str->buffer); + + msl_src_cleanup(&src, &gen->string_buffers); + msl_dst_cleanup(&dst, &gen->string_buffers); +} + +static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + msl_print_indent(gen->buffer, gen->indent); + vkd3d_string_buffer_printf(gen->buffer, "return;\n"); +} + static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) { gen->location = ins->location; @@ -60,6 +200,12 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d { case VKD3DSIH_NOP: break; + case VKD3DSIH_MOV: + msl_mov(gen, ins); + break; + case VKD3DSIH_RET: + msl_ret(gen, ins); + break; default: msl_unhandled(gen, ins); break; diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c index 48efe1e2d72..cbf28f5ec50 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -645,6 +645,9 @@ enum vkd3d_sm4_stat_field VKD3D_STAT_TESS_PARTITIONING, VKD3D_STAT_TESS_OUTPUT_PRIMITIVE, VKD3D_STAT_TESS_CONTROL_POINT_COUNT, + VKD3D_STAT_BARRIER, + VKD3D_STAT_LOD, + VKD3D_STAT_GATHER, VKD3D_STAT_COUNT, }; @@ -1793,17 +1796,16 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) {VKD3D_SM4_OP_SAMPLE_LOD, VKD3D_STAT_SAMPLE}, {VKD3D_SM5_OP_SAMPLE_LOD_S, VKD3D_STAT_SAMPLE}, {VKD3D_SM5_OP_SAMPLE_CL_S, VKD3D_STAT_SAMPLE}, - {VKD3D_SM4_OP_GATHER4, VKD3D_STAT_SAMPLE}, - {VKD3D_SM5_OP_GATHER4_PO, VKD3D_STAT_SAMPLE}, {VKD3D_SM4_OP_SAMPLE_C, VKD3D_STAT_SAMPLE_C}, {VKD3D_SM4_OP_SAMPLE_C_LZ, VKD3D_STAT_SAMPLE_C}, {VKD3D_SM5_OP_SAMPLE_C_LZ_S, VKD3D_STAT_SAMPLE_C}, {VKD3D_SM5_OP_SAMPLE_C_CL_S, VKD3D_STAT_SAMPLE_C}, - {VKD3D_SM5_OP_GATHER4_C, VKD3D_STAT_SAMPLE_C}, - {VKD3D_SM5_OP_GATHER4_PO_C, VKD3D_STAT_SAMPLE_C}, {VKD3D_SM4_OP_SAMPLE_GRAD, VKD3D_STAT_SAMPLE_GRAD}, {VKD3D_SM5_OP_SAMPLE_GRAD_CL_S, VKD3D_STAT_SAMPLE_GRAD}, {VKD3D_SM4_OP_SAMPLE_B, VKD3D_STAT_SAMPLE_BIAS}, + {VKD3D_SM4_OP_GATHER4, VKD3D_STAT_GATHER}, + {VKD3D_SM5_OP_GATHER4_PO, VKD3D_STAT_GATHER}, + {VKD3D_SM4_OP_LOD, VKD3D_STAT_LOD}, {VKD3D_SM4_OP_LD, VKD3D_STAT_LOAD}, {VKD3D_SM4_OP_LD2DMS, VKD3D_STAT_LOAD}, @@ -1857,6 +1859,8 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) {VKD3D_SM5_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, VKD3D_STAT_TESS_OUTPUT_PRIMITIVE}, {VKD3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT, VKD3D_STAT_TESS_CONTROL_POINT_COUNT}, {VKD3D_SM5_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, VKD3D_STAT_TESS_CONTROL_POINT_COUNT}, + + {VKD3D_SM5_OP_SYNC, VKD3D_STAT_BARRIER}, }; memset(lookup, 0, sizeof(*lookup)); @@ -6433,8 +6437,8 @@ static void write_sm4_stat(struct hlsl_ctx *ctx, const struct sm4_stat *stat, st put_u32(&buffer, stat->fields[VKD3D_STAT_DCL_INPUT_PRIMITIVE]); put_u32(&buffer, stat->fields[VKD3D_STAT_DCL_OUTPUT_TOPOLOGY]); put_u32(&buffer, stat->fields[VKD3D_STAT_DCL_VERTICES_OUT]); - put_u32(&buffer, 0); /* Unknown */ - put_u32(&buffer, 0); /* Unknown */ + put_u32(&buffer, stat->fields[VKD3D_STAT_GATHER]); + put_u32(&buffer, stat->fields[VKD3D_STAT_LOD]); put_u32(&buffer, 0); /* Sample frequency */ if (hlsl_version_ge(ctx, 5, 0)) @@ -6444,7 +6448,7 @@ static void write_sm4_stat(struct hlsl_ctx *ctx, const struct sm4_stat *stat, st put_u32(&buffer, stat->fields[VKD3D_STAT_TESS_OUTPUT_PRIMITIVE]); put_u32(&buffer, stat->fields[VKD3D_STAT_TESS_PARTITIONING]); put_u32(&buffer, stat->fields[VKD3D_STAT_TESS_DOMAIN]); - put_u32(&buffer, 0); /* Barrier instructions */ + put_u32(&buffer, stat->fields[VKD3D_STAT_BARRIER]); put_u32(&buffer, stat->fields[VKD3D_STAT_ATOMIC]); put_u32(&buffer, stat->fields[VKD3D_STAT_STORE]); } diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c index ee98a504a5b..fc217860403 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c @@ -1635,7 +1635,8 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, case VKD3D_SHADER_TARGET_GLSL: if ((ret = vsir_program_scan(program, &scan_info, message_context, &scan_descriptor_info)) < 0) return ret; - ret = glsl_compile(program, config_flags, compile_info, out, message_context); + ret = glsl_compile(program, config_flags, &scan_descriptor_info, + compile_info, out, message_context); vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info); break; diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h index 8146a393a4c..a5d869172d3 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -168,6 +168,7 @@ enum vkd3d_shader_error VKD3D_SHADER_WARNING_HLSL_IGNORED_DEFAULT_VALUE = 5306, VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000, + VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND = 6001, VKD3D_SHADER_ERROR_D3DBC_UNEXPECTED_EOF = 7000, VKD3D_SHADER_ERROR_D3DBC_INVALID_VERSION_TOKEN = 7001, @@ -1593,8 +1594,9 @@ int shader_parse_input_signature(const struct vkd3d_shader_code *dxbc, struct vkd3d_shader_message_context *message_context, struct shader_signature *signature); int glsl_compile(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, - struct vkd3d_shader_message_context *message_context); + const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info, + const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); #define SPIRV_MAX_SRC_COUNT 6 -- 2.45.2