mesa/st: Reuse st_choose_matching_format from st_choose_format().
authorEric Anholt <eric@anholt.net>
Tue, 17 Sep 2019 19:39:23 +0000 (12:39 -0700)
committerEric Anholt <eric@anholt.net>
Fri, 15 Nov 2019 20:32:17 +0000 (20:32 +0000)
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@whitecape.org>
src/mesa/state_tracker/st_cb_drawpixels.c
src/mesa/state_tracker/st_cb_texture.c
src/mesa/state_tracker/st_format.c
src/mesa/state_tracker/st_format.h
src/mesa/state_tracker/st_texture.c

index 2a59566abeff31fdc40af34fc37c78300a9b1734..6b47548d33ba7ab7355a3bf4c5a12728d7fe9bef 100644 (file)
@@ -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);
          }
       }
 
index 5954d424249df4410bdc81321888743c5e165e0f..ace19c59b0eb5ef7e1acacc5dd467da451036fa4 100644 (file)
@@ -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!?! */
index 396254afbeafc006bb7c138859e0694d647f0116..c0e9e25c71d13ee6bd1e8efd34c51590d534cc88 100644 (file)
@@ -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;
index 036d3378286e1efdd17a1f3a152acf8ae9f60ca9..0a8e3bc921f973645f4c7d95cbd0b93c1ad57908 100644 (file)
@@ -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,
index 72fc4a0c09b0e7197299115af877ebe66ffce9f1..a2a310daab4cfe640209edb8ac57441c09bbe58c 100644 (file)
@@ -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,