driconf/Intel: Add lower_depth_range_rate option workaround for Homerun Clash misrendering issue

Intel has different Z interpolation float point rounding
than other mesa gpus
For example gl_Position.z = 0.0 will be interpolated to
gl_FragCoord.z = 0.5 for all gpus

gl_FragCoord = -0.00000001 will be interpolated to
gl_FragCoord.z = 0.4999999702 for Intel
and rounded to gl_FragCoord.z = 0.5 for other gpus

Games with LEQUAL depth func will fail depth test on Intel
and will pass it on other gpus in such case

This workaround lowers translated depth range
and several gl_FragCoord.z coords with extra small difference
will be translated to the same UINT16\UINT24\UINT32
value of an integer depth buffer

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/7199

Signed-off-by: Illia Polishchuk <illia.a.polishchuk@globallogic.com>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18412>
This commit is contained in:
Illia Polishchuk
2022-09-13 12:22:33 +03:00
committed by Marge Bot
parent dedd8affd8
commit 74658b01d2
16 changed files with 59 additions and 0 deletions

View File

@@ -765,6 +765,8 @@ crocus_screen_create(int fd, const struct pipe_screen_config *config)
driQueryOptionb(config->options, "always_flush_cache");
screen->driconf.limit_trig_input_range =
driQueryOptionb(config->options, "limit_trig_input_range");
screen->driconf.lower_depth_range_rate =
driQueryOptionf(config->options, "lower_depth_range_rate");
screen->precompile = env_var_as_boolean("shader_precompile", true);

View File

@@ -199,6 +199,7 @@ struct crocus_screen {
bool disable_throttling;
bool always_flush_cache;
bool limit_trig_input_range;
float lower_depth_range_rate;
} driconf;
uint64_t aperture_bytes;

View File

@@ -3371,9 +3371,15 @@ crocus_set_viewport_states(struct pipe_context *ctx,
const struct pipe_viewport_state *states)
{
struct crocus_context *ice = (struct crocus_context *) ctx;
struct crocus_screen *screen = (struct crocus_screen *)ctx->screen;
memcpy(&ice->state.viewports[start_slot], states, sizeof(*states) * count);
/* Fix depth test misrenderings by lowering translated depth range */
if (screen->driconf.lower_depth_range_rate != 1.0f)
ice->state.viewports[start_slot].translate[2] *=
screen->driconf.lower_depth_range_rate;
ice->state.dirty |= CROCUS_DIRTY_SF_CL_VIEWPORT;
ice->state.dirty |= CROCUS_DIRTY_RASTER;
#if GFX_VER >= 6

View File

@@ -10,3 +10,7 @@ DRI_CONF_SECTION_END
DRI_CONF_SECTION_PERFORMANCE
DRI_CONF_OPT_E(bo_reuse, 1, 0, 1, "Buffer object reuse",)
DRI_CONF_SECTION_END
DRI_CONF_SECTION_QUALITY
DRI_CONF_PP_LOWER_DEPTH_RANGE_RATE()
DRI_CONF_SECTION_END

View File

@@ -12,3 +12,7 @@ DRI_CONF_SECTION_PERFORMANCE
DRI_CONF_ADAPTIVE_SYNC(true)
DRI_CONF_OPT_E(bo_reuse, 1, 0, 1, "Buffer object reuse",)
DRI_CONF_SECTION_END
DRI_CONF_SECTION_QUALITY
DRI_CONF_PP_LOWER_DEPTH_RANGE_RATE()
DRI_CONF_SECTION_END

View File

@@ -845,6 +845,8 @@ iris_screen_create(int fd, const struct pipe_screen_config *config)
driQueryOptionb(config->options, "sync_compile");
screen->driconf.limit_trig_input_range =
driQueryOptionb(config->options, "limit_trig_input_range");
screen->driconf.lower_depth_range_rate =
driQueryOptionf(config->options, "lower_depth_range_rate");
screen->precompile = env_var_as_boolean("shader_precompile", true);

View File

@@ -182,6 +182,7 @@ struct iris_screen {
bool always_flush_cache;
bool sync_compile;
bool limit_trig_input_range;
float lower_depth_range_rate;
} driconf;
/** Does the kernel support various features (KERNEL_HAS_* bitfield)? */

View File

@@ -3200,9 +3200,15 @@ iris_set_viewport_states(struct pipe_context *ctx,
const struct pipe_viewport_state *states)
{
struct iris_context *ice = (struct iris_context *) ctx;
struct iris_screen *screen = (struct iris_screen *)ctx->screen;
memcpy(&ice->state.viewports[start_slot], states, sizeof(*states) * count);
/* Fix depth test misrenderings by lowering translated depth range */
if (screen->driconf.lower_depth_range_rate != 1.0f)
ice->state.viewports[start_slot].translate[2] *=
screen->driconf.lower_depth_range_rate;
ice->state.dirty |= IRIS_DIRTY_SF_CL_VIEWPORT;
if (ice->state.cso_rast && (!ice->state.cso_rast->depth_clip_near ||

View File

@@ -77,6 +77,10 @@ static const driOptionDescription anv_dri_options[] = {
DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST(false)
DRI_CONF_LIMIT_TRIG_INPUT_RANGE(false)
DRI_CONF_SECTION_END
DRI_CONF_SECTION_QUALITY
DRI_CONF_PP_LOWER_DEPTH_RANGE_RATE()
DRI_CONF_SECTION_END
};
/* This is probably far to big but it reflects the max size used for messages
@@ -1058,6 +1062,8 @@ anv_init_dri_options(struct anv_instance *instance)
driQueryOptionb(&instance->dri_options, "limit_trig_input_range");
instance->sample_mask_out_opengl_behaviour =
driQueryOptionb(&instance->dri_options, "anv_sample_mask_out_opengl_behaviour");
instance->lower_depth_range_rate =
driQueryOptionf(&instance->dri_options, "lower_depth_range_rate");
}
VkResult anv_CreateInstance(

View File

@@ -997,6 +997,7 @@ struct anv_instance {
bool assume_full_subgroups;
bool limit_trig_input_range;
bool sample_mask_out_opengl_behaviour;
float lower_depth_range_rate;
};
VkResult anv_init_wsi(struct anv_physical_device *physical_device);

View File

@@ -3150,6 +3150,7 @@ cmd_buffer_emit_clip(struct anv_cmd_buffer *cmd_buffer)
static void
cmd_buffer_emit_viewport(struct anv_cmd_buffer *cmd_buffer)
{
struct anv_instance *instance = cmd_buffer->device->physical->instance;
struct anv_cmd_graphics_state *gfx = &cmd_buffer->state.gfx;
const struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
@@ -3186,6 +3187,10 @@ cmd_buffer_emit_viewport(struct anv_cmd_buffer *cmd_buffer)
.YMaxViewPort = MAX2(vp->y, vp->y + vp->height) - 1,
};
/* Fix depth test misrenderings by lowering translated depth range */
if (instance->lower_depth_range_rate != 1.0f)
sfv.ViewportMatrixElementm32 *= instance->lower_depth_range_rate;
const uint32_t fb_size_max = 1 << 14;
uint32_t x_min = 0, x_max = fb_size_max;
uint32_t y_min = 0, y_max = fb_size_max;

View File

@@ -77,6 +77,10 @@ static const driOptionDescription anv_dri_options[] = {
DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST(false)
DRI_CONF_LIMIT_TRIG_INPUT_RANGE(false)
DRI_CONF_SECTION_END
DRI_CONF_SECTION_QUALITY
DRI_CONF_PP_LOWER_DEPTH_RANGE_RATE()
DRI_CONF_SECTION_END
};
/* This is probably far to big but it reflects the max size used for messages
@@ -1102,6 +1106,8 @@ anv_init_dri_options(struct anv_instance *instance)
driQueryOptionb(&instance->dri_options, "limit_trig_input_range");
instance->sample_mask_out_opengl_behaviour =
driQueryOptionb(&instance->dri_options, "anv_sample_mask_out_opengl_behaviour");
instance->lower_depth_range_rate =
driQueryOptionf(&instance->dri_options, "lower_depth_range_rate");
}
VkResult anv_CreateInstance(

View File

@@ -1085,6 +1085,7 @@ struct anv_instance {
bool assume_full_subgroups;
bool limit_trig_input_range;
bool sample_mask_out_opengl_behaviour;
float lower_depth_range_rate;
};
VkResult anv_init_wsi(struct anv_physical_device *physical_device);

View File

@@ -3455,6 +3455,7 @@ cmd_buffer_emit_clip(struct anv_cmd_buffer *cmd_buffer)
static void
cmd_buffer_emit_viewport(struct anv_cmd_buffer *cmd_buffer)
{
struct anv_instance *instance = cmd_buffer->device->physical->instance;
struct anv_cmd_graphics_state *gfx = &cmd_buffer->state.gfx;
const struct vk_dynamic_graphics_state *dyn =
&cmd_buffer->vk.dynamic_graphics_state;
@@ -3493,6 +3494,10 @@ cmd_buffer_emit_viewport(struct anv_cmd_buffer *cmd_buffer)
#endif
};
/* Fix depth test misrenderings by lowering translated depth range */
if (instance->lower_depth_range_rate != 1.0f)
sfv.ViewportMatrixElementm32 *= instance->lower_depth_range_rate;
const uint32_t fb_size_max = 1 << 14;
uint32_t x_min = 0, x_max = fb_size_max;
uint32_t y_min = 0, y_max = fb_size_max;

View File

@@ -322,6 +322,11 @@ TODO: document the other workarounds.
<option name="vs_position_always_invariant" value="true" />
</application>
<application name="Homerun Clash" executable="com.haegin.homerunclash">
<!-- https://gitlab.freedesktop.org/mesa/mesa/-/issues/7199 -->
<option name="lower_depth_range_rate" value="0.8" />
</application>
<!-- Workarounds for SPECviewperf relying on invalid / non-conformant
OpenGL behavior. Older SPECviewperf versions might also need this.
-->

View File

@@ -335,6 +335,10 @@
DRI_CONF_OPT_I(pp_jimenezmlaa_color, def, min, max, \
"Morphological anti-aliasing based on Jimenez' MLAA. 0 to disable, 8 for default quality. Color version, usable with 2d GL apps")
#define DRI_CONF_PP_LOWER_DEPTH_RANGE_RATE() \
DRI_CONF_OPT_F(lower_depth_range_rate, 1.0, 0.0, 1.0, \
"Lower depth range for fixing misrendering issues due to z coordinate float point interpolation accuracy")
/**
* \brief Performance-related options
*/