From d781aee2d58e59b61a34fefef0a4ce4b527a6c99 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Sat, 16 Sep 2023 07:19:25 +1000 Subject: [PATCH] Updated vkd3d to ee28861837c825818ace2e1e50825ade87a9c723. --- libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 2 +- libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 4 - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 3 +- libs/vkd3d/libs/vkd3d-shader/hlsl.h | 9 +- libs/vkd3d/libs/vkd3d-shader/hlsl.y | 56 +++++++++- libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 100 ++++++++++++++++++ libs/vkd3d/libs/vkd3d-shader/spirv.c | 10 +- libs/vkd3d/libs/vkd3d-shader/tpf.c | 25 +++++ .../libs/vkd3d-shader/vkd3d_shader_main.c | 3 +- 9 files changed, 197 insertions(+), 15 deletions(-) diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c index d72402eb250..f0c386f1b3a 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c @@ -714,7 +714,7 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler, break; case VKD3D_DECL_USAGE_TEXCOORD: - shader_addline(buffer, "texture%u", semantic->usage_idx); + shader_addline(buffer, "texcoord%u", semantic->usage_idx); break; case VKD3D_DECL_USAGE_TANGENT: diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c index 2b02d51f59a..d5104ae9b79 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -1982,10 +1982,6 @@ static void write_sm1_sampler_dcl(struct hlsl_ctx *ctx, struct vkd3d_bytecode_bu switch (sampler_dim) { - case HLSL_SAMPLER_DIM_1D: - res_type = VKD3D_SM1_RESOURCE_TEXTURE_1D; - break; - case HLSL_SAMPLER_DIM_2D: res_type = VKD3D_SM1_RESOURCE_TEXTURE_2D; break; diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c index b8cf6813f67..5fe9047bf25 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c @@ -2486,7 +2486,8 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) [HLSL_OP2_RSHIFT] = ">>", [HLSL_OP3_DP2ADD] = "dp2add", - [HLSL_OP3_LERP] = "lerp", + [HLSL_OP3_MOVC] = "movc", + [HLSL_OP3_TERNARY] = "ternary", }; return op_names[op]; diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h index 73b08ee3ea0..2cde5d58eba 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -550,8 +550,15 @@ enum hlsl_ir_expr_op HLSL_OP2_NEQUAL, HLSL_OP2_RSHIFT, + /* DP2ADD(a, b, c) computes the scalar product of a.xy and b.xy, + * then adds c. */ HLSL_OP3_DP2ADD, - HLSL_OP3_LERP, + /* MOVC(a, b, c) returns c if a is bitwise zero and b otherwise. + * TERNARY(a, b, c) returns c if a == 0 and b otherwise. + * They differ for floating point numbers, because + * -0.0 == 0.0, but it is not bitwise zero. */ + HLSL_OP3_MOVC, + HLSL_OP3_TERNARY, }; #define HLSL_MAX_OPERANDS 3 diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y index 161d1ab42c3..fb6d485ea69 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -2913,6 +2913,7 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *x, *y, *div, *abs, *frac, *neg_frac, *ge, *select, *zero; + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 }; static const struct hlsl_constant_value zero_value; if (!(x = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) @@ -2940,7 +2941,10 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer if (!(ge = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_GEQUAL, div, zero, loc))) return false; - if (!(select = hlsl_add_conditional(ctx, params->instrs, ge, frac, neg_frac))) + operands[0] = ge; + operands[1] = frac; + operands[2] = neg_frac; + if (!(select = add_expr(ctx, params->instrs, HLSL_OP3_TERNARY, operands, x->data_type, loc))) return false; return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, select, y, loc); @@ -3453,7 +3457,42 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1], hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, hlsl_sampler_dim_count(dim)), loc))) - coords = params->args[1]; + { + return false; + } + + /* tex1D() functions never produce 1D resource declarations. For newer profiles half offset + is used for the second coordinate, while older ones appear to replicate first coordinate.*/ + if (dim == HLSL_SAMPLER_DIM_1D) + { + struct hlsl_ir_load *load; + struct hlsl_ir_node *half; + struct hlsl_ir_var *var; + unsigned int idx = 0; + + if (!(var = hlsl_new_synthetic_var(ctx, "coords", hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 2), loc))) + return false; + + initialize_var_components(ctx, params->instrs, var, &idx, coords); + if (shader_profile_version_ge(ctx, 4, 0)) + { + if (!(half = hlsl_new_float_constant(ctx, 0.5f, loc))) + return false; + hlsl_block_add_instr(params->instrs, half); + + initialize_var_components(ctx, params->instrs, var, &idx, half); + } + else + initialize_var_components(ctx, params->instrs, var, &idx, coords); + + if (!(load = hlsl_new_var_load(ctx, var, loc))) + return false; + hlsl_block_add_instr(params->instrs, &load->node); + + coords = &load->node; + + dim = HLSL_SAMPLER_DIM_2D; + } load_params.coords = coords; load_params.resource = params->args[0]; @@ -3466,6 +3505,12 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * return true; } +static bool intrinsic_tex1D(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + return intrinsic_tex(ctx, params, loc, "tex1D", HLSL_SAMPLER_DIM_1D); +} + static bool intrinsic_tex2D(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -3652,6 +3697,7 @@ intrinsic_functions[] = {"smoothstep", 3, true, intrinsic_smoothstep}, {"sqrt", 1, true, intrinsic_sqrt}, {"step", 2, true, intrinsic_step}, + {"tex1D", -1, false, intrinsic_tex1D}, {"tex2D", -1, false, intrinsic_tex2D}, {"tex3D", -1, false, intrinsic_tex3D}, {"texCUBE", -1, false, intrinsic_texCUBE}, @@ -6555,6 +6601,7 @@ conditional_expr: struct hlsl_ir_node *cond = node_from_block($1); struct hlsl_ir_node *first = node_from_block($3); struct hlsl_ir_node *second = node_from_block($5); + struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = { 0 }; struct hlsl_type *common_type; hlsl_block_add_block($1, $3); @@ -6571,7 +6618,10 @@ conditional_expr: if (!(second = add_implicit_conversion(ctx, $1, second, common_type, &@5))) YYABORT; - if (!hlsl_add_conditional(ctx, $1, cond, first, second)) + args[0] = cond; + args[1] = first; + args[2] = second; + if (!add_expr(ctx, $1, HLSL_OP3_TERNARY, args, common_type, &@1)) YYABORT; $$ = $1; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c index 710d2908166..be024842164 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -934,6 +934,55 @@ static struct hlsl_ir_node *add_zero_mipmap_level(struct hlsl_ctx *ctx, struct h return &coords_load->node; } +/* hlsl_ir_swizzle nodes that directly point to a matrix value are only a parse-time construct that + * represents matrix swizzles (e.g. mat._m01_m23) before we know if they will be used in the lhs of + * an assignment or as a value made from different components of the matrix. The former cases should + * have already been split into several separate assignments, but the latter are lowered by this + * pass. */ +static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +{ + struct hlsl_ir_swizzle *swizzle; + struct hlsl_ir_load *var_load; + struct hlsl_deref var_deref; + struct hlsl_type *matrix_type; + struct hlsl_ir_var *var; + unsigned int x, y, k, i; + + if (instr->type != HLSL_IR_SWIZZLE) + return false; + swizzle = hlsl_ir_swizzle(instr); + matrix_type = swizzle->val.node->data_type; + if (matrix_type->class != HLSL_CLASS_MATRIX) + return false; + + if (!(var = hlsl_new_synthetic_var(ctx, "matrix-swizzle", instr->data_type, &instr->loc))) + return false; + hlsl_init_simple_deref_from_var(&var_deref, var); + + for (i = 0; i < instr->data_type->dimx; ++i) + { + struct hlsl_block store_block; + struct hlsl_ir_node *load; + + y = (swizzle->swizzle >> (8 * i + 4)) & 0xf; + x = (swizzle->swizzle >> 8 * i) & 0xf; + k = y * matrix_type->dimx + x; + + if (!(load = hlsl_add_load_component(ctx, block, swizzle->val.node, k, &instr->loc))) + return false; + + if (!hlsl_new_store_component(ctx, &store_block, &var_deref, i, load)) + return false; + hlsl_block_add_block(block, &store_block); + } + + if (!(var_load = hlsl_new_var_load(ctx, var, &instr->loc))) + return false; + hlsl_block_add_instr(block, &var_load->node); + + return true; +} + /* hlsl_ir_index nodes are a parse-time construct used to represent array indexing and struct * record access before knowing if they will be used in the lhs of an assignment --in which case * they are lowered into a deref-- or as the load of an element within a larger value. @@ -2391,6 +2440,54 @@ static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void * return true; } +/* Use 'movc' for the ternary operator. */ +static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], *replacement; + struct hlsl_ir_node *zero, *cond, *first, *second; + struct hlsl_constant_value zero_value = { 0 }; + struct hlsl_ir_expr *expr; + struct hlsl_type *type; + + if (instr->type != HLSL_IR_EXPR) + return false; + + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP3_TERNARY) + return false; + + cond = expr->operands[0].node; + first = expr->operands[1].node; + second = expr->operands[2].node; + + if (cond->data_type->base_type == HLSL_TYPE_FLOAT) + { + if (!(zero = hlsl_new_constant(ctx, cond->data_type, &zero_value, &instr->loc))) + return false; + list_add_tail(&instr->entry, &zero->entry); + + memset(operands, 0, sizeof(operands)); + operands[0] = zero; + operands[1] = cond; + type = cond->data_type; + type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->dimx, type->dimy); + if (!(cond = hlsl_new_expr(ctx, HLSL_OP2_NEQUAL, operands, type, &instr->loc))) + return false; + list_add_before(&instr->entry, &cond->entry); + } + + memset(operands, 0, sizeof(operands)); + operands[0] = cond; + operands[1] = first; + operands[2] = second; + if (!(replacement = hlsl_new_expr(ctx, HLSL_OP3_MOVC, operands, first->data_type, &instr->loc))) + return false; + list_add_before(&instr->entry, &replacement->entry); + + hlsl_replace_node(instr, replacement); + return true; +} + static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_type *type = instr->data_type, *arg_type; @@ -4247,6 +4344,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry while (hlsl_transform_ir(ctx, lower_calls, body, NULL)); + lower_ir(ctx, lower_matrix_swizzles, body); hlsl_transform_ir(ctx, lower_index_loads, body, NULL); LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) @@ -4349,6 +4447,8 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry hlsl_transform_ir(ctx, track_object_components_usage, body, NULL); sort_synthetic_separated_samplers_first(ctx); + if (profile->major_version >= 4) + hlsl_transform_ir(ctx, lower_ternary, body, NULL); if (profile->major_version < 4) { hlsl_transform_ir(ctx, lower_division, body, NULL); diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c index f93960d6d54..95f6914acb7 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c @@ -5564,7 +5564,7 @@ static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler * } static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, - const struct vkd3d_shader_register_range *range, unsigned int register_id, unsigned int size) + const struct vkd3d_shader_register_range *range, unsigned int register_id, unsigned int size_in_bytes) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t vec4_id, array_type_id, length_id, struct_id, var_id; @@ -5572,6 +5572,7 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, struct vkd3d_push_constant_buffer_binding *push_cb; struct vkd3d_descriptor_variable_info var_info; struct vkd3d_symbol reg_symbol; + unsigned int size; struct vkd3d_shader_register reg = { @@ -5580,18 +5581,19 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, .idx_count = 1, }; + size = size_in_bytes / (VKD3D_VEC4_SIZE * sizeof(uint32_t)); + if ((push_cb = spirv_compiler_find_push_constant_buffer(compiler, range))) { /* Push constant buffers are handled in * spirv_compiler_emit_push_constant_buffers(). */ - unsigned int cb_size_in_bytes = size * VKD3D_VEC4_SIZE * sizeof(uint32_t); push_cb->reg = reg; push_cb->size = size; - if (cb_size_in_bytes > push_cb->pc.size) + if (size_in_bytes > push_cb->pc.size) { WARN("Constant buffer size %u exceeds push constant size %u.\n", - cb_size_in_bytes, push_cb->pc.size); + size_in_bytes, push_cb->pc.size); } return; } diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c index 7949be150bf..045fb6c5f64 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -4341,6 +4341,26 @@ static void write_sm4_binary_op_with_two_destinations(const struct tpf_writer *t write_sm4_instruction(tpf, &instr); } +static void write_sm4_ternary_op(const struct tpf_writer *tpf, enum vkd3d_sm4_opcode opcode, + const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src1, const struct hlsl_ir_node *src2, + const struct hlsl_ir_node *src3) +{ + struct sm4_instruction instr; + + memset(&instr, 0, sizeof(instr)); + instr.opcode = opcode; + + sm4_dst_from_node(&instr.dsts[0], dst); + instr.dst_count = 1; + + sm4_src_from_node(&instr.srcs[0], src1, instr.dsts[0].writemask); + sm4_src_from_node(&instr.srcs[1], src2, instr.dsts[0].writemask); + sm4_src_from_node(&instr.srcs[2], src3, instr.dsts[0].writemask); + instr.src_count = 3; + + write_sm4_instruction(tpf, &instr); +} + static void write_sm4_ld(const struct tpf_writer *tpf, const struct hlsl_ir_node *dst, const struct hlsl_deref *resource, const struct hlsl_ir_node *coords, const struct hlsl_ir_node *sample_index, const struct hlsl_ir_node *texel_offset, @@ -4702,6 +4722,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex { const struct hlsl_ir_node *arg1 = expr->operands[0].node; const struct hlsl_ir_node *arg2 = expr->operands[1].node; + const struct hlsl_ir_node *arg3 = expr->operands[2].node; const struct hlsl_type *dst_type = expr->node.data_type; struct vkd3d_string_buffer *dst_type_string; @@ -5127,6 +5148,10 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex &expr->node, arg1, arg2); break; + case HLSL_OP3_MOVC: + write_sm4_ternary_op(tpf, VKD3D_SM4_OP_MOVC, &expr->node, arg1, arg2, arg3); + break; + default: hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 %s expression.", debug_hlsl_expr_op(expr->op)); } diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c index a70894a160d..9d8fa82fb86 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c @@ -705,7 +705,8 @@ static void vkd3d_shader_scan_add_uav_flag(const struct vkd3d_shader_scan_contex for (i = 0; i < context->scan_descriptor_info->descriptor_count; ++i) { - if (context->scan_descriptor_info->descriptors[i].register_id == range_id) + if (context->scan_descriptor_info->descriptors[i].type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV + && context->scan_descriptor_info->descriptors[i].register_id == range_id) { context->scan_descriptor_info->descriptors[i].flags |= flag; break; -- 2.40.1