Mesa (master): mesa/st: Reuse st_choose_matching_format from st_choose_format().

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Nov 15 20:53:54 UTC 2019


Module: Mesa
Branch: master
Commit: b30589cbd3dd61a8bb27757fecd536cb559732ad
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=b30589cbd3dd61a8bb27757fecd536cb559732ad

Author: Eric Anholt <eric at anholt.net>
Date:   Tue Sep 17 12:39:23 2019 -0700

mesa/st: Reuse st_choose_matching_format from st_choose_format().

We had this ad-hoc exact size matching for unsized internalformats,
but st_choose_matching_format() can do exactly what we want.  This
means, that, for example, we'll now prefer the matching ordering for
565/565_REV if the driver supports both orders.  We also pass
Unpack.SwapBytes through from ChooseTextureFormat so that we can hit
the memcpy path for 8888 formats when that flag is set.

Some interesting format choice changes from this (on softpipe):
intf/form/type        before            after
----------------------------------------------------
RGBA/RGBA/USHORT:     R8G8B8A8_UNORM -> RGBA_UNORM16
RGB/RGBA/8888:        X8B8G8R8_UNORM -> R8G8B8X8_UNORM
RGB/ABGR/8888_REV:    X8B8G8R8_UNORM -> R8G8B8X8_UNORM
RGBA/RGBA/5551:       B5G5R5A1_UNORM -> A1B5G5R5_UNORM
RGBA/RGBA/4444:       R8G8B8A8_UNORM -> A4B4G4R4_UNORM
RGBA/GL_RGBA/1010102: R8G8B8A8_UNORM -> A2B10G10R10_UNORM
DEPTH/DEPTH/UINT:     Z24X8          -> Z_UNORM32
DEPTH/DEPTH/USHORT:   Z24X8          -> Z_UNORM16

v2: Make sure that the baseformat still matches.  v1 would pick
    MESA_FORMAT_L16_UNORM for RED/LUMINANCE/SHORT, when we clearly
    want a red format.

Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>

---

 src/mesa/state_tracker/st_cb_drawpixels.c |  15 ++--
 src/mesa/state_tracker/st_cb_texture.c    |   3 +-
 src/mesa/state_tracker/st_format.c        | 111 ++++++++----------------------
 src/mesa/state_tracker/st_format.h        |   2 +-
 src/mesa/state_tracker/st_texture.c       |   2 +-
 5 files changed, 39 insertions(+), 94 deletions(-)

diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 2a59566abef..6b47548d33b 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -642,7 +642,8 @@ make_texture(struct st_context *st,
 
       pipeFormat = st_choose_format(st, intFormat, format, type,
                                     st->internal_target, 0, 0,
-                                    PIPE_BIND_SAMPLER_VIEW, FALSE);
+                                    PIPE_BIND_SAMPLER_VIEW,
+                                    false, false);
       assert(pipeFormat != PIPE_FORMAT_NONE);
    }
 
@@ -1772,7 +1773,7 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
       if (type == GL_DEPTH) {
          srcFormat = st_choose_format(st, GL_DEPTH_COMPONENT, GL_NONE,
                                       GL_NONE, st->internal_target, 0, 0,
-                                      srcBind, FALSE);
+                                      srcBind, false, false);
       }
       else {
          assert(type == GL_COLOR);
@@ -1780,27 +1781,27 @@ st_CopyPixels(struct gl_context *ctx, GLint srcx, GLint srcy,
          if (util_format_is_float(srcFormat)) {
             srcFormat = st_choose_format(st, GL_RGBA32F, GL_NONE,
                                          GL_NONE, st->internal_target, 0, 0,
-                                         srcBind, FALSE);
+                                         srcBind, false, false);
          }
          else if (util_format_is_pure_sint(srcFormat)) {
             srcFormat = st_choose_format(st, GL_RGBA32I, GL_NONE,
                                          GL_NONE, st->internal_target, 0, 0,
-                                         srcBind, FALSE);
+                                         srcBind, false, false);
          }
          else if (util_format_is_pure_uint(srcFormat)) {
             srcFormat = st_choose_format(st, GL_RGBA32UI, GL_NONE,
                                          GL_NONE, st->internal_target, 0, 0,
-                                         srcBind, FALSE);
+                                         srcBind, false, false);
          }
          else if (util_format_is_snorm(srcFormat)) {
             srcFormat = st_choose_format(st, GL_RGBA16_SNORM, GL_NONE,
                                          GL_NONE, st->internal_target, 0, 0,
-                                         srcBind, FALSE);
+                                         srcBind, false, false);
          }
          else {
             srcFormat = st_choose_format(st, GL_RGBA, GL_NONE,
                                          GL_NONE, st->internal_target, 0, 0,
-                                         srcBind, FALSE);
+                                         srcBind, false, false);
          }
       }
 
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 5954d424249..ace19c59b0e 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -2090,7 +2090,8 @@ st_GetTexSubImage(struct gl_context * ctx,
       }
 
       dst_format = st_choose_format(st, dst_glformat, format, type,
-                                    pipe_target, 0, 0, bind, FALSE);
+                                    pipe_target, 0, 0, bind,
+                                    false, false);
 
       if (dst_format == PIPE_FORMAT_NONE) {
          /* unable to get an rgba format!?! */
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index 396254afbea..c0e9e25c71d 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -1078,78 +1078,6 @@ find_supported_format(struct pipe_screen *screen,
    return PIPE_FORMAT_NONE;
 }
 
-
-struct exact_format_mapping
-{
-   GLenum format;
-   GLenum type;
-   enum pipe_format pformat;
-};
-
-static const struct exact_format_mapping rgba8888_tbl[] =
-{
-   { GL_RGBA,     GL_UNSIGNED_INT_8_8_8_8,        PIPE_FORMAT_ABGR8888_UNORM },
-   { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV,    PIPE_FORMAT_ABGR8888_UNORM },
-   { GL_RGBA,     GL_UNSIGNED_INT_8_8_8_8_REV,    PIPE_FORMAT_RGBA8888_UNORM },
-   { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8,        PIPE_FORMAT_RGBA8888_UNORM },
-   { GL_BGRA,     GL_UNSIGNED_INT_8_8_8_8,        PIPE_FORMAT_ARGB8888_UNORM },
-   { GL_BGRA,     GL_UNSIGNED_INT_8_8_8_8_REV,    PIPE_FORMAT_BGRA8888_UNORM },
-   { GL_RGBA,     GL_UNSIGNED_BYTE,               PIPE_FORMAT_R8G8B8A8_UNORM },
-   { GL_ABGR_EXT, GL_UNSIGNED_BYTE,               PIPE_FORMAT_A8B8G8R8_UNORM },
-   { GL_BGRA,     GL_UNSIGNED_BYTE,               PIPE_FORMAT_B8G8R8A8_UNORM },
-   { 0,           0,                              0                          }
-};
-
-static const struct exact_format_mapping rgbx8888_tbl[] =
-{
-   { GL_RGBA,     GL_UNSIGNED_INT_8_8_8_8,        PIPE_FORMAT_XBGR8888_UNORM },
-   { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV,    PIPE_FORMAT_XBGR8888_UNORM },
-   { GL_RGBA,     GL_UNSIGNED_INT_8_8_8_8_REV,    PIPE_FORMAT_RGBX8888_UNORM },
-   { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8,        PIPE_FORMAT_RGBX8888_UNORM },
-   { GL_BGRA,     GL_UNSIGNED_INT_8_8_8_8,        PIPE_FORMAT_XRGB8888_UNORM },
-   { GL_BGRA,     GL_UNSIGNED_INT_8_8_8_8_REV,    PIPE_FORMAT_BGRX8888_UNORM },
-   { GL_RGBA,     GL_UNSIGNED_BYTE,               PIPE_FORMAT_R8G8B8X8_UNORM },
-   { GL_ABGR_EXT, GL_UNSIGNED_BYTE,               PIPE_FORMAT_X8B8G8R8_UNORM },
-   { GL_BGRA,     GL_UNSIGNED_BYTE,               PIPE_FORMAT_B8G8R8X8_UNORM },
-   { 0,           0,                              0                          }
-};
-
-
-/**
- * For unsized/base internal formats, we may choose a convenient effective
- * internal format for {format, type}. If one exists, return that, otherwise
- * return PIPE_FORMAT_NONE.
- */
-static enum pipe_format
-find_exact_format(GLint internalFormat, GLenum format, GLenum type)
-{
-   uint i;
-   const struct exact_format_mapping* tbl;
-
-   if (format == GL_NONE || type == GL_NONE)
-      return PIPE_FORMAT_NONE;
-
-   switch (internalFormat) {
-   case 4:
-   case GL_RGBA:
-      tbl = rgba8888_tbl;
-      break;
-   case 3:
-   case GL_RGB:
-      tbl = rgbx8888_tbl;
-      break;
-   default:
-      return PIPE_FORMAT_NONE;
-   }
-
-   for (i = 0; tbl[i].format; i++)
-      if (tbl[i].format == format && tbl[i].type == type)
-         return tbl[i].pformat;
-
-   return PIPE_FORMAT_NONE;
-}
-
-
 /**
  * Given an OpenGL internalFormat value for a texture or surface, return
  * the best matching PIPE_FORMAT_x, or PIPE_FORMAT_NONE if there's no match.
@@ -1172,7 +1100,7 @@ st_choose_format(struct st_context *st, GLenum internalFormat,
                  GLenum format, GLenum type,
                  enum pipe_texture_target target, unsigned sample_count,
                  unsigned storage_sample_count,
-                 unsigned bindings, boolean allow_dxt)
+                 unsigned bindings, bool swap_bytes, bool allow_dxt)
 {
    struct pipe_screen *screen = st->pipe->screen;
    unsigned i;
@@ -1185,12 +1113,23 @@ st_choose_format(struct st_context *st, GLenum internalFormat,
       return PIPE_FORMAT_NONE;
    }
 
-   /* search for exact matches */
-   pf = find_exact_format(internalFormat, format, type);
-   if (pf != PIPE_FORMAT_NONE &&
-       screen->is_format_supported(screen, pf, target, sample_count,
-                                   storage_sample_count, bindings)) {
-      goto success;
+   /* If we have an unsized internalFormat, and the driver supports a format
+    * that exactly matches format/type such that we can just memcpy, pick that
+    * (unless the format wouldn't still be unorm, which is the expectation for
+    * unsized formats).
+    */
+   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);
+
+      if (pf != PIPE_FORMAT_NONE &&
+          screen->is_format_supported(screen, pf, target, sample_count,
+                                      storage_sample_count, bindings) &&
+          _mesa_get_format_base_format(st_pipe_format_to_mesa_format(pf)) ==
+          internalFormat) {
+         goto success;
+      }
    }
 
    /* For an unsized GL_RGB but a 2_10_10_10 type, try to pick one of the
@@ -1261,7 +1200,8 @@ st_choose_renderbuffer_format(struct st_context *st,
       bindings = PIPE_BIND_RENDER_TARGET;
    return st_choose_format(st, internalFormat, GL_NONE, GL_NONE,
                            PIPE_TEXTURE_2D, sample_count,
-                           storage_sample_count, bindings, FALSE);
+                           storage_sample_count, bindings,
+                           false, false);
 }
 
 
@@ -1382,13 +1322,14 @@ st_ChooseTextureFormat(struct gl_context *ctx, GLenum target,
    }
 
    pFormat = st_choose_format(st, internalFormat, format, type,
-                              pTarget, 0, 0, bindings, GL_TRUE);
+                              pTarget, 0, 0, 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,
-                                 GL_TRUE);
+                                 ctx->Unpack.SwapBytes, true);
    }
 
    if (pFormat == PIPE_FORMAT_NONE) {
@@ -1445,7 +1386,8 @@ st_QuerySamplesForFormat(struct gl_context *ctx, GLenum target,
    /* Set sample counts in descending order. */
    for (i = 16; i > 1; i--) {
       format = st_choose_format(st, internalFormat, GL_NONE, GL_NONE,
-                                PIPE_TEXTURE_2D, i, i, bind, FALSE);
+                                PIPE_TEXTURE_2D, i, i, bind,
+                                false, false);
 
       if (format != PIPE_FORMAT_NONE) {
          samples[num_sample_counts++] = i;
@@ -1505,7 +1447,8 @@ st_QueryInternalFormat(struct gl_context *ctx, GLenum target,
                                                   GL_NONE,
                                                   GL_NONE,
                                                   PIPE_TEXTURE_2D, 0, 0,
-                                                  bindings, FALSE);
+                                                  bindings,
+                                                  false, false);
       if (pformat)
          params[0] = internalFormat;
       break;
diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h
index 036d3378286..0a8e3bc921f 100644
--- a/src/mesa/state_tracker/st_format.h
+++ b/src/mesa/state_tracker/st_format.h
@@ -55,7 +55,7 @@ st_choose_format(struct st_context *st, GLenum internalFormat,
                  GLenum format, GLenum type,
                  enum pipe_texture_target target, unsigned sample_count,
                  unsigned storage_sample_count,
-                 unsigned bindings, boolean allow_dxt);
+                 unsigned bindings, bool swap_bytes, bool allow_dxt);
 
 extern enum pipe_format
 st_choose_renderbuffer_format(struct st_context *st,
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index 72fc4a0c09b..a2a310daab4 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -416,7 +416,7 @@ st_create_color_map_texture(struct gl_context *ctx)
    /* find an RGBA texture format */
    format = st_choose_format(st, GL_RGBA, GL_NONE, GL_NONE,
                              PIPE_TEXTURE_2D, 0, 0, PIPE_BIND_SAMPLER_VIEW,
-                             FALSE);
+                             false, false);
 
    /* create texture for color map/table */
    pt = st_texture_create(st, PIPE_TEXTURE_2D, format, 0,




More information about the mesa-commit mailing list