mesa: Add GL API support for ARB_copy_image
authorJason Ekstrand <jason.ekstrand@intel.com>
Fri, 27 Jun 2014 22:34:53 +0000 (15:34 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Mon, 11 Aug 2014 18:20:23 +0000 (11:20 -0700)
This adds the API entrypoint, error checking logic, and a driver hook for
the ARB_copy_image extension.

v2: Fix a typo in ARB_copy_image.xml and add it to the makefile
v3: Put ARB_copy_image.xml in the right place alphebetically in the
    makefile and properly prefix the commit message
v4: Fixed some line wrapping and added a check for null
v5: Check for incomplete renderbuffers

Signed-off-by: Jason Ekstrand <jason.ekstrand@intel.com>
Reviewed-by: Juha-Pekka Heikkila <juhapekka.heikkila@gmail.com>
Reviewed-by: Neil Roberts <neil@linux.intel.com>
v6: Update dispatch_sanity for the addition of CopyImageSubData

13 files changed:
src/mapi/glapi/gen/ARB_copy_image.xml [new file with mode: 0644]
src/mapi/glapi/gen/Makefile.am
src/mapi/glapi/gen/gl_API.xml
src/mapi/glapi/gen/gl_genexec.py
src/mesa/Makefile.sources
src/mesa/main/copyimage.c [new file with mode: 0644]
src/mesa/main/copyimage.h [new file with mode: 0644]
src/mesa/main/dd.h
src/mesa/main/extensions.c
src/mesa/main/mtypes.h
src/mesa/main/tests/dispatch_sanity.cpp
src/mesa/main/textureview.c
src/mesa/main/textureview.h

diff --git a/src/mapi/glapi/gen/ARB_copy_image.xml b/src/mapi/glapi/gen/ARB_copy_image.xml
new file mode 100644 (file)
index 0000000..2fbd845
--- /dev/null
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="GL_ARB_copy_image" number="123">
+
+    <function name="CopyImageSubData" offset="assign">
+        <param name="srcName" type="GLuint"/>
+        <param name="srcTarget" type="GLenum"/>
+        <param name="srcLevel" type="GLint"/>
+        <param name="srcX" type="GLint"/>
+        <param name="srcY" type="GLint"/>
+        <param name="srcZ" type="GLint"/>
+        <param name="dstName" type="GLuint"/>
+        <param name="dstTarget" type="GLenum"/>
+        <param name="dstLevel" type="GLint"/>
+        <param name="dstX" type="GLint"/>
+        <param name="dstY" type="GLint"/>
+        <param name="dstZ" type="GLint"/>
+        <param name="srcWidth" type="GLsizei"/>
+        <param name="srcHeight" type="GLsizei"/>
+        <param name="srcDepth" type="GLsizei"/>
+    </function>
+
+</category>
+
+</OpenGLAPI>
index 212731fa4042dc16ed896dc3543da109ed295f1c..645def4ef5c669f72ceaa5e0b1cb24ec87622d30 100644 (file)
@@ -117,6 +117,7 @@ API_XML = \
        ARB_compressed_texture_pixel_storage.xml \
        ARB_compute_shader.xml \
        ARB_copy_buffer.xml \
+       ARB_copy_image.xml \
        ARB_debug_output.xml \
        ARB_depth_buffer_float.xml \
        ARB_depth_clamp.xml \
index e011509e5386d81c217230c45a19278aa52723e4..619717d9e9ec3bbae96d6ea047d7818ec8a8b91a 100644 (file)
 
 <xi:include href="ARB_compute_shader.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
 
-<!-- ARB extension #123 -->
+<xi:include href="ARB_copy_image.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
 
 <xi:include href="ARB_texture_view.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
 
index 4609193977d428ba149cc0a8aed6bccfeeb88088..d479e66da037841a8f27d5752f179ede5f9ab2df 100644 (file)
@@ -62,6 +62,7 @@ header = """/**
 #include "main/condrender.h"
 #include "main/context.h"
 #include "main/convolve.h"
+#include "main/copyimage.h"
 #include "main/depth.h"
 #include "main/dlist.h"
 #include "main/drawpix.h"
index 45c53ca0e0e14870067a1f11f83fa2c8fb2eb62e..d02c174d9126a54e2a0466f826a06d87b661be49 100644 (file)
@@ -31,6 +31,7 @@ MAIN_FILES = \
        $(SRCDIR)main/condrender.c \
        $(SRCDIR)main/context.c \
        $(SRCDIR)main/convolve.c \
+       $(SRCDIR)main/copyimage.c \
        $(SRCDIR)main/cpuinfo.c \
        $(SRCDIR)main/debug.c \
        $(SRCDIR)main/depth.c \
diff --git a/src/mesa/main/copyimage.c b/src/mesa/main/copyimage.c
new file mode 100644 (file)
index 0000000..e1110dd
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2014 Intel Corporation.  All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Jason Ekstrand <jason.ekstrand@intel.com>
+ */
+
+#include "glheader.h"
+#include "errors.h"
+#include "enums.h"
+#include "copyimage.h"
+#include "teximage.h"
+#include "texobj.h"
+#include "fbobject.h"
+#include "textureview.h"
+
+static bool
+prepare_target(struct gl_context *ctx, GLuint name, GLenum *target, int level,
+               struct gl_texture_object **tex_obj,
+               struct gl_texture_image **tex_image, GLuint *tmp_tex,
+               const char *dbg_prefix)
+{
+   struct gl_renderbuffer *rb;
+
+   if (name == 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCopyImageSubData(%sName = %d)", dbg_prefix, name);
+      return false;
+   }
+
+   /*
+    * INVALID_ENUM is generated
+    *  * if either <srcTarget> or <dstTarget>
+    *   - is not RENDERBUFFER or a valid non-proxy texture target
+    *   - is TEXTURE_BUFFER, or
+    *   - is one of the cubemap face selectors described in table 3.17,
+    */
+   switch (*target) {
+   case GL_RENDERBUFFER:
+      /* Not a texture target, but valid */
+   case GL_TEXTURE_1D:
+   case GL_TEXTURE_1D_ARRAY:
+   case GL_TEXTURE_2D:
+   case GL_TEXTURE_3D:
+   case GL_TEXTURE_CUBE_MAP:
+   case GL_TEXTURE_RECTANGLE:
+   case GL_TEXTURE_2D_ARRAY:
+   case GL_TEXTURE_CUBE_MAP_ARRAY:
+   case GL_TEXTURE_2D_MULTISAMPLE:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+      /* These are all valid */
+      break;
+   case GL_TEXTURE_EXTERNAL_OES:
+      /* Only exists in ES */
+   case GL_TEXTURE_BUFFER:
+   default:
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glCopyImageSubData(%sTarget = %s)", dbg_prefix,
+                  _mesa_lookup_enum_by_nr(*target));
+      return false;
+   }
+
+   if (*target == GL_RENDERBUFFER) {
+      rb = _mesa_lookup_renderbuffer(ctx, name);
+      if (!rb) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glCopyImageSubData(%sName = %u)", dbg_prefix, name);
+         return false;
+      }
+
+      if (!rb->Name) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glCopyImageSubData(%sName incomplete)", dbg_prefix);
+         return false;
+      }
+
+      if (level != 0) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glCopyImageSubData(%sLevel = %u)", dbg_prefix, level);
+         return false;
+      }
+
+      if (rb->NumSamples > 1)
+         *target = GL_TEXTURE_2D_MULTISAMPLE;
+      else
+         *target = GL_TEXTURE_2D;
+
+      *tmp_tex = 0;
+      _mesa_GenTextures(1, tmp_tex);
+      if (*tmp_tex == 0)
+         return false; /* Error already set by GenTextures */
+
+      _mesa_BindTexture(*target, *tmp_tex);
+      *tex_obj = _mesa_lookup_texture(ctx, *tmp_tex);
+      *tex_image = _mesa_get_tex_image(ctx, *tex_obj, *target, 0);
+
+      if (!ctx->Driver.BindRenderbufferTexImage(ctx, rb, *tex_image)) {
+         _mesa_problem(ctx, "Failed to create texture from renderbuffer");
+         return false;
+      }
+
+      if (ctx->Driver.FinishRenderTexture && !rb->NeedsFinishRenderTexture) {
+         rb->NeedsFinishRenderTexture = true;
+         ctx->Driver.FinishRenderTexture(ctx, rb);
+      }
+   } else {
+      *tex_obj = _mesa_lookup_texture(ctx, name);
+      if (!*tex_obj) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glCopyImageSubData(%sName = %u)", dbg_prefix, name);
+         return false;
+      }
+
+      _mesa_test_texobj_completeness(ctx, *tex_obj);
+      if (!(*tex_obj)->_BaseComplete ||
+          (level != 0 && !(*tex_obj)->_MipmapComplete)) {
+         _mesa_error(ctx, GL_INVALID_OPERATION,
+                     "glCopyImageSubData(%sName incomplete)", dbg_prefix);
+         return false;
+      }
+
+      if ((*tex_obj)->Target != *target) {
+         _mesa_error(ctx, GL_INVALID_ENUM,
+                     "glCopyImageSubData(%sTarget = %s)", dbg_prefix,
+                     _mesa_lookup_enum_by_nr(*target));
+         return false;
+      }
+
+      if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glCopyImageSubData(%sLevel = %d)", dbg_prefix, level);
+         return false;
+      }
+
+      *tex_image = _mesa_select_tex_image(ctx, *tex_obj, *target, level);
+      if (!*tex_image) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glCopyImageSubData(%sLevel = %u)", dbg_prefix, level);
+         return false;
+      }
+   }
+
+   return true;
+}
+
+static bool
+check_region_bounds(struct gl_context *ctx, struct gl_texture_image *tex_image,
+                    int x, int y, int z, int width, int height, int depth,
+                    const char *dbg_prefix)
+{
+   if (width < 0 || height < 0 || depth < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCopyImageSubData(%sWidth, %sHeight, or %sDepth is negative)",
+                  dbg_prefix, dbg_prefix, dbg_prefix);
+      return false;
+   }
+
+   if (x < 0 || y < 0 || z < 0) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCopyImageSubData(%sX, %sY, or %sZ is negative)",
+                  dbg_prefix, dbg_prefix, dbg_prefix);
+      return false;
+   }
+
+   if (x + width > tex_image->Width) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCopyImageSubData(%sX or %sWidth exceeds image bounds)",
+                  dbg_prefix, dbg_prefix);
+      return false;
+   }
+
+   switch (tex_image->TexObject->Target) {
+   case GL_TEXTURE_1D:
+   case GL_TEXTURE_1D_ARRAY:
+      if (y != 0 || height != 1) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glCopyImageSubData(%sY or %sHeight exceeds image bounds)",
+                     dbg_prefix, dbg_prefix);
+         return false;
+      }
+      break;
+   default:
+      if (y + height > tex_image->Height) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glCopyImageSubData(%sY or %sHeight exceeds image bounds)",
+                     dbg_prefix, dbg_prefix);
+         return false;
+      }
+      break;
+   }
+
+   switch (tex_image->TexObject->Target) {
+   case GL_TEXTURE_1D:
+   case GL_TEXTURE_2D:
+   case GL_TEXTURE_2D_MULTISAMPLE:
+   case GL_TEXTURE_RECTANGLE:
+      if (z != 0 || depth != 1) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glCopyImageSubData(%sZ or %sDepth exceeds image bounds)",
+                     dbg_prefix, dbg_prefix);
+         return false;
+      }
+      break;
+   case GL_TEXTURE_CUBE_MAP:
+      if (z < 0 || z + depth > 6) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glCopyImageSubData(%sZ or %sDepth exceeds image bounds)",
+                     dbg_prefix, dbg_prefix);
+         return false;
+      }
+      break;
+   case GL_TEXTURE_1D_ARRAY:
+      if (z < 0 || z + depth > tex_image->Height) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glCopyImageSubData(%sZ or %sDepth exceeds image bounds)",
+                     dbg_prefix, dbg_prefix);
+         return false;
+      }
+      break;
+   case GL_TEXTURE_CUBE_MAP_ARRAY:
+   case GL_TEXTURE_2D_ARRAY:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+   case GL_TEXTURE_3D:
+      if (z < 0 || z + depth > tex_image->Depth) {
+         _mesa_error(ctx, GL_INVALID_VALUE,
+                     "glCopyImageSubData(%sZ or %sDepth exceeds image bounds)",
+                     dbg_prefix, dbg_prefix);
+         return false;
+      }
+      break;
+   }
+
+   return true;
+}
+
+void
+_mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel,
+                       GLint srcX, GLint srcY, GLint srcZ,
+                       GLuint dstName, GLenum dstTarget, GLint dstLevel,
+                       GLint dstX, GLint dstY, GLint dstZ,
+                       GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)
+{
+   GET_CURRENT_CONTEXT(ctx);
+   GLuint tmpTexNames[2] = { 0, 0 };
+   struct gl_texture_object *srcTexObj, *dstTexObj;
+   struct gl_texture_image *srcTexImage, *dstTexImage;
+   GLuint src_bw, src_bh, dst_bw, dst_bh;
+   int i, srcNewZ, dstNewZ, Bpt;
+
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glCopyImageSubData(%u, %s, %d, %d, %d, %d, "
+                                          "%u, %s, %d, %d, %d, %d, "
+                                          "%d, %d, %d)\n",
+                  srcName, _mesa_lookup_enum_by_nr(srcTarget), srcLevel,
+                  srcX, srcY, srcZ,
+                  dstName, _mesa_lookup_enum_by_nr(dstTarget), dstLevel,
+                  dstX, dstY, dstZ,
+                  srcWidth, srcHeight, srcWidth);
+
+   if (!prepare_target(ctx, srcName, &srcTarget, srcLevel,
+                       &srcTexObj, &srcTexImage, &tmpTexNames[0], "src"))
+      goto cleanup;
+
+   if (!prepare_target(ctx, dstName, &dstTarget, dstLevel,
+                       &dstTexObj, &dstTexImage, &tmpTexNames[1], "dst"))
+      goto cleanup;
+
+   _mesa_get_format_block_size(srcTexImage->TexFormat, &src_bw, &src_bh);
+   if ((srcX % src_bw != 0) || (srcY % src_bh != 0) ||
+       (srcWidth % src_bw != 0) || (srcHeight % src_bh != 0)) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCopyImageSubData(unaligned src rectangle)");
+      goto cleanup;
+   }
+
+   _mesa_get_format_block_size(dstTexImage->TexFormat, &dst_bw, &dst_bh);
+   if ((dstX % dst_bw != 0) || (dstY % dst_bh != 0)) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCopyImageSubData(unaligned dst rectangle)");
+      goto cleanup;
+   }
+
+   /* Very simple sanity check.  This is sufficient if one of the textures
+    * is compressed. */
+   Bpt = _mesa_get_format_bytes(srcTexImage->TexFormat);
+   if (_mesa_get_format_bytes(dstTexImage->TexFormat) != Bpt) {
+      _mesa_error(ctx, GL_INVALID_VALUE,
+                  "glCopyImageSubData(internalFormat mismatch)");
+      goto cleanup;
+   }
+
+   if (!check_region_bounds(ctx, srcTexImage, srcX, srcY, srcZ,
+                            srcWidth, srcHeight, srcDepth, "src"))
+      goto cleanup;
+
+   if (!check_region_bounds(ctx, dstTexImage, dstX, dstY, dstZ,
+                            (srcWidth / src_bw) * dst_bw,
+                            (srcHeight / src_bh) * dst_bh, srcDepth, "dst"))
+      goto cleanup;
+
+   if (_mesa_is_format_compressed(srcTexImage->TexFormat)) {
+      /* XXX: Technically, we should probaby do some more specific checking
+       * here.  However, this should be sufficient for all compressed
+       * formats that mesa supports since it is a direct memory copy.
+       */
+   } else if (_mesa_is_format_compressed(dstTexImage->TexFormat)) {
+   } else if (_mesa_texture_view_compatible_format(ctx,
+                                                   srcTexImage->InternalFormat,
+                                                   dstTexImage->InternalFormat)) {
+   } else {
+      return; /* Error loged by _mesa_texture_view_compatible_format */
+   }
+
+   for (i = 0; i < srcDepth; ++i) {
+      if (srcTexObj->Target == GL_TEXTURE_CUBE_MAP) {
+         srcTexImage = srcTexObj->Image[i + srcZ][srcLevel];
+         srcNewZ = 0;
+      } else {
+         srcNewZ = srcZ + i;
+      }
+
+      if (dstTexObj->Target == GL_TEXTURE_CUBE_MAP) {
+         dstTexImage = dstTexObj->Image[i + dstZ][dstLevel];
+         dstNewZ = 0;
+      } else {
+         dstNewZ = dstZ + i;
+      }
+
+      ctx->Driver.CopyImageSubData(ctx, srcTexImage, srcX, srcY, srcNewZ,
+                                   dstTexImage, dstX, dstY, dstNewZ,
+                                   srcWidth, srcHeight);
+   }
+
+cleanup:
+   _mesa_DeleteTextures(2, tmpTexNames);
+}
diff --git a/src/mesa/main/copyimage.h b/src/mesa/main/copyimage.h
new file mode 100644 (file)
index 0000000..40e95b6
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2014 Intel Corporation.  All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Jason Ekstrand <jason.ekstrand@intel.com>
+ */
+
+
+#ifndef COPYIMAGE_H
+#define COPYIMAGE_H
+
+#include "mtypes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void GLAPIENTRY
+_mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel,
+                       GLint srcX, GLint srcY, GLint srcZ,
+                       GLuint destName, GLenum destTarget, GLint destLevel,
+                       GLint destX, GLint destY, GLint destZ,
+                       GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* COPYIMAGE_H */
index 89765351e14d39c9c9bb55372718122f3962685d..c130b14a52298feedd821d218056c70be5b5ba54 100644 (file)
@@ -268,6 +268,22 @@ struct dd_function_table {
                            GLint x, GLint y,
                            GLsizei width, GLsizei height);
 
+   /**
+    * Called by glCopyImageSubData().
+    *
+    * This function should copy one 2-D slice from srcTexImage to
+    * dstTexImage.  If one of the textures is 3-D or is a 1-D or 2-D array
+    * texture, this function will be called multiple times: once for each
+    * slice.  If one of the textures is a cube map, this function will be
+    * called once for each face to be copied.
+    */
+   void (*CopyImageSubData)(struct gl_context *ctx,
+                            struct gl_texture_image *src_image,
+                            int src_x, int src_y, int src_z,
+                            struct gl_texture_image *dstTexImage,
+                            int dst_x, int dst_y, int dst_z,
+                            int src_width, int src_height);
+
    /**
     * Called by glGenerateMipmap() or when GL_GENERATE_MIPMAP_SGIS is enabled.
     * Note that if the texture is a cube map, the <target> parameter will
index 9ac8377a475b526f4459ba3e5b60644d8577d3c6..d60838a1ce79599d5899708bc020ebd908f85414 100644 (file)
@@ -95,6 +95,7 @@ static const struct extension extension_table[] = {
    { "GL_ARB_compressed_texture_pixel_storage",    o(dummy_true),                              GL,             2011 },
    { "GL_ARB_compute_shader",                      o(ARB_compute_shader),                      GL,             2012 },
    { "GL_ARB_copy_buffer",                         o(dummy_true),                              GL,             2008 },
+   { "GL_ARB_copy_image",                          o(ARB_copy_image),                          GL,             2012 },
    { "GL_ARB_conservative_depth",                  o(ARB_conservative_depth),                  GL,             2011 },
    { "GL_ARB_debug_output",                        o(dummy_true),                              GL,             2009 },
    { "GL_ARB_depth_buffer_float",                  o(ARB_depth_buffer_float),                  GL,             2008 },
index ff130da15d0eb924dab985d896e0d61872d092f1..e141ac658930a1a07d5b7b6d24ca428834efcb9f 100644 (file)
@@ -3552,6 +3552,7 @@ struct gl_extensions
    GLboolean ARB_color_buffer_float;
    GLboolean ARB_compute_shader;
    GLboolean ARB_conservative_depth;
+   GLboolean ARB_copy_image;
    GLboolean ARB_depth_buffer_float;
    GLboolean ARB_depth_clamp;
    GLboolean ARB_depth_texture;
index 5e751f493fff759966ae6bf589ee40ca2b2982ee..04fa86b72dbb3ec6a08724304665215d40e3d872 100644 (file)
@@ -838,7 +838,7 @@ const struct function gl_core_functions_possible[] = {
 // { "glClearNamedBufferSubDataEXT", 43, -1 },          // XXX: Add to xml
    { "glDispatchCompute", 43, -1 },
    { "glDispatchComputeIndirect", 43, -1 },
-// { "glCopyImageSubData", 43, -1 },                    // XXX: Add to xml
+   { "glCopyImageSubData", 43, -1 },
    { "glTextureView", 43, -1 },
    { "glBindVertexBuffer", 43, -1 },
    { "glVertexAttribFormat", 43, -1 },
index 77a3b782b5af036a6220e351437747311a388cd7..b3521e2190e30ab1002b0c115a396962fe790e14 100644 (file)
@@ -320,15 +320,11 @@ target_valid(struct gl_context *ctx, GLenum origTarget, GLenum newTarget)
  * If an error is found, record it with _mesa_error()
  * \return false if any error, true otherwise.
  */
-static bool
-compatible_format(struct gl_context *ctx, const struct gl_texture_object *origTexObj,
-                  GLenum internalformat)
+GLboolean
+_mesa_texture_view_compatible_format(struct gl_context *ctx,
+                                     GLenum origInternalFormat,
+                                     GLenum newInternalFormat)
 {
-   /* Level 0 of a texture created by glTextureStorage or glTextureView
-    * is always defined.
-    */
-   struct gl_texture_image *texImage = origTexObj->Image[0][0];
-   GLint origInternalFormat = texImage->InternalFormat;
    unsigned int origViewClass, newViewClass;
 
    /* The two textures' internal formats must be compatible according to
@@ -337,19 +333,15 @@ compatible_format(struct gl_context *ctx, const struct gl_texture_object *origTe
     * The internal formats must be identical if not in that table,
     * or an INVALID_OPERATION error is generated.
     */
-   if (origInternalFormat == internalformat)
-      return true;
+   if (origInternalFormat == newInternalFormat)
+      return GL_TRUE;
 
    origViewClass = lookup_view_class(ctx, origInternalFormat);
-   newViewClass = lookup_view_class(ctx, internalformat);
+   newViewClass = lookup_view_class(ctx, newInternalFormat);
    if ((origViewClass == newViewClass) && origViewClass != false)
-      return true;
+      return GL_TRUE;
 
-   _mesa_error(ctx, GL_INVALID_OPERATION,
-               "glTextureView(internalformat %s not compatible with origtexture %s)",
-               _mesa_lookup_enum_by_nr(internalformat),
-               _mesa_lookup_enum_by_nr(origInternalFormat));
-   return false;
+   return GL_FALSE;
 }
 /**
  * Helper function for TexStorage and teximagemultisample to set immutable
@@ -512,8 +504,14 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,
       return;
    }
 
-   if (!compatible_format(ctx, origTexObj, internalformat)) {
-      return; /* Error logged */
+   if (!_mesa_texture_view_compatible_format(ctx,
+                                             origTexObj->Image[0][0]->InternalFormat,
+                                             internalformat)) {
+      _mesa_error(ctx, GL_INVALID_OPERATION,
+                  "glTextureView(internalformat %s not compatible with origtexture %s)",
+                  _mesa_lookup_enum_by_nr(internalformat),
+                  _mesa_lookup_enum_by_nr(origTexObj->Image[0][0]->InternalFormat));
+      return;
    }
 
    texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,
index 3088ac19393b3b25d1d6fc8621ff0129710e3fee..549a13cd809fda8d0326c4e6a27b6d1d834b36d0 100644 (file)
 #ifndef TEXTUREVIEW_H
 #define TEXTUREVIEW_H
 
+GLboolean
+_mesa_texture_view_compatible_format(struct gl_context *ctx,
+                                     GLenum origInternalFormat,
+                                     GLenum newInternalFormat);
 
 extern void GLAPIENTRY
 _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,