mesa/formatquery: Added INTERNALFORMAT_{X}_{SIZE,TYPE} <pname> queries
authorAntia Puentes <apuentes@igalia.com>
Sat, 19 Dec 2015 16:21:21 +0000 (17:21 +0100)
committerEduardo Lima Mitev <elima@igalia.com>
Thu, 3 Mar 2016 14:14:06 +0000 (15:14 +0100)
From the ARB_internalformat_query2 spec:

   "- INTERNALFORMAT_RED_SIZE
    - INTERNALFORMAT_GREEN_SIZE
    - INTERNALFORMAT_BLUE_SIZE
    - INTERNALFORMAT_ALPHA_SIZE
    - INTERNALFORMAT_DEPTH_SIZE
    - INTERNALFORMAT_STENCIL_SIZE
    - INTERNALFORMAT_SHARED_SIZE
      For uncompressed internal formats, queries of these values return the
      actual resolutions that would be used for storing image array components
      for the resource.
      For compressed internal formats, the resolutions returned specify the
      component resolution of an uncompressed internal format that produces
      an image of roughly the same quality as the compressed algorithm.
      For textures this query will return the same information as querying
      GetTexLevelParameter{if}v for TEXTURE_*_SIZE would return.
      If the internal format is unsupported, or if a particular component is
      not present in the format, 0 is written to <params>.

    - INTERNALFORMAT_RED_TYPE
    - INTERNALFORMAT_GREEN_TYPE
    - INTERNALFORMAT_BLUE_TYPE
    - INTERNALFORMAT_ALPHA_TYPE
    - INTERNALFORMAT_DEPTH_TYPE
    - INTERNALFORMAT_STENCIL_TYPE
      For uncompressed internal formats, queries for these values return the
      data type used to store the component.
      For compressed internal formats the types returned specify how components
      are interpreted after decompression.
      For textures this query returns the same information as querying
      GetTexLevelParameter{if}v for TEXTURE_*TYPE would return.
      Possible values return include, NONE, SIGNED_NORMALIZED,
      UNSIGNED_NORMALIZED, FLOAT, INT, UNSIGNED_INT, representing missing,
      signed normalized fixed point, unsigned normalized fixed point,
      floating-point, signed unnormalized integer and unsigned unnormalized
      integer components. NONE is returned for all component types if the
      format is unsupported."

Reviewed-by: Dave Airlie <airlied@redhat.com>
src/mesa/main/formatquery.c

index 2037e84..0beb1a7 100644 (file)
@@ -29,6 +29,7 @@
 #include "fbobject.h"
 #include "formatquery.h"
 #include "teximage.h"
+#include "texparam.h"
 
 static bool
 _is_renderable(struct gl_context *ctx, GLenum internalformat)
@@ -682,56 +683,90 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
       break;
 
    case GL_INTERNALFORMAT_RED_SIZE:
-      /* @TODO */
-      break;
-
    case GL_INTERNALFORMAT_GREEN_SIZE:
-      /* @TODO */
-      break;
-
    case GL_INTERNALFORMAT_BLUE_SIZE:
-      /* @TODO */
-      break;
-
    case GL_INTERNALFORMAT_ALPHA_SIZE:
-      /* @TODO */
-      break;
-
    case GL_INTERNALFORMAT_DEPTH_SIZE:
-      /* @TODO */
-      break;
-
    case GL_INTERNALFORMAT_STENCIL_SIZE:
-      /* @TODO */
-      break;
-
    case GL_INTERNALFORMAT_SHARED_SIZE:
-      /* @TODO */
-      break;
-
    case GL_INTERNALFORMAT_RED_TYPE:
-      /* @TODO */
-      break;
-
    case GL_INTERNALFORMAT_GREEN_TYPE:
-      /* @TODO */
-      break;
-
    case GL_INTERNALFORMAT_BLUE_TYPE:
-      /* @TODO */
-      break;
-
    case GL_INTERNALFORMAT_ALPHA_TYPE:
-      /* @TODO */
-      break;
-
    case GL_INTERNALFORMAT_DEPTH_TYPE:
-      /* @TODO */
-      break;
+   case GL_INTERNALFORMAT_STENCIL_TYPE: {
+      GLint baseformat;
+      mesa_format texformat;
 
-   case GL_INTERNALFORMAT_STENCIL_TYPE:
-      /* @TODO */
+      if (target != GL_RENDERBUFFER) {
+         if (!_mesa_legal_get_tex_level_parameter_target(ctx, target, true))
+            goto end;
+
+         baseformat = _mesa_base_tex_format(ctx, internalformat);
+      } else {
+         baseformat = _mesa_base_fbo_format(ctx, internalformat);
+      }
+
+      /* Let the driver choose the texture format.
+       *
+       * Disclaimer: I am considering that drivers use for renderbuffers the
+       * same format-choice logic as for textures.
+       */
+      texformat = ctx->Driver.ChooseTextureFormat(ctx, target, internalformat,
+                                                  GL_NONE /*format */, GL_NONE /* type */);
+
+      if (texformat == MESA_FORMAT_NONE || baseformat <= 0)
+         goto end;
+
+      /* Implementation based on what Mesa does for glGetTexLevelParameteriv
+       * and glGetRenderbufferParameteriv functions.
+       */
+      if (pname == GL_INTERNALFORMAT_SHARED_SIZE) {
+         if (_mesa_has_EXT_texture_shared_exponent(ctx) &&
+             target != GL_TEXTURE_BUFFER &&
+             target != GL_RENDERBUFFER &&
+             texformat == MESA_FORMAT_R9G9B9E5_FLOAT) {
+            buffer[0] = 5;
+         }
+         goto end;
+      }
+
+      if (!_mesa_base_format_has_channel(baseformat, pname))
+         goto end;
+
+      switch (pname) {
+      case GL_INTERNALFORMAT_DEPTH_SIZE:
+         if (!_mesa_has_ARB_depth_texture(ctx) &&
+             target != GL_RENDERBUFFER &&
+             target != GL_TEXTURE_BUFFER)
+            goto end;
+         /* fallthrough */
+      case GL_INTERNALFORMAT_RED_SIZE:
+      case GL_INTERNALFORMAT_GREEN_SIZE:
+      case GL_INTERNALFORMAT_BLUE_SIZE:
+      case GL_INTERNALFORMAT_ALPHA_SIZE:
+      case GL_INTERNALFORMAT_STENCIL_SIZE:
+         buffer[0] = _mesa_get_format_bits(texformat, pname);
+         break;
+
+      case GL_INTERNALFORMAT_DEPTH_TYPE:
+         if (!_mesa_has_ARB_texture_float(ctx))
+            goto end;
+         /* fallthrough */
+      case GL_INTERNALFORMAT_RED_TYPE:
+      case GL_INTERNALFORMAT_GREEN_TYPE:
+      case GL_INTERNALFORMAT_BLUE_TYPE:
+      case GL_INTERNALFORMAT_ALPHA_TYPE:
+      case GL_INTERNALFORMAT_STENCIL_TYPE:
+         buffer[0]  = _mesa_get_format_datatype(texformat);
+         break;
+
+      default:
+         break;
+
+      }
       break;
+   }
 
    case GL_MAX_WIDTH:
       /* @TODO */