From 6b6e4bc212326986801a45c5fd6cb41bf0f1bb82 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Tue, 19 Mar 2024 23:06:07 -0500 Subject: [PATCH] vkd3d-shader: Add a compile option to control whether implicit truncation warnings are printed. d3dcompiler and d3dx9 versions before 42 don't emit this error; this will be necessary to emulate that behaviour. Other warnings exist that are introduced in different d3dcompiler versions, although there are not very many distinct HLSL warnings to begin with. We could of course group all these together under a single compiler option, but I find that using separate top-level options is unilaterally friendlier to an API consumer, and simpler to implement as well. It also in some sense maps conceptually to e.g. "-Wno-implicit-conversion". --- include/vkd3d_shader.h | 11 +++++++++ libs/vkd3d-shader/hlsl.c | 37 ++++++++++++++++++---------- libs/vkd3d-shader/hlsl.h | 1 + libs/vkd3d-shader/hlsl.y | 2 +- tests/vkd3d_shader_api.c | 52 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 89 insertions(+), 14 deletions(-) diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 0cd2a861..0ce2ef67 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -310,6 +310,17 @@ enum vkd3d_shader_compile_option_name * \since 1.12 */ VKD3D_SHADER_COMPILE_OPTION_CHILD_EFFECT = 0x0000000b, + /** + * If \a value is nonzero, emit a compile warning warn when vectors or + * matrices are truncated in an implicit conversion. + * If warnings are disabled, this option has no effect. + * This option has no effects for targets other than HLSL. + * + * The default value is nonzero, i.e. enable implicit truncation warnings. + * + * \since 1.12 + */ + VKD3D_SHADER_COMPILE_OPTION_WARN_IMPLICIT_TRUNCATION = 0x0000000c, VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME), }; diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 147b86f5..cba954c9 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -3593,24 +3593,35 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil return false; ctx->cur_buffer = ctx->globals_buffer; + ctx->warn_implicit_truncation = true; + for (i = 0; i < compile_info->option_count; ++i) { const struct vkd3d_shader_compile_option *option = &compile_info->options[i]; - if (option->name == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER) + switch (option->name) { - if (option->value == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ROW_MAJOR) - ctx->matrix_majority = HLSL_MODIFIER_ROW_MAJOR; - else if (option->value == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR) - ctx->matrix_majority = HLSL_MODIFIER_COLUMN_MAJOR; - } - else if (option->name == VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY) - { - ctx->semantic_compat_mapping = option->value & VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES; - } - else if (option->name == VKD3D_SHADER_COMPILE_OPTION_CHILD_EFFECT) - { - ctx->child_effect = !!option->value; + case VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER: + if (option->value == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ROW_MAJOR) + ctx->matrix_majority = HLSL_MODIFIER_ROW_MAJOR; + else if (option->value == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR) + ctx->matrix_majority = HLSL_MODIFIER_COLUMN_MAJOR; + break; + + case VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY: + ctx->semantic_compat_mapping = option->value & VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES; + break; + + case VKD3D_SHADER_COMPILE_OPTION_CHILD_EFFECT: + ctx->child_effect = option->value; + break; + + case VKD3D_SHADER_COMPILE_OPTION_WARN_IMPLICIT_TRUNCATION: + ctx->warn_implicit_truncation = option->value; + break; + + default: + break; } } diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 93ec67d0..64111f3f 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -925,6 +925,7 @@ struct hlsl_ctx bool semantic_compat_mapping; bool child_effect; + bool warn_implicit_truncation; }; struct hlsl_resource_load_params diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index 2824e26d..52c21765 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -413,7 +413,7 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct return NULL; } - if (dst_type->dimx * dst_type->dimy < src_type->dimx * src_type->dimy) + if (dst_type->dimx * dst_type->dimy < src_type->dimx * src_type->dimy && ctx->warn_implicit_truncation) hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.", src_type->class == HLSL_CLASS_VECTOR ? "vector" : "matrix"); diff --git a/tests/vkd3d_shader_api.c b/tests/vkd3d_shader_api.c index 1dc1a313..d3aa2e52 100644 --- a/tests/vkd3d_shader_api.c +++ b/tests/vkd3d_shader_api.c @@ -1642,6 +1642,57 @@ static void test_emit_signature(void) } } +static void test_warning_options(void) +{ + struct vkd3d_shader_hlsl_source_info hlsl_info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_HLSL_SOURCE_INFO}; + struct vkd3d_shader_compile_info info = {.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO}; + struct vkd3d_shader_compile_option options[1]; + struct vkd3d_shader_code d3dbc; + char *messages; + int rc; + + static const char ps_source[] = + "float4 main(uniform float4 u) : color\n" + "{\n" + " float3 x = u;\n" + " return 0;\n" + "}\n"; + + hlsl_info.profile = "ps_2_0"; + + info.next = &hlsl_info; + info.source.code = ps_source; + info.source.size = ARRAY_SIZE(ps_source); + info.source_type = VKD3D_SHADER_SOURCE_HLSL; + info.target_type = VKD3D_SHADER_TARGET_D3D_BYTECODE; + info.log_level = VKD3D_SHADER_LOG_INFO; + + rc = vkd3d_shader_compile(&info, &d3dbc, &messages); + ok(rc == VKD3D_OK, "Got rc %d.\n", rc); + ok(messages, "Expected messages.\n"); + vkd3d_shader_free_shader_code(&d3dbc); + vkd3d_shader_free_messages(messages); + + info.options = options; + info.option_count = ARRAY_SIZE(options); + options[0].name = VKD3D_SHADER_COMPILE_OPTION_WARN_IMPLICIT_TRUNCATION; + options[0].value = 0; + + rc = vkd3d_shader_compile(&info, &d3dbc, &messages); + ok(rc == VKD3D_OK, "Got rc %d.\n", rc); + ok(!messages, "Expected no messages.\n"); + vkd3d_shader_free_shader_code(&d3dbc); + vkd3d_shader_free_messages(messages); + + options[0].value = 1; + + rc = vkd3d_shader_compile(&info, &d3dbc, &messages); + ok(rc == VKD3D_OK, "Got rc %d.\n", rc); + ok(messages, "Expected messages.\n"); + vkd3d_shader_free_shader_code(&d3dbc); + vkd3d_shader_free_messages(messages); +} + START_TEST(vkd3d_shader_api) { setlocale(LC_ALL, ""); @@ -1656,4 +1707,5 @@ START_TEST(vkd3d_shader_api) run_test(test_build_varying_map); run_test(test_scan_combined_resource_samplers); run_test(test_emit_signature); + run_test(test_warning_options); }