[Mesa-dev] [PATCH v2 64/65] i965/formatquery: Add support for INTERNALFORMAT_PREFERRED query

Eduardo Lima Mitev elima at igalia.com
Tue Feb 23 08:44:50 UTC 2016


This pname is tricky. The spec states that an internal format should be
returned, that is compatible with the passed internal format, and has
at least the same precision. There is no clear API to resolve this.

The closest we have (and what other drivers (i.e, NVidia proprietary) do,
is to return the same internal format given as parameter. But we validate
first that the passed internal format is supported by i965.

To check for support, we have the TextureFormatSupported map'. But
this map expects a 'mesa_format', which takes a format+typen. So, we must
first "come up" with a generic type that is suited for this internal format,
then get a mesa_format, and then do the validation.

The cleanest solution here is to add a method that does exactly what
the spec wants: a driver's preferred internal format from a given
internal format. But at this point we lack a clear view of what
defines this preference, and also there seems to be no API for it.

v1: Updated to include missing DEPTH/STENCIL formats in
    get_generic_type_for_internal_format()

---
 src/mesa/drivers/dri/i965/brw_formatquery.c | 73 +++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/src/mesa/drivers/dri/i965/brw_formatquery.c b/src/mesa/drivers/dri/i965/brw_formatquery.c
index 1bd212c..57c6148 100644
--- a/src/mesa/drivers/dri/i965/brw_formatquery.c
+++ b/src/mesa/drivers/dri/i965/brw_formatquery.c
@@ -22,7 +22,9 @@
  */
 
 #include "brw_context.h"
+#include "brw_state.h"
 #include "main/formatquery.h"
+#include "main/glformats.h"
 
 static size_t
 brw_query_samples_for_format(struct gl_context *ctx, GLenum target,
@@ -63,6 +65,46 @@ brw_query_samples_for_format(struct gl_context *ctx, GLenum target,
    }
 }
 
+/**
+ * Returns a generic GL type from an internal format, so that it can be used
+ * together with the base format to obtain a mesa_format by calling
+ * mesa_format_from_format_and_type().
+ */
+static GLenum
+get_generic_type_for_internal_format(GLenum internalFormat)
+{
+   if (_mesa_is_color_format(internalFormat)) {
+      if (_mesa_is_enum_format_unsigned_int(internalFormat))
+         return GL_UNSIGNED_BYTE;
+      else if (_mesa_is_enum_format_signed_int(internalFormat))
+         return GL_BYTE;
+   } else {
+      switch (internalFormat) {
+      case GL_STENCIL_INDEX:
+      case GL_STENCIL_INDEX8:
+         return GL_UNSIGNED_BYTE;
+      case GL_DEPTH_COMPONENT:
+      case GL_DEPTH_COMPONENT16:
+         return GL_UNSIGNED_SHORT;
+      case GL_DEPTH_COMPONENT24:
+      case GL_DEPTH_COMPONENT32:
+         return GL_UNSIGNED_INT;
+      case GL_DEPTH_COMPONENT32F:
+         return GL_FLOAT;
+      case GL_DEPTH_STENCIL:
+      case GL_DEPTH24_STENCIL8:
+         return GL_UNSIGNED_INT_24_8;
+      case GL_DEPTH32F_STENCIL8:
+         return GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
+      default:
+         /* fall-through */
+         break;
+      }
+   }
+
+   return GL_FLOAT;
+}
+
 void
 brw_query_internal_format(struct gl_context *ctx, GLenum target,
                           GLenum internalFormat, GLenum pname, GLint *params)
@@ -85,6 +127,37 @@ brw_query_internal_format(struct gl_context *ctx, GLenum target,
       break;
    }
 
+   case GL_INTERNALFORMAT_PREFERRED: {
+      params[0] = GL_NONE;
+
+      /* We need to resolve an internal format that is compatible with
+       * the passed internal format, and optimal to the driver. By now,
+       * we just validate that the passed internal format is supported by
+       * the driver, and if so return the same internal format, otherwise
+       * return GL_NONE.
+       *
+       * For validating the internal format, we use the
+       * ctx->TextureFormatSupported map to check that a BRW surface format
+       * exists, that can be derived from the internal format. But this
+       * expects a mesa_format, not an internal format. So we need to "come up"
+       * with a type that is generic enough, to resolve the mesa_format first.
+       */
+      GLenum type = get_generic_type_for_internal_format(internalFormat);
+
+      /* Get a mesa_format from the internal format and type. */
+      GLint base_format = _mesa_base_tex_format(ctx, internalFormat);
+      if (base_format != -1) {
+         mesa_format mesa_format =
+            _mesa_format_from_format_and_type(base_format, type);
+
+         if (mesa_format < MESA_FORMAT_COUNT &&
+             ctx->TextureFormatSupported[mesa_format]) {
+            params[0] = internalFormat;
+         }
+      }
+      break;
+   }
+
    default:
       /* By default, we call the driver hook's fallback function from the frontend,
        * which has generic implementation for all pnames.
-- 
2.5.3



More information about the mesa-dev mailing list