<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Aug 1, 2014 at 2:56 AM, Juha-Pekka Heikkila <span dir="ltr"><<a href="mailto:juhapekka.heikkila@gmail.com" target="_blank">juhapekka.heikkila@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On 01.08.2014 06:39, Jason Ekstrand wrote:<br>
> This adds the API entrypoint, error checking logic, and a driver hook for<br>
> the ARB_copy_image extension.<br>
><br>
> v2: Fix a typo in ARB_copy_image.xml and add it to the makefile<br>
> v3: Put ARB_copy_image.xml in the right place alphebetically in the makefile and update the commit message<br>
><br>
> Signed-off-by: Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com">jason.ekstrand@intel.com</a>><br>
> ---<br>
>  src/mapi/glapi/gen/ARB_copy_image.xml |  28 +++<br>
>  src/mapi/glapi/gen/Makefile.am        |   1 +<br>
>  src/mapi/glapi/gen/gl_API.xml         |   2 +-<br>
>  src/mapi/glapi/gen/gl_genexec.py      |   1 +<br>
>  src/mesa/Makefile.sources             |   1 +<br>
>  src/mesa/main/copyimage.c             | 341 ++++++++++++++++++++++++++++++++++<br>
>  src/mesa/main/copyimage.h             |  49 +++++<br>
>  src/mesa/main/dd.h                    |  16 ++<br>
>  src/mesa/main/extensions.c            |   1 +<br>
>  src/mesa/main/mtypes.h                |   1 +<br>
>  src/mesa/main/textureview.c           |  34 ++--<br>
>  src/mesa/main/textureview.h           |   4 +<br>
>  12 files changed, 459 insertions(+), 20 deletions(-)<br>
>  create mode 100644 src/mapi/glapi/gen/ARB_copy_image.xml<br>
>  create mode 100644 src/mesa/main/copyimage.c<br>
>  create mode 100644 src/mesa/main/copyimage.h<br>
><br>
> diff --git a/src/mapi/glapi/gen/ARB_copy_image.xml b/src/mapi/glapi/gen/ARB_copy_image.xml<br>
> new file mode 100644<br>
> index 0000000..2fbd845<br>
> --- /dev/null<br>
> +++ b/src/mapi/glapi/gen/ARB_copy_image.xml<br>
> @@ -0,0 +1,28 @@<br>
> +<?xml version="1.0"?><br>
> +<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd"><br>
> +<br>
> +<OpenGLAPI><br>
> +<br>
> +<category name="GL_ARB_copy_image" number="123"><br>
> +<br>
> +    <function name="CopyImageSubData" offset="assign"><br>
> +        <param name="srcName" type="GLuint"/><br>
> +        <param name="srcTarget" type="GLenum"/><br>
> +        <param name="srcLevel" type="GLint"/><br>
> +        <param name="srcX" type="GLint"/><br>
> +        <param name="srcY" type="GLint"/><br>
> +        <param name="srcZ" type="GLint"/><br>
> +        <param name="dstName" type="GLuint"/><br>
> +        <param name="dstTarget" type="GLenum"/><br>
> +        <param name="dstLevel" type="GLint"/><br>
> +        <param name="dstX" type="GLint"/><br>
> +        <param name="dstY" type="GLint"/><br>
> +        <param name="dstZ" type="GLint"/><br>
> +        <param name="srcWidth" type="GLsizei"/><br>
> +        <param name="srcHeight" type="GLsizei"/><br>
> +        <param name="srcDepth" type="GLsizei"/><br>
> +    </function><br>
> +<br>
> +</category><br>
> +<br>
> +</OpenGLAPI><br>
> diff --git a/src/mapi/glapi/gen/Makefile.am b/src/mapi/glapi/gen/Makefile.am<br>
> index 212731f..645def4 100644<br>
> --- a/src/mapi/glapi/gen/Makefile.am<br>
> +++ b/src/mapi/glapi/gen/Makefile.am<br>
> @@ -117,6 +117,7 @@ API_XML = \<br>
>       ARB_compressed_texture_pixel_storage.xml \<br>
>       ARB_compute_shader.xml \<br>
>       ARB_copy_buffer.xml \<br>
> +     ARB_copy_image.xml \<br>
>       ARB_debug_output.xml \<br>
>       ARB_depth_buffer_float.xml \<br>
>       ARB_depth_clamp.xml \<br>
> diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml<br>
> index e011509..619717d 100644<br>
> --- a/src/mapi/glapi/gen/gl_API.xml<br>
> +++ b/src/mapi/glapi/gen/gl_API.xml<br>
> @@ -8302,7 +8302,7 @@<br>
><br>
>  <xi:include href="ARB_compute_shader.xml" xmlns:xi="<a href="http://www.w3.org/2001/XInclude" target="_blank">http://www.w3.org/2001/XInclude</a>"/><br>
><br>
> -<!-- ARB extension #123 --><br>
> +<xi:include href="ARB_copy_image.xml" xmlns:xi="<a href="http://www.w3.org/2001/XInclude" target="_blank">http://www.w3.org/2001/XInclude</a>"/><br>
><br>
>  <xi:include href="ARB_texture_view.xml" xmlns:xi="<a href="http://www.w3.org/2001/XInclude" target="_blank">http://www.w3.org/2001/XInclude</a>"/><br>
><br>
> diff --git a/src/mapi/glapi/gen/gl_genexec.py b/src/mapi/glapi/gen/gl_genexec.py<br>
> index 4609193..d479e66 100644<br>
> --- a/src/mapi/glapi/gen/gl_genexec.py<br>
> +++ b/src/mapi/glapi/gen/gl_genexec.py<br>
> @@ -62,6 +62,7 @@ header = """/**<br>
>  #include "main/condrender.h"<br>
>  #include "main/context.h"<br>
>  #include "main/convolve.h"<br>
> +#include "main/copyimage.h"<br>
>  #include "main/depth.h"<br>
>  #include "main/dlist.h"<br>
>  #include "main/drawpix.h"<br>
> diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources<br>
> index f4904fb..037cc83 100644<br>
> --- a/src/mesa/Makefile.sources<br>
> +++ b/src/mesa/Makefile.sources<br>
> @@ -28,6 +28,7 @@ MAIN_FILES = \<br>
>       $(SRCDIR)main/condrender.c \<br>
>       $(SRCDIR)main/context.c \<br>
>       $(SRCDIR)main/convolve.c \<br>
> +     $(SRCDIR)main/copyimage.c \<br>
>       $(SRCDIR)main/cpuinfo.c \<br>
>       $(SRCDIR)main/debug.c \<br>
>       $(SRCDIR)main/depth.c \<br>
> diff --git a/src/mesa/main/copyimage.c b/src/mesa/main/copyimage.c<br>
> new file mode 100644<br>
> index 0000000..96435f3<br>
> --- /dev/null<br>
> +++ b/src/mesa/main/copyimage.c<br>
> @@ -0,0 +1,341 @@<br>
> +/*<br>
> + * Mesa 3-D graphics library<br>
> + *<br>
> + * Copyright (C) 2014 Intel Corporation.  All Rights Reserved.<br>
> + *<br>
> + * Permission is hereby granted, free of charge, to any person obtaining a<br>
> + * copy of this software and associated documentation files (the "Software"),<br>
> + * to deal in the Software without restriction, including without limitation<br>
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
> + * and/or sell copies of the Software, and to permit persons to whom the<br>
> + * Software is furnished to do so, subject to the following conditions:<br>
> + *<br>
> + * The above copyright notice and this permission notice shall be included<br>
> + * in all copies or substantial portions of the Software.<br>
> + *<br>
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS<br>
> + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR<br>
> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,<br>
> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR<br>
> + * OTHER DEALINGS IN THE SOFTWARE.<br>
> + *<br>
> + * Authors:<br>
> + *    Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com">jason.ekstrand@intel.com</a>><br>
> + */<br>
> +<br>
> +#include "glheader.h"<br>
> +#include "errors.h"<br>
> +#include "enums.h"<br>
> +#include "copyimage.h"<br>
> +#include "teximage.h"<br>
> +#include "texobj.h"<br>
> +#include "fbobject.h"<br>
> +#include "textureview.h"<br>
> +<br>
> +static bool<br>
> +prepare_target(struct gl_context *ctx, GLuint name, GLenum *target, int level,<br>
> +               struct gl_texture_object **tex_obj,<br>
> +               struct gl_texture_image **tex_image, GLuint *tmp_tex,<br>
> +               const char *dbg_prefix)<br>
> +{<br>
> +   struct gl_renderbuffer *rb;<br>
> +<br>
> +   if (name == 0) {<br>
> +      _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                  "glCopyImageSubData(%sName = %d)", dbg_prefix, name);<br>
> +      return false;<br>
> +   }<br>
> +<br>
> +   /*<br>
> +    * INVALID_ENUM is generated<br>
> +    *  * if either <srcTarget> or <dstTarget><br>
> +    *   - is not RENDERBUFFER or a valid non-proxy texture target<br>
> +    *   - is TEXTURE_BUFFER, or<br>
> +    *   - is one of the cubemap face selectors described in table 3.17,<br>
> +    */<br>
> +   switch (*target) {<br>
> +   case GL_RENDERBUFFER:<br>
> +      /* Not a texture target, but valid */<br>
> +   case GL_TEXTURE_1D:<br>
> +   case GL_TEXTURE_1D_ARRAY:<br>
> +   case GL_TEXTURE_2D:<br>
> +   case GL_TEXTURE_3D:<br>
> +   case GL_TEXTURE_CUBE_MAP:<br>
> +   case GL_TEXTURE_RECTANGLE:<br>
> +   case GL_TEXTURE_2D_ARRAY:<br>
> +   case GL_TEXTURE_CUBE_MAP_ARRAY:<br>
> +   case GL_TEXTURE_2D_MULTISAMPLE:<br>
> +   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:<br>
> +      /* These are all valid */<br>
> +      break;<br>
> +   case GL_TEXTURE_EXTERNAL_OES:<br>
> +      /* Only exists in ES */<br>
> +   case GL_TEXTURE_BUFFER:<br>
> +   default:<br>
> +      _mesa_error(ctx, GL_INVALID_ENUM,<br>
> +                  "glCopyImageSubData(%sTarget = %s)", dbg_prefix,<br>
> +                  _mesa_lookup_enum_by_nr(*target));<br>
> +      return false;<br>
> +   }<br>
> +<br>
> +   if (*target == GL_RENDERBUFFER) {<br>
> +      rb = _mesa_lookup_renderbuffer(ctx, name);<br>
> +      if (!rb) {<br>
> +         _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                     "glCopyImageSubData(%sName = %u)", dbg_prefix, name);<br>
> +         return false;<br>
> +      }<br>
> +<br>
> +      if (level != 0) {<br>
> +         _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                     "glCopyImageSubData(%sLevel = %u)", dbg_prefix, level);<br>
> +         return false;<br>
> +      }<br>
> +<br>
> +      if (rb->NumSamples > 1)<br>
> +         *target = GL_TEXTURE_2D_MULTISAMPLE;<br>
> +      else<br>
> +         *target = GL_TEXTURE_2D;<br>
> +<br>
> +      _mesa_GenTextures(1, tmp_tex);<br>
<br>
</div></div>Should check if tmp_tex got something. If tmp_tex did not get anything<br>
there is error already set in context.<br></blockquote><div><br></div><div>Yeah, I can fix that up easily enough.  That should protect us from segfaults on a null tex_obj below.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div><div class="h5"><br>
> +      _mesa_BindTexture(*target, *tmp_tex);<br>
> +      *tex_obj = _mesa_lookup_texture(ctx, *tmp_tex);<br>
> +      *tex_image = _mesa_get_tex_image(ctx, *tex_obj, *target, 0);<br>
> +<br>
> +      if (!ctx->Driver.BindRenderbufferTexImage(ctx, rb, *tex_image)) {<br>
> +         _mesa_problem(ctx, "Failed to create texture from renderbuffer");<br>
> +         return false;<br>
> +      }<br>
> +<br>
> +      if (ctx->Driver.FinishRenderTexture && !rb->NeedsFinishRenderTexture) {<br>
> +         rb->NeedsFinishRenderTexture = true;<br>
> +         ctx->Driver.FinishRenderTexture(ctx, rb);<br>
> +      }<br>
> +   } else {<br>
> +      *tex_obj = _mesa_lookup_texture(ctx, name);<br>
> +      if (!*tex_obj) {<br>
> +         _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                     "glCopyImageSubData(%sName = %u)", dbg_prefix, name);<br>
> +         return false;<br>
> +      }<br>
> +<br>
> +      if ((*tex_obj)->Target != *target) {<br>
> +         _mesa_error(ctx, GL_INVALID_ENUM,<br>
> +                     "glCopyImageSubData(%sTarget = %s)", dbg_prefix,<br>
> +                     _mesa_lookup_enum_by_nr(*target));<br>
> +         return false;<br>
> +      }<br>
> +<br>
> +      if (level < 0 || level >= MAX_TEXTURE_LEVELS) {<br>
> +         _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                     "glCopyImageSubData(%sLevel = %d)", dbg_prefix, level);<br>
> +         return false;<br>
> +      }<br>
> +<br>
> +      _mesa_test_texobj_completeness(ctx, *tex_obj);<br>
> +      if (!(*tex_obj)->_BaseComplete ||<br>
> +          (level != 0 && !(*tex_obj)->_MipmapComplete)) {<br>
> +         _mesa_error(ctx, GL_INVALID_OPERATION,<br>
> +                     "glCopyImageSubData(texture incomplete)");<br>
> +         return false;<br>
> +      }<br>
> +<br>
> +      *tex_image = _mesa_select_tex_image(ctx, *tex_obj, *target, level);<br>
> +      if (!*tex_image) {<br>
> +         _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                     "glCopyImageSubData(%sLevel = %u)", dbg_prefix, level);<br>
> +         return false;<br>
> +      }<br>
> +   }<br>
> +<br>
> +   return true;<br>
> +}<br>
> +<br>
> +static bool<br>
> +check_region_bounds(struct gl_context *ctx, struct gl_texture_image *tex_image,<br>
> +                    int x, int y, int z, int width, int height, int depth,<br>
> +                    const char *dbg_prefix)<br>
> +{<br>
> +   if (width < 0 || height < 0 || depth < 0) {<br>
> +      _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                  "glCopyImageSubData(%sWidth, %sHeight, or %sDepth is negative)",<br>
> +                  dbg_prefix, dbg_prefix, dbg_prefix);<br>
> +      return false;<br>
> +   }<br>
> +<br>
> +   if (x < 0 || y < 0 || z < 0) {<br>
> +      _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                  "glCopyImageSubData(%sX, %sY, or %sZ is negative)",<br>
> +                  dbg_prefix, dbg_prefix, dbg_prefix);<br>
> +      return false;<br>
> +   }<br>
> +<br>
> +   if (x + width > tex_image->Width) {<br>
> +      _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                  "glCopyImageSubData(%sX or %sWidth exceeds image bounds)",<br>
> +                  dbg_prefix, dbg_prefix);<br>
> +      return false;<br>
> +   }<br>
> +<br>
> +   switch (tex_image->TexObject->Target) {<br>
> +   case GL_TEXTURE_1D:<br>
> +   case GL_TEXTURE_1D_ARRAY:<br>
> +      if (y != 0 || height != 1) {<br>
> +         _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                     "glCopyImageSubData(%sY or %sHeight exceeds image bounds)",<br>
> +                     dbg_prefix, dbg_prefix);<br>
> +         return false;<br>
> +      }<br>
> +      break;<br>
> +   default:<br>
> +      if (y + height > tex_image->Height) {<br>
> +         _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                     "glCopyImageSubData(%sY or %sHeight exceeds image bounds)",<br>
> +                     dbg_prefix, dbg_prefix);<br>
> +         return false;<br>
> +      }<br>
> +      break;<br>
> +   }<br>
> +<br>
> +   switch (tex_image->TexObject->Target) {<br>
> +   case GL_TEXTURE_1D:<br>
> +   case GL_TEXTURE_2D:<br>
> +   case GL_TEXTURE_2D_MULTISAMPLE:<br>
> +   case GL_TEXTURE_RECTANGLE:<br>
> +      if (z != 0 || depth != 1) {<br>
> +         _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                     "glCopyImageSubData(%sZ or %sDepth exceeds image bounds)",<br>
> +                     dbg_prefix, dbg_prefix);<br>
> +         return false;<br>
> +      }<br>
> +      break;<br>
> +   case GL_TEXTURE_CUBE_MAP:<br>
> +      if (z < 0 || z + depth > 6) {<br>
> +         _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                     "glCopyImageSubData(%sZ or %sDepth exceeds image bounds)",<br>
> +                     dbg_prefix, dbg_prefix);<br>
> +         return false;<br>
> +      }<br>
> +      break;<br>
> +   case GL_TEXTURE_1D_ARRAY:<br>
> +      if (z < 0 || z + depth > tex_image->Height) {<br>
> +         _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                     "glCopyImageSubData(%sZ or %sDepth exceeds image bounds)",<br>
> +                     dbg_prefix, dbg_prefix);<br>
> +         return false;<br>
> +      }<br>
> +      break;<br>
> +   case GL_TEXTURE_CUBE_MAP_ARRAY:<br>
> +   case GL_TEXTURE_2D_ARRAY:<br>
> +   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:<br>
> +   case GL_TEXTURE_3D:<br>
> +      if (z < 0 || z + depth > tex_image->Depth) {<br>
> +         _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                     "glCopyImageSubData(%sZ or %sDepth exceeds image bounds)",<br>
> +                     dbg_prefix, dbg_prefix);<br>
> +         return false;<br>
> +      }<br>
> +      break;<br>
> +   }<br>
> +<br>
> +   return true;<br>
> +}<br>
> +<br>
> +void<br>
> +_mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel,<br>
> +                       GLint srcX, GLint srcY, GLint srcZ,<br>
> +                       GLuint dstName, GLenum dstTarget, GLint dstLevel,<br>
> +                       GLint dstX, GLint dstY, GLint dstZ,<br>
> +                       GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth)<br>
> +{<br>
> +   GET_CURRENT_CONTEXT(ctx);<br>
> +   GLuint tmpTexNames[2] = { 0, 0 };<br>
> +   struct gl_texture_object *srcTexObj, *dstTexObj;<br>
> +   struct gl_texture_image *srcTexImage, *dstTexImage;<br>
> +   GLuint src_bw, src_bh, dst_bw, dst_bh;<br>
> +   int i, srcNewZ, dstNewZ, Bpt;<br>
> +<br>
> +   if (MESA_VERBOSE & VERBOSE_API)<br>
> +      _mesa_debug(ctx, "glCopyImageSubData(%u, %s, %d, %d, %d, %d, "<br>
> +                                          "%u, %s, %d, %d, %d, %d, "<br>
> +                                          "%d, %d, %d)\n",<br>
> +                  srcName, _mesa_lookup_enum_by_nr(srcTarget), srcLevel,<br>
> +                  srcX, srcY, srcZ,<br>
> +                  dstName, _mesa_lookup_enum_by_nr(dstTarget), dstLevel,<br>
> +                  dstX, dstY, dstZ,<br>
> +                  srcWidth, srcHeight, srcWidth);<br>
> +<br>
> +   if (!prepare_target(ctx, srcName, &srcTarget, srcLevel,<br>
> +                       &srcTexObj, &srcTexImage, &tmpTexNames[0], "src"))<br>
> +      goto cleanup;<br>
> +<br>
> +   if (!prepare_target(ctx, dstName, &dstTarget, dstLevel,<br>
> +                       &dstTexObj, &dstTexImage, &tmpTexNames[1], "dst"))<br>
> +      goto cleanup;<br>
> +<br>
> +   _mesa_get_format_block_size(srcTexImage->TexFormat, &src_bw, &src_bh);<br>
> +   if ((srcX % src_bw != 0) || (srcY % src_bh != 0) ||<br>
> +       (srcWidth % src_bw != 0) || (srcHeight % src_bh != 0)) {<br>
> +      _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                  "glCopyImageSubData(unaligned src rectangle)");<br>
> +      goto cleanup;<br>
> +   }<br>
> +<br>
> +   _mesa_get_format_block_size(dstTexImage->TexFormat, &dst_bw, &dst_bh);<br>
> +   if ((dstX % dst_bw != 0) || (dstY % dst_bh != 0)) {<br>
> +      _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                  "glCopyImageSubData(unaligned dst rectangle)");<br>
> +      goto cleanup;<br>
> +   }<br>
> +<br>
> +   /* Very simple sanity check.  This is sufficient if one of the textures<br>
> +    * is compressed. */<br>
> +   Bpt = _mesa_get_format_bytes(srcTexImage->TexFormat);<br>
> +   if (_mesa_get_format_bytes(dstTexImage->TexFormat) != Bpt) {<br>
> +      _mesa_error(ctx, GL_INVALID_VALUE,<br>
> +                  "glCopyImageSubData(internalFormat mismatch)");<br>
> +      goto cleanup;<br>
> +   }<br>
> +<br>
> +   if (!check_region_bounds(ctx, srcTexImage, srcX, srcY, srcZ,<br>
> +                            srcWidth, srcHeight, srcDepth, "src"))<br>
> +      goto cleanup;<br>
> +<br>
> +   if (!check_region_bounds(ctx, dstTexImage, dstX, dstY, dstZ,<br>
> +                            (srcWidth / src_bw) * dst_bw,<br>
> +                            (srcHeight / src_bh) * dst_bh, srcDepth, "dst"))<br>
> +      goto cleanup;<br>
> +<br>
> +   if (_mesa_is_format_compressed(srcTexImage->TexFormat)) {<br>
> +      /* FIXME */<br>
> +   } else if (_mesa_is_format_compressed(dstTexImage->TexFormat)) {<br>
> +   } else if (_mesa_texture_view_compatible_format(ctx, srcTexImage->InternalFormat, dstTexImage->InternalFormat)) {<br>
> +   } else {<br>
> +      return; /* Error loged by _mesa_texture_view_compatible_format */<br>
> +   }<br>
> +<br>
> +   for (i = 0; i < srcDepth; ++i) {<br>
> +      if (srcTexObj->Target == GL_TEXTURE_CUBE_MAP) {<br>
> +         srcTexImage = srcTexObj->Image[i + srcZ][srcLevel];<br>
> +         srcNewZ = 0;<br>
> +      } else {<br>
> +         srcNewZ = srcZ + i;<br>
> +      }<br>
> +<br>
> +      if (dstTexObj->Target == GL_TEXTURE_CUBE_MAP) {<br>
> +         dstTexImage = dstTexObj->Image[i + dstZ][dstLevel];<br>
> +         dstNewZ = 0;<br>
> +      } else {<br>
> +         dstNewZ = dstZ + i;<br>
> +      }<br>
> +<br>
> +      ctx->Driver.CopyImageSubData(ctx, srcTexImage, srcX, srcY, srcNewZ,<br>
> +                                   dstTexImage, dstX, dstY, dstNewZ,<br>
> +                                   srcWidth, srcHeight);<br>
> +   }<br>
> +<br>
> +cleanup:<br>
> +   _mesa_DeleteTextures(2, tmpTexNames);<br>
> +}<br>
> diff --git a/src/mesa/main/copyimage.h b/src/mesa/main/copyimage.h<br>
> new file mode 100644<br>
> index 0000000..40e95b6<br>
> --- /dev/null<br>
> +++ b/src/mesa/main/copyimage.h<br>
> @@ -0,0 +1,49 @@<br>
> +/*<br>
> + * Mesa 3-D graphics library<br>
> + *<br>
> + * Copyright (C) 2014 Intel Corporation.  All Rights Reserved.<br>
> + *<br>
> + * Permission is hereby granted, free of charge, to any person obtaining a<br>
> + * copy of this software and associated documentation files (the "Software"),<br>
> + * to deal in the Software without restriction, including without limitation<br>
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
> + * and/or sell copies of the Software, and to permit persons to whom the<br>
> + * Software is furnished to do so, subject to the following conditions:<br>
> + *<br>
> + * The above copyright notice and this permission notice shall be included<br>
> + * in all copies or substantial portions of the Software.<br>
> + *<br>
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS<br>
> + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR<br>
> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,<br>
> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR<br>
> + * OTHER DEALINGS IN THE SOFTWARE.<br>
> + *<br>
> + * Authors:<br>
> + *    Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com">jason.ekstrand@intel.com</a>><br>
> + */<br>
> +<br>
> +<br>
> +#ifndef COPYIMAGE_H<br>
> +#define COPYIMAGE_H<br>
> +<br>
> +#include "mtypes.h"<br>
> +<br>
> +#ifdef __cplusplus<br>
> +extern "C" {<br>
> +#endif<br>
> +<br>
> +extern void GLAPIENTRY<br>
> +_mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel,<br>
> +                       GLint srcX, GLint srcY, GLint srcZ,<br>
> +                       GLuint destName, GLenum destTarget, GLint destLevel,<br>
> +                       GLint destX, GLint destY, GLint destZ,<br>
> +                       GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth);<br>
> +<br>
> +#ifdef __cplusplus<br>
> +}<br>
> +#endif<br>
> +<br>
> +#endif /* COPYIMAGE_H */<br>
> diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h<br>
> index 8976535..c130b14 100644<br>
> --- a/src/mesa/main/dd.h<br>
> +++ b/src/mesa/main/dd.h<br>
> @@ -269,6 +269,22 @@ struct dd_function_table {<br>
>                             GLsizei width, GLsizei height);<br>
><br>
>     /**<br>
> +    * Called by glCopyImageSubData().<br>
> +    *<br>
> +    * This function should copy one 2-D slice from srcTexImage to<br>
> +    * dstTexImage.  If one of the textures is 3-D or is a 1-D or 2-D array<br>
> +    * texture, this function will be called multiple times: once for each<br>
> +    * slice.  If one of the textures is a cube map, this function will be<br>
> +    * called once for each face to be copied.<br>
> +    */<br>
> +   void (*CopyImageSubData)(struct gl_context *ctx,<br>
> +                            struct gl_texture_image *src_image,<br>
> +                            int src_x, int src_y, int src_z,<br>
> +                            struct gl_texture_image *dstTexImage,<br>
> +                            int dst_x, int dst_y, int dst_z,<br>
> +                            int src_width, int src_height);<br>
> +<br>
> +   /**<br>
>      * Called by glGenerateMipmap() or when GL_GENERATE_MIPMAP_SGIS is enabled.<br>
>      * Note that if the texture is a cube map, the <target> parameter will<br>
>      * indicate which cube face to generate (GL_POSITIVE/NEGATIVE_X/Y/Z).<br>
> diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c<br>
> index 9ac8377..d60838a 100644<br>
> --- a/src/mesa/main/extensions.c<br>
> +++ b/src/mesa/main/extensions.c<br>
> @@ -95,6 +95,7 @@ static const struct extension extension_table[] = {<br>
>     { "GL_ARB_compressed_texture_pixel_storage",    o(dummy_true),                              GL,             2011 },<br>
>     { "GL_ARB_compute_shader",                      o(ARB_compute_shader),                      GL,             2012 },<br>
>     { "GL_ARB_copy_buffer",                         o(dummy_true),                              GL,             2008 },<br>
> +   { "GL_ARB_copy_image",                          o(ARB_copy_image),                          GL,             2012 },<br>
>     { "GL_ARB_conservative_depth",                  o(ARB_conservative_depth),                  GL,             2011 },<br>
>     { "GL_ARB_debug_output",                        o(dummy_true),                              GL,             2009 },<br>
>     { "GL_ARB_depth_buffer_float",                  o(ARB_depth_buffer_float),                  GL,             2008 },<br>
> diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h<br>
> index 3f60a55..f27a508 100644<br>
> --- a/src/mesa/main/mtypes.h<br>
> +++ b/src/mesa/main/mtypes.h<br>
> @@ -3531,6 +3531,7 @@ struct gl_extensions<br>
>     GLboolean ARB_color_buffer_float;<br>
>     GLboolean ARB_compute_shader;<br>
>     GLboolean ARB_conservative_depth;<br>
> +   GLboolean ARB_copy_image;<br>
>     GLboolean ARB_depth_buffer_float;<br>
>     GLboolean ARB_depth_clamp;<br>
>     GLboolean ARB_depth_texture;<br>
> diff --git a/src/mesa/main/textureview.c b/src/mesa/main/textureview.c<br>
> index 77a3b78..dcced1b 100644<br>
> --- a/src/mesa/main/textureview.c<br>
> +++ b/src/mesa/main/textureview.c<br>
> @@ -320,15 +320,11 @@ target_valid(struct gl_context *ctx, GLenum origTarget, GLenum newTarget)<br>
>   * If an error is found, record it with _mesa_error()<br>
>   * \return false if any error, true otherwise.<br>
>   */<br>
> -static bool<br>
> -compatible_format(struct gl_context *ctx, const struct gl_texture_object *origTexObj,<br>
> -                  GLenum internalformat)<br>
> +GLboolean<br>
> +_mesa_texture_view_compatible_format(struct gl_context *ctx,<br>
> +                                     GLenum origInternalFormat,<br>
> +                                     GLenum newInternalFormat)<br>
>  {<br>
> -   /* Level 0 of a texture created by glTextureStorage or glTextureView<br>
> -    * is always defined.<br>
> -    */<br>
> -   struct gl_texture_image *texImage = origTexObj->Image[0][0];<br>
> -   GLint origInternalFormat = texImage->InternalFormat;<br>
>     unsigned int origViewClass, newViewClass;<br>
><br>
>     /* The two textures' internal formats must be compatible according to<br>
> @@ -337,19 +333,15 @@ compatible_format(struct gl_context *ctx, const struct gl_texture_object *origTe<br>
>      * The internal formats must be identical if not in that table,<br>
>      * or an INVALID_OPERATION error is generated.<br>
>      */<br>
> -   if (origInternalFormat == internalformat)<br>
> -      return true;<br>
> +   if (origInternalFormat == newInternalFormat)<br>
> +      return GL_TRUE;<br>
><br>
>     origViewClass = lookup_view_class(ctx, origInternalFormat);<br>
> -   newViewClass = lookup_view_class(ctx, internalformat);<br>
> +   newViewClass = lookup_view_class(ctx, newInternalFormat);<br>
>     if ((origViewClass == newViewClass) && origViewClass != false)<br>
> -      return true;<br>
> +      return GL_TRUE;<br>
><br>
> -   _mesa_error(ctx, GL_INVALID_OPERATION,<br>
> -               "glTextureView(internalformat %s not compatible with origtexture %s)",<br>
> -               _mesa_lookup_enum_by_nr(internalformat),<br>
> -               _mesa_lookup_enum_by_nr(origInternalFormat));<br>
> -   return false;<br>
> +   return GL_FALSE;<br>
>  }<br>
>  /**<br>
>   * Helper function for TexStorage and teximagemultisample to set immutable<br>
> @@ -512,8 +504,12 @@ _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,<br>
>        return;<br>
>     }<br>
><br>
> -   if (!compatible_format(ctx, origTexObj, internalformat)) {<br>
> -      return; /* Error logged */<br>
> +   if (!_mesa_texture_view_compatible_format(ctx, origTexObj->Image[0][0]->InternalFormat, internalformat)) {<br>
> +      _mesa_error(ctx, GL_INVALID_OPERATION,<br>
> +                  "glTextureView(internalformat %s not compatible with origtexture %s)",<br>
> +                  _mesa_lookup_enum_by_nr(internalformat),<br>
> +                  _mesa_lookup_enum_by_nr(origTexObj->Image[0][0]->InternalFormat));<br>
> +      return;<br>
>     }<br>
><br>
>     texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0,<br>
> diff --git a/src/mesa/main/textureview.h b/src/mesa/main/textureview.h<br>
> index 3088ac1..549a13c 100644<br>
> --- a/src/mesa/main/textureview.h<br>
> +++ b/src/mesa/main/textureview.h<br>
> @@ -29,6 +29,10 @@<br>
>  #ifndef TEXTUREVIEW_H<br>
>  #define TEXTUREVIEW_H<br>
><br>
> +GLboolean<br>
> +_mesa_texture_view_compatible_format(struct gl_context *ctx,<br>
> +                                     GLenum origInternalFormat,<br>
> +                                     GLenum newInternalFormat);<br>
><br>
>  extern void GLAPIENTRY<br>
>  _mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture,<br>
><br>
<br>
<br>
</div></div>Other than the small detail on patches 1 and 5 this set, 1..5, is<br>
Reviewed-by: Juha-Pekka Heikkila <<a href="mailto:juhapekka.heikkila@gmail.com">juhapekka.heikkila@gmail.com</a>><br></blockquote><div><br></div><div>Thanks for looking over them.<br></div><div>--Jason Ekstrand<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class="HOEnZb"><font color="#888888"><br>
/Juha-Pekka<br>
</font></span></blockquote></div><br></div></div>