diff --git a/src/freedreno/vulkan/tu_device.c b/src/freedreno/vulkan/tu_device.c index abe8515dfa8..9627e41b69d 100644 --- a/src/freedreno/vulkan/tu_device.c +++ b/src/freedreno/vulkan/tu_device.c @@ -436,6 +436,10 @@ static const driOptionDescription tu_dri_options[] = { DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST(false) DRI_CONF_VK_DONT_CARE_AS_LOAD(false) DRI_CONF_SECTION_END + + DRI_CONF_SECTION_MISCELLANEOUS + DRI_CONF_DISABLE_CONSERVATIVE_LRZ(false) + DRI_CONF_SECTION_END }; static void @@ -449,6 +453,9 @@ tu_init_dri_options(struct tu_instance *instance) if (driQueryOptionb(&instance->dri_options, "vk_dont_care_as_load")) instance->debug_flags |= TU_DEBUG_DONT_CARE_AS_LOAD; + + instance->conservative_lrz = + !driQueryOptionb(&instance->dri_options, "disable_conservative_lrz"); } VKAPI_ATTR VkResult VKAPI_CALL diff --git a/src/freedreno/vulkan/tu_device.h b/src/freedreno/vulkan/tu_device.h index f7dab0d29e4..51c7dfe9661 100644 --- a/src/freedreno/vulkan/tu_device.h +++ b/src/freedreno/vulkan/tu_device.h @@ -149,6 +149,14 @@ struct tu_instance struct driOptionCache available_dri_options; enum tu_debug_flags debug_flags; + + /* Conservative LRZ (default true) invalidates LRZ on draws with + * blend and depth-write enabled, because this can lead to incorrect + * rendering. Driconf can be used to disable conservative LRZ for + * games which do not have the problematic sequence of draws *and* + * suffer a performance loss with conservative LRZ. + */ + bool conservative_lrz; }; VK_DEFINE_HANDLE_CASTS(tu_instance, vk.base, VkInstance, VK_OBJECT_TYPE_INSTANCE) diff --git a/src/freedreno/vulkan/tu_lrz.c b/src/freedreno/vulkan/tu_lrz.c index 138b483368e..1553d7ec63f 100644 --- a/src/freedreno/vulkan/tu_lrz.c +++ b/src/freedreno/vulkan/tu_lrz.c @@ -812,7 +812,7 @@ tu6_calculate_lrz_state(struct tu_cmd_buffer *cmd, * enable LRZ write. But this would cause early-z/lrz to discard * fragments from draw A which should be visible due to draw B. */ - if (reads_dest && z_write_enable) { + if (reads_dest && z_write_enable && cmd->device->instance->conservative_lrz) { perf_debug(cmd->device, "Invalidating LRZ due to blend+depthwrite"); disable_lrz = true; } diff --git a/src/gallium/auxiliary/target-helpers/drm_helper.h b/src/gallium/auxiliary/target-helpers/drm_helper.h index 7dff0b66c18..b1524c192e5 100644 --- a/src/gallium/auxiliary/target-helpers/drm_helper.h +++ b/src/gallium/auxiliary/target-helpers/drm_helper.h @@ -267,11 +267,18 @@ pipe_msm_create_screen(int fd, const struct pipe_screen_config *config) screen = fd_drm_screen_create(fd, NULL, config); return screen ? debug_screen_wrap(screen) : NULL; } -DRM_DRIVER_DESCRIPTOR(msm, NULL, 0) + +const driOptionDescription msm_driconf[] = { +#ifdef GALLIUM_FREEDRENO + #include "freedreno/driinfo_freedreno.h" +#endif +}; +DRM_DRIVER_DESCRIPTOR(msm, msm_driconf, ARRAY_SIZE(msm_driconf)) +DRM_DRIVER_DESCRIPTOR_ALIAS(msm, kgsl, msm_driconf, ARRAY_SIZE(msm_driconf)) #else DRM_DRIVER_DESCRIPTOR_STUB(msm) +DRM_DRIVER_DESCRIPTOR_STUB(kgsl) #endif -DRM_DRIVER_DESCRIPTOR_ALIAS(msm, kgsl, NULL, 0) #if defined(GALLIUM_VIRGL) || (defined(GALLIUM_FREEDRENO) && !defined(PIPE_LOADER_DYNAMIC)) #include "virgl/drm/virgl_drm_public.h" @@ -295,9 +302,7 @@ pipe_virtio_gpu_create_screen(int fd, const struct pipe_screen_config *config) } const driOptionDescription virgl_driconf[] = { -#ifdef GALLIUM_VIRGL #include "virgl/virgl_driinfo.h.in" -#endif }; DRM_DRIVER_DESCRIPTOR(virtio_gpu, virgl_driconf, ARRAY_SIZE(virgl_driconf)) diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c index 7dc9fcba543..c576b58c8cd 100644 --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c @@ -202,17 +202,8 @@ compute_lrz_state(struct fd6_emit *emit) assert_dt * Normally looking at the state in draw C, we'd assume we could * enable LRZ write. But this would cause early-z/lrz to discard * fragments from draw A which should be visible due to draw B. - * - * NOTE: So far invalid rendering due to this case has only been - * found in a single game (The Walking Dead: Season One - - * com.telltalegames.walkingdead100). But other Telltale Games - * use the same Telltale Tool engine, so they might also have the - * same issue. But blend+depthwrite is more common. Hopefully - * it only shows up late in the renderpass where invalidating LRZ - * would not be too costly, but if this is found to cause perf - * regressions, a driconf allowlist/denylist can be added. */ - if (reads_dest && zsa->writes_z) { + if (reads_dest && zsa->writes_z && ctx->screen->conservative_lrz) { if (!zsa->perf_warn_blend && rsc->lrz_valid) { perf_debug_ctx(ctx, "Invalidating LRZ due to blend+depthwrite"); zsa->perf_warn_blend = true; diff --git a/src/gallium/drivers/freedreno/driinfo_freedreno.h b/src/gallium/drivers/freedreno/driinfo_freedreno.h new file mode 100644 index 00000000000..a23b865ebd4 --- /dev/null +++ b/src/gallium/drivers/freedreno/driinfo_freedreno.h @@ -0,0 +1,5 @@ +// freedreno specific driconf options + +DRI_CONF_SECTION_MISCELLANEOUS + DRI_CONF_DISABLE_CONSERVATIVE_LRZ(false) +DRI_CONF_SECTION_END diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 308aa239cd5..9a7ad7e9452 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -1096,6 +1096,9 @@ fd_screen_create(struct fd_device *dev, struct renderonly *ro, driParseConfigFiles(config->options, config->options_info, 0, "msm", NULL, fd_dev_name(screen->dev_id), NULL, 0, NULL, 0); + screen->conservative_lrz = + !driQueryOptionb(config->options, "disable_conservative_lrz"); + struct sysinfo si; sysinfo(&si); screen->ram_size = si.totalram; diff --git a/src/gallium/drivers/freedreno/freedreno_screen.h b/src/gallium/drivers/freedreno/freedreno_screen.h index 0aa0e2357c4..0e2d5790989 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.h +++ b/src/gallium/drivers/freedreno/freedreno_screen.h @@ -94,6 +94,14 @@ struct fd_screen { bool has_robustness; bool has_syncobj; + /* Conservative LRZ (default true) invalidates LRZ on draws with + * blend and depth-write enabled, because this can lead to incorrect + * rendering. Driconf can be used to disable conservative LRZ for + * games which do not have the problematic sequence of draws *and* + * suffer a performance loss with conservative LRZ. + */ + bool conservative_lrz; + const struct fd_dev_info *info; uint32_t ccu_offset_gmem; uint32_t ccu_offset_bypass; diff --git a/src/gallium/drivers/freedreno/meson.build b/src/gallium/drivers/freedreno/meson.build index d2c33d6649f..00642b7a2ce 100644 --- a/src/gallium/drivers/freedreno/meson.build +++ b/src/gallium/drivers/freedreno/meson.build @@ -19,6 +19,7 @@ # SOFTWARE. files_libfreedreno = files( + 'driinfo_freedreno.h', 'freedreno_autotune.c', 'freedreno_autotune.h', 'freedreno_batch.c', diff --git a/src/gallium/drivers/virgl/virgl_driinfo.h.in b/src/gallium/drivers/virgl/virgl_driinfo.h.in index f57e5880965..301247b35ec 100644 --- a/src/gallium/drivers/virgl/virgl_driinfo.h.in +++ b/src/gallium/drivers/virgl/virgl_driinfo.h.in @@ -11,4 +11,12 @@ DRI_CONF_SECTION_MISCELLANEOUS DRI_CONF_GLES_EMULATE_BGRA(true) DRI_CONF_GLES_APPLY_BGRA_DEST_SWIZZLE(true) DRI_CONF_GLES_SAMPLES_PASSED_VALUE(1024, 1, 400000000) + + /* + * Native-context drivers also (can) bind to the some virtio_gpu guest + * kernel device. Because drm_helper ties the driconf config to the + * drm device name, we also need to include config options for any + * possible drm-native-context guest driver: + */ + DRI_CONF_DISABLE_CONSERVATIVE_LRZ(false) DRI_CONF_SECTION_END diff --git a/src/util/driconf.h b/src/util/driconf.h index bcc6d8190e4..899a6ae2bb8 100644 --- a/src/util/driconf.h +++ b/src/util/driconf.h @@ -515,6 +515,14 @@ DRI_CONF_OPT_B(format_l8_srgb_enable_readback, def, \ "Force-enable reading back L8_SRGB textures") +/** + * \brief freedreno specific configuration options + */ + +#define DRI_CONF_DISABLE_CONSERVATIVE_LRZ(def) \ + DRI_CONF_OPT_B(disable_conservative_lrz, def, \ + "Disable conservative LRZ") + /** * \brief venus specific configuration options */