mesa: Implement MESA_texture_const_bandwidth

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/9891
Signed-off-by: Rob Clark <robdclark@chromium.org>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25464>
diff --git a/docs/gallium/screen.rst b/docs/gallium/screen.rst
index d66453c..5de2c52 100644
--- a/docs/gallium/screen.rst
+++ b/docs/gallium/screen.rst
@@ -646,6 +646,7 @@
 * ``PIPE_CAP_DEVICE_PROTECTED_CONTEXT``: Whether the device supports protected / encrypted context which can manipulate protected / encrypted content (some devices might need protected contexts to access protected content, whereas ``PIPE_CAP_DEVICE_PROTECTED_SURFACE`` does not require any particular context to do so).
 * ``PIPE_CAP_ALLOW_GLTHREAD_BUFFER_SUBDATA_OPT``: Whether to allow glthread to convert glBufferSubData to glCopyBufferSubData. This may improve or worsen performance depending on your driver.
 * ``PIPE_CAP_VALIDATE_ALL_DIRTY_STATES`` : Whether state validation must also validate the state changes for resources types used in the previous shader but not in the current shader.
+* ``PIPE_CAP_HAS_CONST_BW``: Whether the driver only supports non-data-dependent layouts (ie. not bandwidth compressed formats like AFBC, UBWC, etc), or supports ``PIPE_BIND_CONST_BW`` to disable data-dependent layouts on requested resources.
 * ``PIPE_CAP_NULL_TEXTURES`` : Whether the driver supports sampling from NULL textures.
 * ``PIPE_CAP_ASTC_VOID_EXTENTS_NEED_DENORM_FLUSH`` : True if the driver/hardware needs denormalized values in ASTC void extent blocks flushed to zero.
 
diff --git a/src/gallium/auxiliary/util/u_screen.c b/src/gallium/auxiliary/util/u_screen.c
index f7005cb..522c0e8 100644
--- a/src/gallium/auxiliary/util/u_screen.c
+++ b/src/gallium/auxiliary/util/u_screen.c
@@ -548,6 +548,7 @@
    case PIPE_CAP_VALIDATE_ALL_DIRTY_STATES:
    case PIPE_CAP_NULL_TEXTURES:
    case PIPE_CAP_ASTC_VOID_EXTENTS_NEED_DENORM_FLUSH:
+   case PIPE_CAP_HAS_CONST_BW:
       return 0;
 
    default:
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 47c06d8..0cbbb9d 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -481,7 +481,7 @@
 /* Resource is the DRI_PRIME blit destination. Only set on on the render GPU. */
 #define PIPE_BIND_PRIME_BLIT_DST (1 << 24)
 #define PIPE_BIND_USE_FRONT_RENDERING (1 << 25) /* Resource may be used for frontbuffer rendering */
-
+#define PIPE_BIND_CONST_BW    (1 << 26) /* Avoid using a data dependent layout (AFBC, UBWC, etc) */
 
 /**
  * Flags for the driver about resource behaviour:
@@ -935,6 +935,7 @@
    PIPE_CAP_ASTC_VOID_EXTENTS_NEED_DENORM_FLUSH,
 
    PIPE_CAP_VALIDATE_ALL_DIRTY_STATES,
+   PIPE_CAP_HAS_CONST_BW,
    PIPE_CAP_LAST,
    /* XXX do not add caps after PIPE_CAP_LAST! */
 };
diff --git a/src/mesa/main/consts_exts.h b/src/mesa/main/consts_exts.h
index b80f69b..ddd6b05 100644
--- a/src/mesa/main/consts_exts.h
+++ b/src/mesa/main/consts_exts.h
@@ -249,6 +249,7 @@
    GLboolean KHR_texture_compression_astc_ldr;
    GLboolean KHR_texture_compression_astc_sliced_3d;
    GLboolean MESA_framebuffer_flip_y;
+   GLboolean MESA_texture_const_bandwidth;
    GLboolean MESA_pack_invert;
    GLboolean MESA_tile_raster_order;
    GLboolean EXT_shader_framebuffer_fetch;
diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h
index 2eab460..e2ef94f 100644
--- a/src/mesa/main/extensions_table.h
+++ b/src/mesa/main/extensions_table.h
@@ -382,6 +382,7 @@
 EXT(MESA_pack_invert                        , MESA_pack_invert                       , GLL, GLC,  x ,  x , 2002)
 EXT(MESA_sampler_objects                    , dummy_true                             ,  x ,  x ,  x , ES2, 2019)
 EXT(MESA_shader_integer_functions           , MESA_shader_integer_functions          , GLL, GLC,  x ,  30, 2016)
+EXT(MESA_texture_const_bandwidth            , MESA_texture_const_bandwidth           , GLL, GLC,  x , ES2, 2023)
 EXT(MESA_texture_signed_rgba                , EXT_texture_snorm                      , GLL, GLC,  x ,  x , 2009)
 EXT(MESA_tile_raster_order                  , MESA_tile_raster_order                 , GLL, GLC,  x , ES2, 2017)
 EXT(MESA_window_pos                         , MESA_window_pos                        , GLL,  x ,  x ,  x , 2000)
diff --git a/src/mesa/main/formatquery.c b/src/mesa/main/formatquery.c
index c394fe6..ae59413 100644
--- a/src/mesa/main/formatquery.c
+++ b/src/mesa/main/formatquery.c
@@ -764,10 +764,14 @@
       break;
    case GL_NUM_TILING_TYPES_EXT:
       params[0] = 2;
+      if (_mesa_has_MESA_texture_const_bandwidth(ctx))
+         params[0]++;
       break;
    case GL_TILING_TYPES_EXT:
       params[0] = GL_OPTIMAL_TILING_EXT;
       params[1] = GL_LINEAR_TILING_EXT;
+      if (_mesa_has_MESA_texture_const_bandwidth(ctx))
+         params[2] = GL_CONST_BW_TILING_MESA;
       break;
 
    default:
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index d0f37c3..f0d0b57 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -3340,8 +3340,11 @@
    pt.bind = bind;
    /* only set this for OpenGL textures, not renderbuffers */
    pt.flags = PIPE_RESOURCE_FLAG_TEXTURING_MORE_LIKELY;
-   if (memObj->TextureTiling == GL_LINEAR_TILING_EXT)
+   if (memObj->TextureTiling == GL_LINEAR_TILING_EXT) {
       pt.bind |= PIPE_BIND_LINEAR;
+   } else if (memObj->TextureTiling == GL_CONST_BW_TILING_MESA) {
+      pt.bind |= PIPE_BIND_CONST_BW;
+   }
 
    pt.nr_samples = nr_samples;
    pt.nr_storage_samples = nr_samples;
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 8cc079e..0abc9a7 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -871,6 +871,7 @@
       { o(OES_texture_view),                 PIPE_CAP_SAMPLER_VIEW_TARGET              },
       { o(INTEL_blackhole_render),           PIPE_CAP_FRONTEND_NOOP                    },
       { o(ARM_shader_framebuffer_fetch_depth_stencil), PIPE_CAP_FBFETCH_ZS             },
+      { o(MESA_texture_const_bandwidth),     PIPE_CAP_HAS_CONST_BW                     },
    };
 
    /* Required: render target and sampler support */