diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 46feff35..115bb21b 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -190,6 +190,17 @@ enum vkd3d_shader_compile_option_backward_compatibility * - DEPTH to SV_Depth for pixel shader outputs. */ VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES = 0x00000001, + /** + * Causes 'double' to behave as an alias for 'float'. This option only + * applies to HLSL sources with shader model 1-3 target profiles. Without + * this option using the 'double' type produces compilation errors in + * these target profiles. + * + * This option is disabled by default. + * + * \since 1.14 + */ + VKD3D_SHADER_COMPILE_OPTION_DOUBLE_AS_FLOAT_ALIAS = 0x00000002, VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY), }; diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index 10f2e5e5..693d86d3 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -1835,8 +1835,10 @@ void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buff switch (comp_type->e.numeric.type) { case HLSL_TYPE_DOUBLE: - hlsl_fixme(ctx, &var->loc, "Write double default values."); - uni.u = 0; + if (ctx->double_as_float_alias) + uni.u = var->default_values[k].number.u; + else + uni.u = 0; break; case HLSL_TYPE_INT: diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 32dd9686..1bdca895 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -4248,6 +4248,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil case VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY: ctx->semantic_compat_mapping = option->value & VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES; + ctx->double_as_float_alias = option->value & VKD3D_SHADER_COMPILE_OPTION_DOUBLE_AS_FLOAT_ALIAS; break; case VKD3D_SHADER_COMPILE_OPTION_CHILD_EFFECT: diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 6782fa4c..c03b1f9e 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -1091,6 +1091,7 @@ struct hlsl_ctx bool child_effect; bool include_empty_buffers; bool warn_implicit_truncation; + bool double_as_float_alias; }; static inline bool hlsl_version_ge(const struct hlsl_ctx *ctx, unsigned int major, unsigned int minor) diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 6cae0e3b..4d44fc5e 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -6622,7 +6622,13 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, return true; case HLSL_TYPE_DOUBLE: - hlsl_fixme(ctx, &instr->loc, "SM1 cast from double to float."); + if (ctx->double_as_float_alias) + { + sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); + return true; + } + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "The 'double' type is not supported for the %s profile.", ctx->profile->name); break; default: @@ -6660,7 +6666,22 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, break; case HLSL_TYPE_DOUBLE: - hlsl_fixme(ctx, &instr->loc, "SM1 cast to double."); + switch (src_type->e.numeric.type) + { + case HLSL_TYPE_FLOAT: + if (ctx->double_as_float_alias) + { + sm1_generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); + return true; + } + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "The 'double' type is not supported for the %s profile.", ctx->profile->name); + break; + + default: + hlsl_fixme(ctx, &instr->loc, "SM1 cast to double."); + break; + } break; case HLSL_TYPE_BOOL: diff --git a/programs/vkd3d-compiler/main.c b/programs/vkd3d-compiler/main.c index 76ee61f0..8a07e2e2 100644 --- a/programs/vkd3d-compiler/main.c +++ b/programs/vkd3d-compiler/main.c @@ -38,6 +38,7 @@ enum { OPTION_HELP = CHAR_MAX + 1, + OPTION_ALIAS_DOUBLE_AS_FLOAT, OPTION_BUFFER_UAV, OPTION_CHILD_EFFECT, OPTION_ENTRY, @@ -185,6 +186,9 @@ static void print_usage(const char *program_name) "[options...] [file]\n" "Options:\n" " -h, --help Display this information and exit.\n" + " --alias-double-as-float\n" + " Treat 'double' as 'float' when compiling HLSL sources\n" + " with shader model 1-3 target profiles.\n" " -b Specify the target type. Use --print-target-types to\n" " list the valid and default target types for a given\n" " source type.\n" @@ -488,6 +492,7 @@ static bool parse_command_line(int argc, char **argv, struct options *options) static struct option long_options[] = { {"help", no_argument, NULL, OPTION_HELP}, + {"alias-double-as-float", no_argument, NULL, OPTION_ALIAS_DOUBLE_AS_FLOAT}, {"buffer-uav", required_argument, NULL, OPTION_BUFFER_UAV}, {"child-effect", no_argument, NULL, OPTION_CHILD_EFFECT}, {"entry", required_argument, NULL, OPTION_ENTRY}, @@ -602,6 +607,10 @@ static bool parse_command_line(int argc, char **argv, struct options *options) compat_options |= VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES; break; + case OPTION_ALIAS_DOUBLE_AS_FLOAT: + compat_options |= VKD3D_SHADER_COMPILE_OPTION_DOUBLE_AS_FLOAT_ALIAS; + break; + case OPTION_STRIP_DEBUG: add_compile_option(options, VKD3D_SHADER_COMPILE_OPTION_STRIP_DEBUG, 1); break;