mesa: handle a bunch of formats in IMPLEMENTATION_COLOR_READ_*
authorTomeu Vizoso <tomeu.vizoso@collabora.com>
Fri, 22 Jun 2018 13:04:04 +0000 (15:04 +0200)
committerJakob Bornecrantz <jakob@collabora.com>
Wed, 18 Jul 2018 13:52:35 +0000 (14:52 +0100)
Virgl could save a lot of work converting buffers in the host side
between formats if Mesa supported a bunch of other formats when reading
pixels.

This commit adds cases to handle specific formats so that the values
reported by the two calls match more closely the underlying native
formats.

In GLES is important that IMPLEMENTATION_COLOR_READ_* return the native
format and data type because the spec only allows reading with those,
besides GL_RGBA or GL_RGBA_INTEGER.

Additionally, because virgl currently doesn't implement such
conversions, this commit fixes several tests in
dEQP-GLES3.functional.fbo.color.clear.*, when using virgl in the guest
side.

The logic is based on knowledge that is shared with
_mesa_format_matches_format_and_type() but we cannot assert that the
results match as we don't have all the starting information at both
points. So leave the assert out and hope CI comes soon to save us all.

v2: * Let R10G10B10A2_UINT fall back to GL_RGBA_INTEGER (Eric Anholt)
    * Assert with _mesa_format_matches_format_and_type (Eric Anholt)

v3: * Remove the assert, as it won't be reliable (Eric Anholt)

v4: * Use _mesa_is_format_integer in the fallback (Eric Anholt)

v5: * Remove superfluous call to
      _mesa_uncompressed_format_to_type_and_comps (Eric Anholt)

Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Signed-off-by: Jakob Bornecrantz <jakob@collabora.com>
src/mesa/main/framebuffer.c

index 3ec8b91eaa2c0b62e26ea9a21635254e0ec59346..78a80649a04447ddea412a9cac40e97267159a32 100644 (file)
@@ -844,22 +844,49 @@ _mesa_get_color_read_format(struct gl_context *ctx,
    }
    else {
       const mesa_format format = fb->_ColorReadBuffer->Format;
-      const GLenum data_type = _mesa_get_format_datatype(format);
 
-      if (format == MESA_FORMAT_B8G8R8A8_UNORM)
+      switch (format) {
+      case MESA_FORMAT_RGBA_UINT8:
+         return GL_RGBA_INTEGER;
+      case MESA_FORMAT_B8G8R8A8_UNORM:
          return GL_BGRA;
-      else if (format == MESA_FORMAT_B5G6R5_UNORM)
+      case MESA_FORMAT_B5G6R5_UNORM:
+      case MESA_FORMAT_R11G11B10_FLOAT:
          return GL_RGB;
-      else if (format == MESA_FORMAT_R_UNORM8)
+      case MESA_FORMAT_RG_FLOAT32:
+      case MESA_FORMAT_RG_FLOAT16:
+      case MESA_FORMAT_R8G8_UNORM:
+      case MESA_FORMAT_R8G8_SNORM:
+         return GL_RG;
+      case MESA_FORMAT_RG_SINT32:
+      case MESA_FORMAT_RG_UINT32:
+      case MESA_FORMAT_RG_SINT16:
+      case MESA_FORMAT_RG_UINT16:
+      case MESA_FORMAT_RG_SINT8:
+      case MESA_FORMAT_RG_UINT8:
+         return GL_RG_INTEGER;
+      case MESA_FORMAT_R_FLOAT32:
+      case MESA_FORMAT_R_FLOAT16:
+      case MESA_FORMAT_R_UNORM16:
+      case MESA_FORMAT_R_UNORM8:
+      case MESA_FORMAT_R_SNORM16:
+      case MESA_FORMAT_R_SNORM8:
          return GL_RED;
+      case MESA_FORMAT_R_SINT32:
+      case MESA_FORMAT_R_UINT32:
+      case MESA_FORMAT_R_SINT16:
+      case MESA_FORMAT_R_UINT16:
+      case MESA_FORMAT_R_SINT8:
+      case MESA_FORMAT_R_UINT8:
+         return GL_RED_INTEGER;
+      default:
+         break;
+      }
 
-      switch (data_type) {
-      case GL_UNSIGNED_INT:
-      case GL_INT:
+      if (_mesa_is_format_integer(format))
          return GL_RGBA_INTEGER;
-      default:
+      else
          return GL_RGBA;
-      }
    }
 }
 
@@ -892,29 +919,13 @@ _mesa_get_color_read_type(struct gl_context *ctx,
       return GL_NONE;
    }
    else {
-      const GLenum format = fb->_ColorReadBuffer->Format;
-      const GLenum data_type = _mesa_get_format_datatype(format);
-
-      if (format == MESA_FORMAT_B5G6R5_UNORM)
-         return GL_UNSIGNED_SHORT_5_6_5;
-
-      if (format == MESA_FORMAT_B10G10R10A2_UNORM ||
-          format == MESA_FORMAT_B10G10R10X2_UNORM ||
-          format == MESA_FORMAT_R10G10B10A2_UNORM ||
-          format == MESA_FORMAT_R10G10B10X2_UNORM)
-         return GL_UNSIGNED_INT_2_10_10_10_REV;
-
-      switch (data_type) {
-      case GL_SIGNED_NORMALIZED:
-         return GL_BYTE;
-      case GL_UNSIGNED_INT:
-      case GL_INT:
-      case GL_FLOAT:
-         return data_type;
-      case GL_UNSIGNED_NORMALIZED:
-      default:
-         return GL_UNSIGNED_BYTE;
-      }
+      const mesa_format format = fb->_ColorReadBuffer->Format;
+      GLenum data_type;
+      GLuint comps;
+
+      _mesa_uncompressed_format_to_type_and_comps(format, &data_type, &comps);
+
+      return data_type;
    }
 }