diff --git a/gitlab/build.yml b/gitlab/build.yml index 0eac7722..7cc88f1f 100644 --- a/gitlab/build.yml +++ b/gitlab/build.yml @@ -30,12 +30,14 @@ build-radv-64: - amd-gpu variables: VK_LOADER_DRIVERS_SELECT: 'radeon_*' + VKD3D_SHADER_CONFIG: 'force_validation' build-llvmpipe-64: extends: .build-linux allow_failure: true variables: VK_LOADER_DRIVERS_SELECT: 'lvp_*' + VKD3D_SHADER_CONFIG: 'force_validation' build-radv-32: extends: .build-linux @@ -44,6 +46,7 @@ build-radv-32: variables: VK_LOADER_DRIVERS_SELECT: 'radeon_*' CC: 'gcc -m32' + VKD3D_SHADER_CONFIG: 'force_validation' build-llvmpipe-32: extends: .build-linux @@ -51,6 +54,7 @@ build-llvmpipe-32: variables: VK_LOADER_DRIVERS_SELECT: 'lvp_*' CC: 'gcc -m32' + VKD3D_SHADER_CONFIG: 'force_validation' build-mac: stage: build @@ -87,6 +91,7 @@ build-mac: - if [ -f pipeline_failed ] ; then exit 1 ; fi variables: VKD3D_DISABLE_EXTENSIONS: "VK_EXT_descriptor_indexing" + VKD3D_SHADER_CONFIG: 'force_validation' artifacts: when: always paths: diff --git a/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d-shader/d3dbc.c index ee3c6906..0d2b8d24 100644 --- a/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d-shader/d3dbc.c @@ -1344,6 +1344,9 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi for (i = 0; i < ARRAY_SIZE(sm1->p.shader_desc.flat_constant_count); ++i) sm1->p.shader_desc.flat_constant_count[i].external = get_external_constant_count(sm1, i); + if (!sm1->p.failed) + vsir_validate(&sm1->p); + if (sm1->p.failed) { WARN("Failed to parse shader.\n"); diff --git a/libs/vkd3d-shader/dxil.c b/libs/vkd3d-shader/dxil.c index ded5a82f..b778f6ab 100644 --- a/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d-shader/dxil.c @@ -2955,6 +2955,9 @@ int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compi compile_info->source_name, message_context); vkd3d_free(byte_code); + if (!sm6->p.failed && ret >= 0) + vsir_validate(&sm6->p); + if (sm6->p.failed && ret >= 0) ret = VKD3D_ERROR_INVALID_SHADER; diff --git a/libs/vkd3d-shader/ir.c b/libs/vkd3d-shader/ir.c index f3b51e8c..7ee191b3 100644 --- a/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d-shader/ir.c @@ -1290,5 +1290,22 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, if (result >= 0 && TRACE_ON()) vkd3d_shader_trace(instructions, &parser->shader_version); + if (result >= 0 && !parser->failed) + vsir_validate(parser); + + if (result >= 0 && parser->failed) + result = VKD3D_ERROR_INVALID_SHADER; + return result; } + +struct validation_context +{ + struct vkd3d_shader_parser *parser; +}; + +void vsir_validate(struct vkd3d_shader_parser *parser) +{ + if (!(parser->config_flags & VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION)) + return; +} diff --git a/libs/vkd3d-shader/tpf.c b/libs/vkd3d-shader/tpf.c index ff5befaf..58b7f030 100644 --- a/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d-shader/tpf.c @@ -2642,6 +2642,9 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi if (sm4->p.shader_version.type == VKD3D_SHADER_TYPE_HULL && !sm4->has_control_point_phase && !sm4->p.failed) shader_sm4_validate_default_phase_index_ranges(sm4); + if (!sm4->p.failed) + vsir_validate(&sm4->p); + if (sm4->p.failed) { WARN("Failed to parse shader.\n"); diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c index 9ccb917c..5645dca3 100644 --- a/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d-shader/vkd3d_shader_main.c @@ -454,6 +454,25 @@ static void init_scan_signature_info(const struct vkd3d_shader_compile_info *inf } } +static const struct vkd3d_debug_option vkd3d_shader_config_options[] = +{ + {"force_validation", VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION}, /* force validation of internal shader representations */ +}; + +static uint64_t vkd3d_shader_init_config_flags(void) +{ + uint64_t config_flags; + const char *config; + + config = getenv("VKD3D_SHADER_CONFIG"); + config_flags = vkd3d_parse_debug_options(config, vkd3d_shader_config_options, ARRAY_SIZE(vkd3d_shader_config_options)); + + if (config_flags) + TRACE("VKD3D_SHADER_CONFIG='%s'.\n", config); + + return config_flags; +} + bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vkd3d_shader_message_context *message_context, const char *source_name, const struct vkd3d_shader_version *version, const struct vkd3d_shader_parser_ops *ops, @@ -465,6 +484,7 @@ bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, parser->location.column = 0; parser->shader_version = *version; parser->ops = ops; + parser->config_flags = vkd3d_shader_init_config_flags(); return shader_instruction_array_init(&parser->instructions, instruction_reserve); } diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h index 70055614..c847d73b 100644 --- a/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d-shader/vkd3d_shader_private.h @@ -1095,6 +1095,11 @@ bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_ unsigned int dst, unsigned int src); void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions); +enum vkd3d_shader_config_flags +{ + VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION = 0x00000001, +}; + struct vkd3d_shader_parser { struct vkd3d_shader_message_context *message_context; @@ -1105,6 +1110,8 @@ struct vkd3d_shader_parser struct vkd3d_shader_version shader_version; const struct vkd3d_shader_parser_ops *ops; struct vkd3d_shader_instruction_array instructions; + + uint64_t config_flags; }; struct vkd3d_shader_parser_ops @@ -1293,6 +1300,8 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); +void vsir_validate(struct vkd3d_shader_parser *parser); + static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( enum vkd3d_data_type data_type) {