diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index dd575a87dd2..a1be0e5011c 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -103,6 +103,8 @@ struct find_variable { /** * Visitor that determines whether or not a variable is ever written. + * Note: this is only considering if the variable is statically written + * (= regardless of the runtime flow of control) * * Use \ref find_assignments for convenience. */ @@ -622,6 +624,13 @@ analyze_clip_cull_usage(struct gl_shader_program *prog, struct gl_context *ctx, struct shader_info *info) { + if (ctx->Const.DoDCEBeforeClipCullAnalysis) { + /* Remove dead functions to avoid raising an error (eg: dead function + * writes to gl_ClipVertex, and main() writes to gl_ClipDistance). + */ + do_dead_functions(shader->ir); + } + info->clip_distance_array_size = 0; info->cull_distance_array_size = 0; diff --git a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h index d93856dd35d..5a15388291b 100644 --- a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h +++ b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h @@ -26,6 +26,7 @@ DRI_CONF_SECTION_DEBUG DRI_CONF_ALLOW_GLSL_RELAXED_ES(false) DRI_CONF_ALLOW_GLSL_BUILTIN_VARIABLE_REDECLARATION(false) DRI_CONF_ALLOW_GLSL_CROSS_STAGE_INTERPOLATION_MISMATCH(false) + DRI_CONF_DO_DCE_BEFORE_CLIP_CULL_ANALYSIS(false) DRI_CONF_ALLOW_HIGHER_COMPAT_VERSION(false) DRI_CONF_FORCE_GLSL_ABS_SQRT(false) DRI_CONF_GLSL_CORRECT_DERIVATIVES_AFTER_DISCARD(false) diff --git a/src/gallium/auxiliary/util/u_driconf.c b/src/gallium/auxiliary/util/u_driconf.c index 531a55c2753..78667b84a14 100644 --- a/src/gallium/auxiliary/util/u_driconf.c +++ b/src/gallium/auxiliary/util/u_driconf.c @@ -57,6 +57,7 @@ u_driconf_fill_st_options(struct st_config_options *options, query_bool_option(vs_position_always_precise); query_bool_option(force_glsl_abs_sqrt); query_bool_option(allow_glsl_cross_stage_interpolation_mismatch); + query_bool_option(do_dce_before_clip_cull_analysis); query_bool_option(allow_draw_out_of_order); query_bool_option(glthread_nop_check_framebuffer_status); query_bool_option(ignore_map_unsynchronized); diff --git a/src/gallium/include/frontend/api.h b/src/gallium/include/frontend/api.h index 6514d87d81a..cde853f3334 100644 --- a/src/gallium/include/frontend/api.h +++ b/src/gallium/include/frontend/api.h @@ -233,6 +233,7 @@ struct st_config_options bool vs_position_always_precise; bool force_glsl_abs_sqrt; bool allow_glsl_cross_stage_interpolation_mismatch; + bool do_dce_before_clip_cull_analysis; bool allow_draw_out_of_order; bool glthread_nop_check_framebuffer_status; bool ignore_map_unsynchronized; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index fb168ed770a..465f0d74977 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -3955,6 +3955,15 @@ struct gl_constants */ GLboolean AllowExtraPPTokens; + /** + * The spec forbids a shader to "statically write both gl_ClipVertex + * and gl_ClipDistance". + * This option adds a tolerance for shader that statically writes to + * both but at least one of the write can be removed by a dead code + * elimination pass. + */ + GLboolean DoDCEBeforeClipCullAnalysis; + /** * Force computing the absolute value for sqrt() and inversesqrt() to follow * D3D9 when apps rely on this behaviour. diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c index 5e731bec413..bd73d5a7aad 100644 --- a/src/mesa/state_tracker/st_extensions.c +++ b/src/mesa/state_tracker/st_extensions.c @@ -1201,6 +1201,8 @@ void st_init_extensions(struct pipe_screen *screen, consts->AllowGLSLCrossStageInterpolationMismatch = options->allow_glsl_cross_stage_interpolation_mismatch; + consts->DoDCEBeforeClipCullAnalysis = options->do_dce_before_clip_cull_analysis; + consts->GLSLIgnoreWriteToReadonlyVar = options->glsl_ignore_write_to_readonly_var; consts->PrimitiveRestartFixedIndex = diff --git a/src/util/driconf.h b/src/util/driconf.h index a2ed0f82d5b..ed464a6c789 100644 --- a/src/util/driconf.h +++ b/src/util/driconf.h @@ -212,6 +212,10 @@ DRI_CONF_OPT_B(allow_glsl_cross_stage_interpolation_mismatch, def, \ "Allow interpolation qualifier mismatch across shader stages") +#define DRI_CONF_DO_DCE_BEFORE_CLIP_CULL_ANALYSIS(def) \ + DRI_CONF_OPT_B(do_dce_before_clip_cull_analysis, def, \ + "Use dead code elimitation before checking for invalid Clip*/CullDistance variables usage.") + #define DRI_CONF_ALLOW_DRAW_OUT_OF_ORDER(def) \ DRI_CONF_OPT_B(allow_draw_out_of_order, def, \ "Allow out-of-order draw optimizations. Set when Z fighting doesn't have to be accurate.")