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); }