From 094e298c1c8cf5d6ee3ba990c9f729a0ca2fdda7 Mon Sep 17 00:00:00 2001 From: Francisco Casas Date: Fri, 14 Jun 2024 19:59:21 -0400 Subject: [PATCH] vkd3d-shader/hlsl: Parse string default values. --- libs/vkd3d-shader/d3dbc.c | 6 ++--- libs/vkd3d-shader/fx.c | 2 +- libs/vkd3d-shader/hlsl.c | 19 +++++++++++++--- libs/vkd3d-shader/hlsl.h | 4 +++- libs/vkd3d-shader/hlsl.y | 41 +++++++++++++++++++++------------- libs/vkd3d-shader/tpf.c | 2 +- tests/hlsl/strings.shader_test | 8 +++---- 7 files changed, 54 insertions(+), 28 deletions(-) diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index 10c8a986..d05394c3 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -1830,17 +1830,17 @@ void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buff break; case HLSL_TYPE_INT: - uni.f = var->default_values[k].value.i; + uni.f = var->default_values[k].number.i; break; case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: - uni.f = var->default_values[k].value.u; + uni.f = var->default_values[k].number.u; break; case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: - uni.u = var->default_values[k].value.u; + uni.u = var->default_values[k].number.u; break; default: diff --git a/libs/vkd3d-shader/fx.c b/libs/vkd3d-shader/fx.c index ebd42390..473c82af 100644 --- a/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d-shader/fx.c @@ -1243,7 +1243,7 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl for (j = 0; j < comp_count; ++j) { - put_u32_unaligned(buffer, value->value.u); + put_u32_unaligned(buffer, value->number.u); value++; } break; diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 56f6f4c5..90dfb5f1 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -167,7 +167,14 @@ void hlsl_free_var(struct hlsl_ir_var *decl) for (k = 0; k <= HLSL_REGSET_LAST_OBJECT; ++k) vkd3d_free((void *)decl->objects_usage[k]); - vkd3d_free(decl->default_values); + if (decl->default_values) + { + unsigned int component_count = hlsl_type_component_count(decl->data_type); + + for (k = 0; k < component_count; ++k) + vkd3d_free((void *)decl->default_values[k].string); + vkd3d_free(decl->default_values); + } for (i = 0; i < decl->state_block_count; ++i) hlsl_free_state_block(decl->state_blocks[i]); @@ -3280,9 +3287,15 @@ void hlsl_dump_var_default_values(const struct hlsl_ir_var *var) vkd3d_string_buffer_printf(&buffer, "var \"%s\" default values:", var->name); for (k = 0; k < component_count; ++k) { - if (k % 4 == 0) + bool is_string = var->default_values[k].string; + + if (k % 4 == 0 || is_string) vkd3d_string_buffer_printf(&buffer, "\n "); - vkd3d_string_buffer_printf(&buffer, " 0x%08x", var->default_values[k].value.u); + + if (is_string) + vkd3d_string_buffer_printf(&buffer, " %s", debugstr_a(var->default_values[k].string)); + else + vkd3d_string_buffer_printf(&buffer, " 0x%08x", var->default_values[k].number.u); } vkd3d_string_buffer_printf(&buffer, "\n"); diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index fe7089ee..37a46bb7 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -456,8 +456,10 @@ struct hlsl_ir_var * This pointer is NULL for others. */ struct hlsl_default_value { + /* Default value, in case the component is a string, othewise it is NULL. */ + const char *string; /* Default value, in case the component is a numeric value. */ - union hlsl_constant_value_component value; + union hlsl_constant_value_component number; } *default_values; /* A dynamic array containing the state block on the variable's declaration, if any. diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 9c4719f4..3273d73b 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -598,11 +598,10 @@ static void check_loop_attributes(struct hlsl_ctx *ctx, const struct parse_attri hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Unroll attribute can't be used with 'fastopt' attribute."); } -static union hlsl_constant_value_component evaluate_static_expression(struct hlsl_ctx *ctx, +static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) { - union hlsl_constant_value_component ret = {0}; - struct hlsl_ir_constant *constant; + struct hlsl_default_value ret = {0}; struct hlsl_ir_node *node; struct hlsl_block expr; struct hlsl_src src; @@ -654,8 +653,16 @@ static union hlsl_constant_value_component evaluate_static_expression(struct hls if (node->type == HLSL_IR_CONSTANT) { - constant = hlsl_ir_constant(node); - ret = constant->value.u[0]; + struct hlsl_ir_constant *constant = hlsl_ir_constant(node); + + ret.number = constant->value.u[0]; + } + else if (node->type == HLSL_IR_STRING_CONSTANT) + { + struct hlsl_ir_string_constant *string = hlsl_ir_string_constant(node); + + if (!(ret.string = vkd3d_strdup(string->string))) + return ret; } else if (node->type == HLSL_IR_STRING_CONSTANT) { @@ -675,10 +682,11 @@ static union hlsl_constant_value_component evaluate_static_expression(struct hls static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct vkd3d_shader_location *loc) { - union hlsl_constant_value_component res; + struct hlsl_default_value res; res = evaluate_static_expression(ctx, block, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); - return res.u; + VKD3D_ASSERT(!res.string); + return res.number.u; } static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type, @@ -2373,7 +2381,7 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i if (!hlsl_clone_block(ctx, &block, instrs)) return; - default_value.value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc); + default_value = evaluate_static_expression(ctx, &block, dst_comp_type, &src->loc); if (dst->is_param) dst_index = *store_index; @@ -2931,14 +2939,17 @@ static bool add_user_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fu struct hlsl_ir_node *comp; struct hlsl_block store_block; - value.u[0] = param->default_values[j].value; - if (!(comp = hlsl_new_constant(ctx, type, &value, loc))) - return false; - hlsl_block_add_instr(args->instrs, comp); + if (!param->default_values[j].string) + { + value.u[0] = param->default_values[j].number; + if (!(comp = hlsl_new_constant(ctx, type, &value, loc))) + return false; + hlsl_block_add_instr(args->instrs, comp); - if (!hlsl_new_store_component(ctx, &store_block, ¶m_deref, j, comp)) - return false; - hlsl_block_add_block(args->instrs, &store_block); + if (!hlsl_new_store_component(ctx, &store_block, ¶m_deref, j, comp)) + return false; + hlsl_block_add_block(args->instrs, &store_block); + } } } diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index f35136ac..39b4f795 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -3607,7 +3607,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) hlsl_fixme(ctx, &var->loc, "Write double default values."); set_u32(&buffer, default_value_offset + comp_offset * sizeof(uint32_t), - var->default_values[k].value.u); + var->default_values[k].number.u); } } } diff --git a/tests/hlsl/strings.shader_test b/tests/hlsl/strings.shader_test index 1ada01e3..a85365ff 100644 --- a/tests/hlsl/strings.shader_test +++ b/tests/hlsl/strings.shader_test @@ -63,7 +63,7 @@ float4 main() : sv_target return apple.a; } -[pixel shader fail todo] +[pixel shader fail] struct apple { float a; @@ -75,13 +75,13 @@ float4 main(struct apple ap = {1, "foobar"}) : sv_target return ap.a; } -[pixel shader fail todo] +[pixel shader fail] float4 main(string s = "foobar") : sv_target { return 0; } -[pixel shader fail(sm>=6) todo] +[pixel shader fail(sm>=6)] string strs[2] = {"foo", "bar"}; float4 main() : sv_target { return 0; } @@ -95,7 +95,7 @@ float4 main() : sv_target { return 0; } % Escape sequences are hanlded differently in DXC. % Octal, hexadecimal, and unicode escape sequences that are out of range are considered errors. -[pixel shader todo fail(sm>=6)] +[pixel shader fail(sm>=6)] string a = "\nAAA\tBBB\rCCC\fDDD\vEEE\sFFF"; string b = "\\AAA\"BBB\'CCC\?DDD\aEEE\bFFF\sGGG"; string c = "\52 AAA\052 BBB\0521 CCC\52a DDD\241 EEE\441 FFF\02 GGG\0 HHH";