Mesa (main): mesa: consider the sample count when choosing a texture format

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri May 6 00:24:55 UTC 2022


Module: Mesa
Branch: main
Commit: 89c94502b6650fed222abd3588e9c927811580aa
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=89c94502b6650fed222abd3588e9c927811580aa

Author: Marek Olšák <marek.olsak at amd.com>
Date:   Wed Apr 27 07:35:48 2022 -0400

mesa: consider the sample count when choosing a texture format

The set of supported MSAA formats can be smaller than the set of supported
non-MSAA formats.

Reviewed-by: Adam Jackson <ajax at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16326>

---

 src/mesa/main/formatquery.c               |  3 ++-
 src/mesa/main/teximage.c                  | 32 +++++++++++++++++++++++++------
 src/mesa/main/teximage.h                  |  3 ++-
 src/mesa/main/texobj.c                    |  2 +-
 src/mesa/main/texstorage.c                |  2 +-
 src/mesa/main/textureview.c               |  2 +-
 src/mesa/state_tracker/st_cb_drawpixels.c |  2 +-
 src/mesa/state_tracker/st_cb_readpixels.c |  2 +-
 src/mesa/state_tracker/st_cb_texture.c    |  8 ++++----
 src/mesa/state_tracker/st_format.c        | 26 +++++++++++++++----------
 src/mesa/state_tracker/st_format.h        |  5 +++--
 11 files changed, 58 insertions(+), 29 deletions(-)

diff --git a/src/mesa/main/formatquery.c b/src/mesa/main/formatquery.c
index 2c2e434c9b2..472705df7e8 100644
--- a/src/mesa/main/formatquery.c
+++ b/src/mesa/main/formatquery.c
@@ -997,7 +997,8 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
        * same format-choice logic as for textures.
        */
       texformat = st_ChooseTextureFormat(ctx, target, internalformat,
-                                         GL_NONE /*format */, GL_NONE /* type */);
+                                         GL_NONE /*format */, GL_NONE /* type */,
+                                         0);
 
       if (texformat == MESA_FORMAT_NONE || baseformat <= 0)
          goto end;
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 62e9d77dead..edea906239e 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -2821,7 +2821,8 @@ mesa_format
 _mesa_choose_texture_format(struct gl_context *ctx,
                             struct gl_texture_object *texObj,
                             GLenum target, GLint level,
-                            GLenum internalFormat, GLenum format, GLenum type)
+                            GLenum internalFormat, GLenum format, GLenum type,
+                            unsigned samples)
 {
    mesa_format f;
 
@@ -2841,8 +2842,27 @@ _mesa_choose_texture_format(struct gl_context *ctx,
       }
    }
 
-   f = st_ChooseTextureFormat(ctx, target, internalFormat,
-                              format, type);
+   if (samples > 0) {
+      /* TODO: This somewhat duplicates the logic in st_texture_storage. */
+      /* Find msaa sample count which is actually supported.  For example,
+       * if the user requests 1x but only 4x or 8x msaa is supported, we'll
+       * choose 4x here.
+       */
+      if (ctx->Const.MaxSamples > 1 && samples == 1) {
+         /* don't try num_samples = 1 with drivers that support real msaa */
+         samples = 2;
+      }
+
+      for (; samples <= ctx->Const.MaxSamples; samples++) {
+         f = st_ChooseTextureFormat(ctx, target, internalFormat,
+                                    format, type, samples);
+         if (f != PIPE_FORMAT_NONE)
+            break;
+      }
+   } else {
+      f = st_ChooseTextureFormat(ctx, target, internalFormat,
+                                 format, type, samples);
+   }
    assert(f != MESA_FORMAT_NONE);
    return f;
 }
@@ -3073,7 +3093,7 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims,
       }
 
       texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
-                                              internalFormat, format, type);
+                                              internalFormat, format, type, 0);
    }
 
    assert(texFormat != MESA_FORMAT_NONE);
@@ -4312,7 +4332,7 @@ copyteximage(struct gl_context *ctx, GLuint dims, struct gl_texture_object *texO
    assert(texObj);
 
    texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
-                                           internalFormat, GL_NONE, GL_NONE);
+                                           internalFormat, GL_NONE, GL_NONE, 0);
 
    /* First check if reallocating the texture buffer can be avoided.
     * Without the realloc the copy can be 20x faster.
@@ -6832,7 +6852,7 @@ texture_image_multisample(struct gl_context *ctx, GLuint dims,
    }
 
    texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
-         internalformat, GL_NONE, GL_NONE);
+         internalformat, GL_NONE, GL_NONE, samples);
    assert(texFormat != MESA_FORMAT_NONE);
 
    dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0,
diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h
index da8721ddc81..81838132935 100644
--- a/src/mesa/main/teximage.h
+++ b/src/mesa/main/teximage.h
@@ -144,7 +144,8 @@ extern mesa_format
 _mesa_choose_texture_format(struct gl_context *ctx,
                             struct gl_texture_object *texObj,
                             GLenum target, GLint level,
-                            GLenum internalFormat, GLenum format, GLenum type);
+                            GLenum internalFormat, GLenum format, GLenum type,
+                            unsigned samples);
 
 extern void
 _mesa_update_fbo_texture(struct gl_context *ctx,
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index 266384ad18e..256d4085307 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -1018,7 +1018,7 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
 
       texFormat = st_ChooseTextureFormat(ctx, target,
                                          GL_RGBA, GL_RGBA,
-                                         GL_UNSIGNED_BYTE);
+                                         GL_UNSIGNED_BYTE, 0);
 
       /* need a loop here just for cube maps */
       for (face = 0; face < numFaces; face++) {
diff --git a/src/mesa/main/texstorage.c b/src/mesa/main/texstorage.c
index 166e68ea45f..d1e24d88a3a 100644
--- a/src/mesa/main/texstorage.c
+++ b/src/mesa/main/texstorage.c
@@ -455,7 +455,7 @@ texture_storage(struct gl_context *ctx, GLuint dims,
    }
 
    texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
-                                           internalformat, GL_NONE, GL_NONE);
+                                           internalformat, GL_NONE, GL_NONE, 0);
 
    if (!no_error) {
       /* check that width, height, depth are legal for the mipmap level */
diff --git a/src/mesa/main/textureview.c b/src/mesa/main/textureview.c
index f6c70aebf27..3829f429eb5 100644
--- a/src/mesa/main/textureview.c
+++ b/src/mesa/main/textureview.c
@@ -541,7 +541,7 @@ texture_view(struct gl_context *ctx, struct gl_texture_object *origTexObj,
    GLenum faceTarget;
 
    texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
-                                           internalformat, GL_NONE, GL_NONE);
+                                           internalformat, GL_NONE, GL_NONE, 0);
    if (texFormat == MESA_FORMAT_NONE) return;
 
    newViewNumLevels = MIN2(numlevels, origTexObj->Attrib.NumLevels - minlevel);
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 4af6c1e8628..7841b1e2055 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -629,7 +629,7 @@ make_texture(struct st_context *st,
     * image to draw.
     */
    pipeFormat = st_choose_matching_format(st, PIPE_BIND_SAMPLER_VIEW,
-                                          format, type, unpack->SwapBytes);
+                                          format, type, 0, 0, unpack->SwapBytes);
 
    if (pipeFormat == PIPE_FORMAT_NONE) {
       /* Use the generic approach. */
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index 6364d8f9444..0b66e56e235 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -476,7 +476,7 @@ st_ReadPixels(struct gl_context *ctx, GLint x, GLint y,
 
    /* Choose the destination format by finding the best match
     * for the format+type combo. */
-   dst_format = st_choose_matching_format(st, bind, format, type,
+   dst_format = st_choose_matching_format(st, bind, format, type, 0, 0,
                                           pack->SwapBytes);
    if (dst_format == PIPE_FORMAT_NONE) {
       goto fallback;
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index d3b041616bb..facf0584ad9 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -295,7 +295,7 @@ st_pbo_get_dst_format(struct gl_context *ctx, enum pipe_texture_target target,
    /* Choose the destination format by finding the best match
     * for the format+type combo. */
    enum pipe_format dst_format = st_choose_matching_format(st, bind, format, type,
-                                                           ctx->Pack.SwapBytes);
+                                                           0, 0, ctx->Pack.SwapBytes);
 
    if (dst_format == PIPE_FORMAT_NONE) {
       GLenum dst_glformat;
@@ -1032,7 +1032,7 @@ prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage,
       /* oops, need to init this image again */
       texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
                                               texImage->InternalFormat, format,
-                                              type);
+                                              type, texImage->NumSamples);
 
       _mesa_init_teximage_fields(ctx, texImage,
                                  texImage->Width, texImage->Height,
@@ -1623,7 +1623,7 @@ try_pbo_upload(struct gl_context *ctx, GLuint dims,
     * support at all because of the remapping we later perform and because
     * at least the Radeon driver actually supports some formats for texture
     * buffers which it doesn't support for regular textures. */
-   src_format = st_choose_matching_format(st, 0, format, type,
+   src_format = st_choose_matching_format(st, 0, format, type, 0, 0,
                                           unpack->SwapBytes);
    if (!src_format) {
       return false;
@@ -2001,7 +2001,7 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims,
 
    /* Choose the source format. */
    src_format = st_choose_matching_format(st, PIPE_BIND_SAMPLER_VIEW,
-                                          format, type, unpack->SwapBytes);
+                                          format, type, 0, 0, unpack->SwapBytes);
    if (!src_format) {
       goto fallback;
    }
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index fadd03073aa..4ce75a8fd8d 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -1138,8 +1138,8 @@ st_choose_format(struct st_context *st, GLenum internalFormat,
     */
    if (_mesa_is_enum_format_unsized(internalFormat) && format != 0 &&
        _mesa_is_type_unsigned(type)) {
-      pf = st_choose_matching_format(st, bindings, format, type,
-                                     swap_bytes);
+      pf = st_choose_matching_format(st, bindings, format, type, sample_count,
+                                     storage_sample_count, swap_bytes);
 
       if (pf != PIPE_FORMAT_NONE &&
           (!bindings || screen->is_format_supported(screen, pf, target, sample_count,
@@ -1236,12 +1236,15 @@ st_choose_matching_format_noverify(struct st_context *st,
  */
 enum pipe_format
 st_choose_matching_format(struct st_context *st, unsigned bind,
-                          GLenum format, GLenum type, GLboolean swapBytes)
+                          GLenum format, GLenum type, unsigned num_samples,
+                          unsigned num_storage_samples, GLboolean swapBytes)
 {
    struct pipe_screen *screen = st->screen;
    enum pipe_format pformat = st_choose_matching_format_noverify(st, format, type, swapBytes);
    if (pformat != PIPE_FORMAT_NONE &&
-       (!bind || screen->is_format_supported(screen, pformat, PIPE_TEXTURE_2D, 0, 0, bind)))
+       (!bind || screen->is_format_supported(screen, pformat, PIPE_TEXTURE_2D,
+                                             num_samples, num_storage_samples,
+                                             bind)))
       return pformat;
 
    return PIPE_FORMAT_NONE;
@@ -1254,7 +1257,7 @@ st_choose_matching_format(struct st_context *st, unsigned bind,
 mesa_format
 st_ChooseTextureFormat(struct gl_context *ctx, GLenum target,
                        GLint internalFormat,
-                       GLenum format, GLenum type)
+                       GLenum format, GLenum type, unsigned samples)
 {
    struct st_context *st = st_context(ctx);
    enum pipe_format pFormat;
@@ -1320,6 +1323,7 @@ st_ChooseTextureFormat(struct gl_context *ctx, GLenum target,
        */
       if (iformat == baseFormat && iformat == basePackFormat) {
          pFormat = st_choose_matching_format(st, bindings, format, type,
+                                             samples, samples,
                                              ctx->Unpack.SwapBytes);
 
          if (pFormat != PIPE_FORMAT_NONE)
@@ -1330,7 +1334,7 @@ st_ChooseTextureFormat(struct gl_context *ctx, GLenum target,
              * target bindings.
              */
             pFormat = st_choose_matching_format(st, PIPE_BIND_SAMPLER_VIEW,
-                                                format, type,
+                                                format, type, samples, samples,
                                                 ctx->Unpack.SwapBytes);
             if (pFormat != PIPE_FORMAT_NONE)
                return st_pipe_format_to_mesa_format(pFormat);
@@ -1339,13 +1343,13 @@ st_ChooseTextureFormat(struct gl_context *ctx, GLenum target,
    }
 
    pFormat = st_choose_format(st, internalFormat, format, type,
-                              pTarget, 0, 0, bindings,
+                              pTarget, samples, samples, bindings,
                               ctx->Unpack.SwapBytes, true);
 
    if (pFormat == PIPE_FORMAT_NONE && !is_renderbuffer) {
       /* try choosing format again, this time without render target bindings */
       pFormat = st_choose_format(st, internalFormat, format, type,
-                                 pTarget, 0, 0, PIPE_BIND_SAMPLER_VIEW,
+                                 pTarget, samples, samples, PIPE_BIND_SAMPLER_VIEW,
                                  ctx->Unpack.SwapBytes, true);
    }
 
@@ -1479,7 +1483,8 @@ st_QueryInternalFormat(struct gl_context *ctx, GLenum target,
       break;
    }
    case GL_TEXTURE_REDUCTION_MODE_ARB: {
-      mesa_format format = st_ChooseTextureFormat(ctx, target, internalFormat, GL_NONE, GL_NONE);
+      mesa_format format = st_ChooseTextureFormat(ctx, target, internalFormat,
+                                                  GL_NONE, GL_NONE, 0);
       enum pipe_format pformat = st_mesa_format_to_pipe_format(st, format);
       struct pipe_screen *screen = st->screen;
       params[0] = pformat != PIPE_FORMAT_NONE &&
@@ -1494,7 +1499,8 @@ st_QueryInternalFormat(struct gl_context *ctx, GLenum target,
       /* this is used only for passing CTS */
       if (target == GL_RENDERBUFFER)
          target = GL_TEXTURE_2D;
-      mesa_format format = st_ChooseTextureFormat(ctx, target, internalFormat, GL_NONE, GL_NONE);
+      mesa_format format = st_ChooseTextureFormat(ctx, target, internalFormat,
+                                                  GL_NONE, GL_NONE, 0);
       enum pipe_format pformat = st_mesa_format_to_pipe_format(st, format);
 
       if (pformat != PIPE_FORMAT_NONE) {
diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h
index 33f43e742dd..028987cfac0 100644
--- a/src/mesa/state_tracker/st_format.h
+++ b/src/mesa/state_tracker/st_format.h
@@ -64,12 +64,13 @@ st_choose_matching_format_noverify(struct st_context *st,
 
 extern enum pipe_format
 st_choose_matching_format(struct st_context *st, unsigned bind,
-			  GLenum format, GLenum type, GLboolean swapBytes);
+			  GLenum format, GLenum type, unsigned num_samples,
+                          unsigned num_storage_samples, GLboolean swapBytes);
 
 extern mesa_format
 st_ChooseTextureFormat(struct gl_context * ctx, GLenum target,
                        GLint internalFormat,
-                       GLenum format, GLenum type);
+                       GLenum format, GLenum type, unsigned samples);
 
 void
 st_QueryInternalFormat(struct gl_context *ctx, GLenum target,



More information about the mesa-commit mailing list