st/mesa: search for smallest supported sample-count

For MaxColorTextureSamples etc, we need to report the smallest
sample-count that is guaranteed to work. On some GPUs (e.g. Arm's Mali
GPUs), larger pixel-formats can't always support the higher sample
counts, becuse it takes up too much storage in the tile buffers.

From the OpenGL 4.6 spec, section 22.3.2 ("Other internal format
queries"):

  "The maximum value in SAMPLES is guaranteed to be at least the
   lowest of the following:

   * The value of MAX_INTEGER_SAMPLES, if internalformat is a
     signed or unsigned integer format.

   * The value of MAX_DEPTH_TEXTURE_SAMPLES, if internalformat
     is a depth/stencil-renderable format and target is TEXTURE_2D_-
     MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY.

   * The value of MAX_COLOR_TEXTURE_SAMPLES, if internalfor-
     mat is a color-renderable format and target is TEXTURE_2D_-
     MULTISAMPLE or TEXTURE_2D_MULTISAMPLE_ARRAY.

   * The value of MAX_SAMPLES"

Since SAMPLES needs to be *at least* MAX_COLOR_TEXTURE_SAMPLES here, we
need to set it to the smallest possible value for any format.

So let's swap the loops here, trying one format at the time. To avoid
doing needless tests, we check from the largest value supported in all
previous formats, omitting sample-counts that has previously been ruled
out.

In addition, we need to check a few larger formats as well, to capture
the limitations above. Since large formats exists in fewer swizzle
variants, we don't need to check as many options as for 8-bit per
component formats.

And since the larger formats are the most likely ones to support lower
sample counts, make sure those formats are listed first.

Reviewed-by: Eric R. Smith <eric.smith@collabora.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34455>
This commit is contained in:
Erik Faye-Lund 2025-04-07 21:05:04 +02:00 committed by Marge Bot
parent 96d62b47fd
commit f56443ac84

View file

@ -704,17 +704,19 @@ get_max_samples_for_formats(struct pipe_screen *screen,
unsigned max_samples,
unsigned bind)
{
unsigned i, f;
unsigned i, f, supported_samples = 0;
for (i = max_samples; i > 0; --i) {
for (f = 0; f < num_formats; f++) {
for (f = 0; f < num_formats; f++) {
for (i = max_samples; i > 0; --i) {
if (screen->is_format_supported(screen, formats[f],
PIPE_TEXTURE_2D, i, i, bind)) {
return i;
/* update both return value and loop-boundary */
max_samples = supported_samples = i;
break;
}
}
}
return 0;
return supported_samples;
}
static unsigned
@ -1352,6 +1354,10 @@ void st_init_extensions(struct pipe_screen *screen,
/* Maximum sample count. */
{
static const enum pipe_format color_formats[] = {
PIPE_FORMAT_R32G32B32A32_FLOAT,
PIPE_FORMAT_R32G32B32A32_UNORM,
PIPE_FORMAT_R16G16B16A16_FLOAT,
PIPE_FORMAT_R16G16B16A16_UNORM,
PIPE_FORMAT_R8G8B8A8_UNORM,
PIPE_FORMAT_B8G8R8A8_UNORM,
PIPE_FORMAT_A8R8G8B8_UNORM,
@ -1365,6 +1371,8 @@ void st_init_extensions(struct pipe_screen *screen,
PIPE_FORMAT_Z32_FLOAT
};
static const enum pipe_format int_formats[] = {
PIPE_FORMAT_R32G32B32A32_SINT,
PIPE_FORMAT_R16G16B16A16_SINT,
PIPE_FORMAT_R8G8B8A8_SINT
};
static const enum pipe_format void_formats[] = {