freedreno: Add driconf to disable conservative LRZ
authorRob Clark <robdclark@chromium.org>
Mon, 16 Jan 2023 16:35:06 +0000 (08:35 -0800)
committerMarge Bot <emma+marge@anholt.net>
Fri, 20 Jan 2023 16:18:03 +0000 (16:18 +0000)
The problematic sequence of draws is pretty rare.  But there are a small
handful of games which do not exhibit the problematic sequence and for
which invalidating LRZ on draws with blend plus depthwrite enabled hurts
performance slightly.  This driconf option enables opting in to the
previous behavior.

Signed-off-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20708>

src/freedreno/vulkan/tu_device.c
src/freedreno/vulkan/tu_device.h
src/freedreno/vulkan/tu_lrz.c
src/gallium/auxiliary/target-helpers/drm_helper.h
src/gallium/drivers/freedreno/a6xx/fd6_emit.c
src/gallium/drivers/freedreno/driinfo_freedreno.h [new file with mode: 0644]
src/gallium/drivers/freedreno/freedreno_screen.c
src/gallium/drivers/freedreno/freedreno_screen.h
src/gallium/drivers/freedreno/meson.build
src/gallium/drivers/virgl/virgl_driinfo.h.in
src/util/driconf.h

index abe8515..9627e41 100644 (file)
@@ -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
index f7dab0d..51c7dfe 100644 (file)
@@ -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)
index 138b483..1553d7e 100644 (file)
@@ -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;
    }
index 7dff0b6..b1524c1 100644 (file)
@@ -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))
 
index 7dc9fcb..c576b58 100644 (file)
@@ -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 (file)
index 0000000..a23b865
--- /dev/null
@@ -0,0 +1,5 @@
+// freedreno specific driconf options
+
+DRI_CONF_SECTION_MISCELLANEOUS
+   DRI_CONF_DISABLE_CONSERVATIVE_LRZ(false)
+DRI_CONF_SECTION_END
index 308aa23..9a7ad7e 100644 (file)
@@ -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;
index 0aa0e23..0e2d579 100644 (file)
@@ -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;
index d2c33d6..00642b7 100644 (file)
@@ -19,6 +19,7 @@
 # SOFTWARE.
 
 files_libfreedreno = files(
+  'driinfo_freedreno.h',
   'freedreno_autotune.c',
   'freedreno_autotune.h',
   'freedreno_batch.c',
index f57e588..301247b 100644 (file)
@@ -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
index bcc6d81..899a6ae 100644 (file)
                   "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
  */
 #define DRI_CONF_VENUS_IMPLICIT_FENCING(def) \