mesa/objectlabel: don't do memcpy if bufSize is 0 (v2)
[mesa.git] / src / mesa / main / formatquery.c
index ac29bc80385354be88cb949b86ae16517f505cff..215c14f889fe131c1e350f1bf1d347e15e7a0a0a 100644 (file)
@@ -573,6 +573,34 @@ _is_internalformat_supported(struct gl_context *ctx, GLenum target,
    return (buffer[0] == GL_TRUE);
 }
 
+static bool
+_legal_target_for_framebuffer_texture_layer(struct gl_context *ctx,
+                                            GLenum target)
+{
+   switch (target) {
+   case GL_TEXTURE_3D:
+   case GL_TEXTURE_1D_ARRAY:
+   case GL_TEXTURE_2D_ARRAY:
+   case GL_TEXTURE_CUBE_MAP_ARRAY:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+   case GL_TEXTURE_CUBE_MAP:
+      return true;
+   default:
+      return false;
+   }
+}
+
+static GLenum
+_mesa_generic_type_for_internal_format(GLenum 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
+      return GL_FLOAT;
+}
+
 /* default implementation of QueryInternalFormat driverfunc, for
  * drivers not implementing ARB_internalformat_query2.
  */
@@ -581,9 +609,7 @@ _mesa_query_internal_format_default(struct gl_context *ctx, GLenum target,
                                     GLenum internalFormat, GLenum pname,
                                     GLint *params)
 {
-   (void) ctx;
    (void) target;
-   (void) internalFormat;
 
    switch (pname) {
    case GL_SAMPLES:
@@ -599,6 +625,52 @@ _mesa_query_internal_format_default(struct gl_context *ctx, GLenum target,
       params[0] = internalFormat;
       break;
 
+   case GL_READ_PIXELS_FORMAT: {
+      GLenum base_format = _mesa_base_tex_format(ctx, internalFormat);
+      switch (base_format) {
+      case GL_STENCIL_INDEX:
+      case GL_DEPTH_COMPONENT:
+      case GL_DEPTH_STENCIL:
+      case GL_RED:
+      case GL_RGB:
+      case GL_BGR:
+      case GL_RGBA:
+      case GL_BGRA:
+         params[0] = base_format;
+         break;
+      default:
+         params[0] = GL_NONE;
+         break;
+      }
+      break;
+   }
+
+   case GL_READ_PIXELS_TYPE:
+   case GL_TEXTURE_IMAGE_TYPE:
+   case GL_GET_TEXTURE_IMAGE_TYPE: {
+      GLenum base_format = _mesa_base_tex_format(ctx, internalFormat);
+      if (base_format > 0)
+         params[0] = _mesa_generic_type_for_internal_format(internalFormat);
+      else
+         params[0] = GL_NONE;
+      break;
+   }
+
+   case GL_TEXTURE_IMAGE_FORMAT:
+   case GL_GET_TEXTURE_IMAGE_FORMAT: {
+      GLenum format = GL_NONE;
+      GLenum base_format = _mesa_base_tex_format(ctx, internalFormat);
+      if (base_format > 0) {
+         if (_mesa_is_enum_format_integer(internalFormat))
+           format = _mesa_base_format_to_integer_format(base_format);
+         else
+           format = base_format;
+      }
+
+      params[0] = format;
+      break;
+   }
+
    case GL_MANUAL_GENERATE_MIPMAP:
    case GL_AUTO_GENERATE_MIPMAP:
    case GL_SRGB_READ:
@@ -619,6 +691,13 @@ _mesa_query_internal_format_default(struct gl_context *ctx, GLenum target,
    case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE:
    case GL_CLEAR_BUFFER:
    case GL_TEXTURE_VIEW:
+   case GL_TEXTURE_SHADOW:
+   case GL_TEXTURE_GATHER:
+   case GL_TEXTURE_GATHER_SHADOW:
+   case GL_FRAMEBUFFER_RENDERABLE:
+   case GL_FRAMEBUFFER_RENDERABLE_LAYERED:
+   case GL_FRAMEBUFFER_BLEND:
+   case GL_FILTER:
       params[0] = GL_FULL_SUPPORT;
       break;
 
@@ -1047,44 +1126,37 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
       buffer[0] = GL_TRUE;
       break;
 
+   case GL_FRAMEBUFFER_RENDERABLE_LAYERED:
+      if (!_mesa_has_EXT_texture_array(ctx) ||
+          _legal_target_for_framebuffer_texture_layer(ctx, target))
+         goto end;
+      /* fallthrough */
    case GL_FRAMEBUFFER_RENDERABLE:
-      /* @TODO */
-      break;
+   case GL_FRAMEBUFFER_BLEND:
+      if (!_mesa_has_ARB_framebuffer_object(ctx))
+         goto end;
 
-   case GL_FRAMEBUFFER_RENDERABLE_LAYERED:
-      /* @TODO */
-      break;
+      if (target == GL_TEXTURE_BUFFER ||
+          !_is_renderable(ctx, internalformat))
+         goto end;
 
-   case GL_FRAMEBUFFER_BLEND:
-      /* @TODO */
+      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
+                                      buffer);
       break;
 
    case GL_READ_PIXELS:
-      /* @TODO */
-      break;
-
    case GL_READ_PIXELS_FORMAT:
-      /* @TODO */
-      break;
-
    case GL_READ_PIXELS_TYPE:
-      /* @TODO */
+      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
+                                      buffer);
       break;
 
    case GL_TEXTURE_IMAGE_FORMAT:
-      /* @TODO */
-      break;
-
-   case GL_TEXTURE_IMAGE_TYPE:
-      /* @TODO */
-      break;
-
    case GL_GET_TEXTURE_IMAGE_FORMAT:
-      /* @TODO */
-      break;
-
+   case GL_TEXTURE_IMAGE_TYPE:
    case GL_GET_TEXTURE_IMAGE_TYPE:
-      /* @TODO */
+      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
+                                      buffer);
       break;
 
    case GL_MIPMAP:
@@ -1162,7 +1234,24 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
       break;
 
    case GL_FILTER:
-      /* @TODO */
+      /* If it doesn't allow to set sampler parameters then it would not allow
+       * to set a filter different to GL_NEAREST. In practice, this method
+       * only filters out MULTISAMPLE/MULTISAMPLE_ARRAY */
+      if (!_mesa_target_allows_setting_sampler_parameters(target))
+         goto end;
+
+      if (_mesa_is_enum_format_integer(internalformat))
+         goto end;
+
+      if (target == GL_TEXTURE_BUFFER)
+         goto end;
+
+      /* At this point we know that multi-texel filtering is supported. We
+       * need to call the driver to know if it is CAVEAT_SUPPORT or
+       * FULL_SUPPORT.
+       */
+      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
+                                      buffer);
       break;
 
    case GL_VERTEX_TEXTURE:
@@ -1189,16 +1278,42 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname,
                                       buffer);
       break;
 
+   case GL_TEXTURE_GATHER:
+   case GL_TEXTURE_GATHER_SHADOW:
+      if (!_mesa_has_ARB_texture_gather(ctx))
+         goto end;
+
+      /* fallthrough */
    case GL_TEXTURE_SHADOW:
-      /* @TODO */
-      break;
+      /* Only depth or depth-stencil image formats make sense in shadow
+         samplers */
+      if (pname != GL_TEXTURE_GATHER &&
+          !_mesa_is_depth_format(internalformat) &&
+          !_mesa_is_depthstencil_format(internalformat))
+         goto end;
 
-   case GL_TEXTURE_GATHER:
-      /* @TODO */
-      break;
+      /* Validate the target for shadow and gather operations */
+      switch (target) {
+      case GL_TEXTURE_2D:
+      case GL_TEXTURE_2D_ARRAY:
+      case GL_TEXTURE_CUBE_MAP:
+      case GL_TEXTURE_CUBE_MAP_ARRAY:
+      case GL_TEXTURE_RECTANGLE:
+         break;
 
-   case GL_TEXTURE_GATHER_SHADOW:
-      /* @TODO */
+      case GL_TEXTURE_1D:
+      case GL_TEXTURE_1D_ARRAY:
+         /* 1D and 1DArray textures are not admitted in gather operations */
+         if (pname != GL_TEXTURE_SHADOW)
+            goto end;
+         break;
+
+      default:
+         goto end;
+      }
+
+      ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname,
+                                      buffer);
       break;
 
    case GL_SHADER_IMAGE_LOAD: