Re: [Mesa-dev] [PATCH 3/3] st/mesa: implement ARB_copy_image

2015-11-03 Thread Marek Olšák
On Wed, Oct 28, 2015 at 5:25 PM, Ilia Mirkin  wrote:
> On Sun, Oct 25, 2015 at 1:25 PM, Marek Olšák  wrote:
>> +static void
>> +st_CopyImageSubData(struct gl_context *ctx,
>> +struct gl_texture_image *src_image,
>> +struct gl_renderbuffer *src_renderbuffer,
>> +int src_x, int src_y, int src_z,
>> +struct gl_texture_image *dst_image,
>> +struct gl_renderbuffer *dst_renderbuffer,
>> +int dst_x, int dst_y, int dst_z,
>> +int src_width, int src_height)
>> +{
>> +   struct st_context *st = st_context(ctx);
>> +   struct pipe_context *pipe = st->pipe;
>> +   struct pipe_resource *src_res, *dst_res;
>> +   struct pipe_box box;
>> +   int src_level, dst_level;
>> +
>> +   if (src_image) {
>> +  struct st_texture_image *src = st_texture_image(src_image);
>> +  src_res = src->pt;
>> +  src_level = src_image->Level;
>> +  src_z += src_image->Face;
>> +   } else {
>> +  struct st_renderbuffer *src = st_renderbuffer(src_renderbuffer);
>> +  src_res = src->texture;
>> +  src_level = 0;
>> +   }
>> +
>> +   if (dst_image) {
>> +  struct st_texture_image *dst = st_texture_image(dst_image);
>> +  dst_res = dst->pt;
>> +  dst_level = dst_image->Level;
>> +  dst_z += dst_image->Face;
>> +   } else {
>> +  struct st_renderbuffer *dst = st_renderbuffer(dst_renderbuffer);
>> +  dst_res = dst->texture;
>> +  dst_level = 0;
>> +   }
>> +
>> +   u_box_2d_zslice(src_x, src_y, src_z, src_width, src_height, );
>> +
>> +   copy_image(pipe, dst_res, dst_level, dst_x, dst_y, dst_z,
>> +  src_res, src_level, );
>> +}
>
> I know you've already pushed this, but the thought just occurred to me
> -- does this deal properly with texture views? I always get immensely
> confused by those, but shouldn't the levels/layers be offset by the
> texture object's minlayer/baselevel/minlevel somewhere? Possibly in
> _mesa_CopyImageSubData?

I don't know, maybe? Intel's intel_copy_image.c doesn't ignore
MinLevel, but ignores MinLayer. Meta ignores both. So does
main/copyimage.c when it checks region bounds.

Marek
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 3/3] st/mesa: implement ARB_copy_image

2015-10-28 Thread Ilia Mirkin
On Sun, Oct 25, 2015 at 1:25 PM, Marek Olšák  wrote:
> +static void
> +st_CopyImageSubData(struct gl_context *ctx,
> +struct gl_texture_image *src_image,
> +struct gl_renderbuffer *src_renderbuffer,
> +int src_x, int src_y, int src_z,
> +struct gl_texture_image *dst_image,
> +struct gl_renderbuffer *dst_renderbuffer,
> +int dst_x, int dst_y, int dst_z,
> +int src_width, int src_height)
> +{
> +   struct st_context *st = st_context(ctx);
> +   struct pipe_context *pipe = st->pipe;
> +   struct pipe_resource *src_res, *dst_res;
> +   struct pipe_box box;
> +   int src_level, dst_level;
> +
> +   if (src_image) {
> +  struct st_texture_image *src = st_texture_image(src_image);
> +  src_res = src->pt;
> +  src_level = src_image->Level;
> +  src_z += src_image->Face;
> +   } else {
> +  struct st_renderbuffer *src = st_renderbuffer(src_renderbuffer);
> +  src_res = src->texture;
> +  src_level = 0;
> +   }
> +
> +   if (dst_image) {
> +  struct st_texture_image *dst = st_texture_image(dst_image);
> +  dst_res = dst->pt;
> +  dst_level = dst_image->Level;
> +  dst_z += dst_image->Face;
> +   } else {
> +  struct st_renderbuffer *dst = st_renderbuffer(dst_renderbuffer);
> +  dst_res = dst->texture;
> +  dst_level = 0;
> +   }
> +
> +   u_box_2d_zslice(src_x, src_y, src_z, src_width, src_height, );
> +
> +   copy_image(pipe, dst_res, dst_level, dst_x, dst_y, dst_z,
> +  src_res, src_level, );
> +}

I know you've already pushed this, but the thought just occurred to me
-- does this deal properly with texture views? I always get immensely
confused by those, but shouldn't the levels/layers be offset by the
texture object's minlayer/baselevel/minlevel somewhere? Possibly in
_mesa_CopyImageSubData?

  -ilia
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 3/3] st/mesa: implement ARB_copy_image

2015-10-27 Thread Nicolai Hähnle

On 25.10.2015 18:25, Marek Olšák wrote:

+/**
+ * Handle complex format conversions using 2 blits with a temporary texture
+ * in between, e.g. blitting from B10G10R10A2 to G16R16.
+ *
+ * This example is implemented this way:
+ * 1) First, blit from B10G10R10A2 to R10G10B10A2, which is canonical, so it
+ *can be reinterpreted as a different canonical format of the same bpp,
+ *such as R16G16. This blit only swaps R and B 10-bit components.
+ * 2) Finnaly, blit the result, which is R10G10B10A2, as R16G16 to G16R16.
+ *This blit only swaps R and G 16-bit components.
+ */


Typo: Finally

Nicolai
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 3/3] st/mesa: implement ARB_copy_image

2015-10-27 Thread Marek Olšák
On Tue, Oct 27, 2015 at 4:26 AM, Ilia Mirkin  wrote:
>> +
>> +static void
>> +copy_image(struct pipe_context *pipe,
>> +   struct pipe_resource *dst,
>> +   unsigned dst_level,
>> +   unsigned dstx, unsigned dsty, unsigned dstz,
>> +   struct pipe_resource *src,
>> +   unsigned src_level,
>> +   const struct pipe_box *src_box)
>> +{
>> +   if (src->format == dst->format ||
>> +   util_format_is_compressed(src->format) ||
>> +   util_format_is_compressed(dst->format)) {
>
> If only :(
>
> Situation: src internal format = GL_RGBA, dst internal format =
> GL_BGRA, but both resources end up with PIPE_FORMAT_RGBA8.
>
> You end up not flipping the channels here. All of these decisions must
> be done based on the GL format, not the PIPE format...

I don't understand. The GL format doesn't specify component ordering,
only the pipe format does.

Marek
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 3/3] st/mesa: implement ARB_copy_image

2015-10-27 Thread Michel Dänzer
On 26.10.2015 02:25, Marek Olšák wrote:
> 
> +/**
> + * Handle complex format conversions using 2 blits with a temporary texture
> + * in between, e.g. blitting from B10G10R10A2 to G16R16.
> + *
> + * This example is implemented this way:
> + * 1) First, blit from B10G10R10A2 to R10G10B10A2, which is canonical, so it
> + *can be reinterpreted as a different canonical format of the same bpp,
> + *such as R16G16. This blit only swaps R and B 10-bit components.
> + * 2) Finnaly, blit the result, which is R10G10B10A2, as R16G16 to G16R16.
> + *This blit only swaps R and G 16-bit components.

In this example, some of the G10 bits will be covered by R16 and some of
them by G16, so step 2) will tear the G10 bits apart and shuffle them
around, won't it? Is that really what's supposed to happen in that case?
Maybe I'm misunderstanding the example.


-- 
Earthling Michel Dänzer   |   http://www.amd.com
Libre software enthusiast | Mesa and X developer
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 3/3] st/mesa: implement ARB_copy_image

2015-10-27 Thread Marek Olšák
On Tue, Oct 27, 2015 at 10:33 AM, Michel Dänzer  wrote:
> On 26.10.2015 02:25, Marek Olšák wrote:
>>
>> +/**
>> + * Handle complex format conversions using 2 blits with a temporary texture
>> + * in between, e.g. blitting from B10G10R10A2 to G16R16.
>> + *
>> + * This example is implemented this way:
>> + * 1) First, blit from B10G10R10A2 to R10G10B10A2, which is canonical, so it
>> + *can be reinterpreted as a different canonical format of the same bpp,
>> + *such as R16G16. This blit only swaps R and B 10-bit components.
>> + * 2) Finnaly, blit the result, which is R10G10B10A2, as R16G16 to G16R16.
>> + *This blit only swaps R and G 16-bit components.
>
> In this example, some of the G10 bits will be covered by R16 and some of
> them by G16, so step 2) will tear the G10 bits apart and shuffle them
> around, won't it? Is that really what's supposed to happen in that case?
> Maybe I'm misunderstanding the example.

Yes, that's correct. ARB_copy_image is memcpy-like. RGB10A2 -> R16G16
must be memcpy. BGRA channel ordering doesn't exist in OpenGL. The
code only deals with GR and BGRA swizzling in gallium and reorders
those to standard RGBA, so that the memcpy can be executed.

Marek
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


Re: [Mesa-dev] [PATCH 3/3] st/mesa: implement ARB_copy_image

2015-10-26 Thread Ilia Mirkin
On Sun, Oct 25, 2015 at 1:25 PM, Marek Olšák  wrote:
> From: Marek Olšák 
>
> I wonder if the craziness was worth it.
> ---
>  src/mesa/Makefile.sources|   2 +
>  src/mesa/state_tracker/st_cb_copyimage.c | 609 
> +++
>  src/mesa/state_tracker/st_cb_copyimage.h |  33 ++
>  src/mesa/state_tracker/st_cb_texture.c   |  51 ---
>  src/mesa/state_tracker/st_context.c  |   2 +
>  src/mesa/state_tracker/st_extensions.c   |   1 +
>  6 files changed, 647 insertions(+), 51 deletions(-)
>  create mode 100644 src/mesa/state_tracker/st_cb_copyimage.c
>  create mode 100644 src/mesa/state_tracker/st_cb_copyimage.h
>
> diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources
> index 4bcaa62..de0e330 100644
> --- a/src/mesa/Makefile.sources
> +++ b/src/mesa/Makefile.sources
> @@ -423,6 +423,8 @@ STATETRACKER_FILES = \
> state_tracker/st_cb_clear.h \
> state_tracker/st_cb_condrender.c \
> state_tracker/st_cb_condrender.h \
> +   state_tracker/st_cb_copyimage.c \
> +   state_tracker/st_cb_copyimage.h \
> state_tracker/st_cb_drawpixels.c \
> state_tracker/st_cb_drawpixels.h \
> state_tracker/st_cb_drawpixels_shader.c \
> diff --git a/src/mesa/state_tracker/st_cb_copyimage.c 
> b/src/mesa/state_tracker/st_cb_copyimage.c
> new file mode 100644
> index 000..1740aaf
> --- /dev/null
> +++ b/src/mesa/state_tracker/st_cb_copyimage.c
> @@ -0,0 +1,609 @@
> +/*
> + * Copyright 2015 Advanced Micro Devices, Inc.
> + *
> + * 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
> + * on the rights to use, copy, modify, merge, publish, distribute, sub
> + * license, 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 (including the next
> + * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHOR(S) AND/OR THEIR SUPPLIERS 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.
> + *
> + */
> +
> +#include "state_tracker/st_context.h"
> +#include "state_tracker/st_cb_copyimage.h"
> +#include "state_tracker/st_cb_fbo.h"
> +#include "state_tracker/st_texture.h"
> +
> +#include "util/u_box.h"
> +#include "util/u_format.h"
> +#include "util/u_inlines.h"
> +
> +
> +/**
> + * Return an equivalent canonical format without "X" channels.
> + *
> + * Copying between incompatible formats is easier when the format is
> + * canonicalized, meaning that it is in a standard form.
> + *
> + * The returned format has the same component sizes and swizzles as
> + * the source format, the type is changed to UINT or UNORM, depending on
> + * which one has the most swizzle combinations in their group.
> + *
> + * If it's not an array format, return a memcpy-equivalent array format.
> + *
> + * The key feature is that swizzled versions of formats of the same
> + * component size always return the same component type.
> + *
> + * X returns A.
> + * Luminance, intensity, alpha, depth, stencil, and 8-bit and 16-bit packed
> + * formats are not supported. (same as ARB_copy_image)
> + */
> +static enum pipe_format
> +get_canonical_format(enum pipe_format format)
> +{
> +   const struct util_format_description *desc =
> +  util_format_description(format);
> +
> +   /* Packed formats. Return the equivalent array format. */
> +   if (format == PIPE_FORMAT_R11G11B10_FLOAT ||
> +   format == PIPE_FORMAT_R9G9B9E5_FLOAT)
> +  return get_canonical_format(PIPE_FORMAT_R8G8B8A8_UINT);
> +
> +   if (desc->nr_channels == 4 &&
> +   desc->channel[0].size == 10 &&
> +   desc->channel[1].size == 10 &&
> +   desc->channel[2].size == 10 &&
> +   desc->channel[3].size == 2) {
> +  if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_X &&
> +  desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_Y &&
> +  desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_Z)
> + return get_canonical_format(PIPE_FORMAT_R8G8B8A8_UINT);
> +
> +  return PIPE_FORMAT_NONE;
> +   }
> +
> +#define RETURN_FOR_SWIZZLE1(x, format) \
> +   if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_##x) \
> +  return format
> +
> +#define RETURN_FOR_SWIZZLE2(x, y, format) \
> +   if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_##x && \
> +   desc->swizzle[1] 

Re: [Mesa-dev] [PATCH 3/3] st/mesa: implement ARB_copy_image

2015-10-26 Thread Brian Paul
Looks good to me.  Yeah, it is kind of crazy.  I think softpipe/llvmpipe 
just need one of my previous patches, plus minor updates.  I'll take 
care of that.


Just one minor nit below.

Oh, and you could probably mention support for GL_ARB_copy_image in the 
release notes file and GL3.txt.


Reviewed-by: Brian Paul 


On 10/25/2015 11:25 AM, Marek Olšák wrote:

From: Marek Olšák 

I wonder if the craziness was worth it.
---
  src/mesa/Makefile.sources|   2 +
  src/mesa/state_tracker/st_cb_copyimage.c | 609 +++
  src/mesa/state_tracker/st_cb_copyimage.h |  33 ++
  src/mesa/state_tracker/st_cb_texture.c   |  51 ---
  src/mesa/state_tracker/st_context.c  |   2 +
  src/mesa/state_tracker/st_extensions.c   |   1 +
  6 files changed, 647 insertions(+), 51 deletions(-)
  create mode 100644 src/mesa/state_tracker/st_cb_copyimage.c
  create mode 100644 src/mesa/state_tracker/st_cb_copyimage.h

diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources
index 4bcaa62..de0e330 100644
--- a/src/mesa/Makefile.sources
+++ b/src/mesa/Makefile.sources
@@ -423,6 +423,8 @@ STATETRACKER_FILES = \
state_tracker/st_cb_clear.h \
state_tracker/st_cb_condrender.c \
state_tracker/st_cb_condrender.h \
+   state_tracker/st_cb_copyimage.c \
+   state_tracker/st_cb_copyimage.h \
state_tracker/st_cb_drawpixels.c \
state_tracker/st_cb_drawpixels.h \
state_tracker/st_cb_drawpixels_shader.c \
diff --git a/src/mesa/state_tracker/st_cb_copyimage.c 
b/src/mesa/state_tracker/st_cb_copyimage.c
new file mode 100644
index 000..1740aaf
--- /dev/null
+++ b/src/mesa/state_tracker/st_cb_copyimage.c
@@ -0,0 +1,609 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, 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 (including the next
+ * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS 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.
+ *
+ */
+
+#include "state_tracker/st_context.h"
+#include "state_tracker/st_cb_copyimage.h"
+#include "state_tracker/st_cb_fbo.h"
+#include "state_tracker/st_texture.h"
+
+#include "util/u_box.h"
+#include "util/u_format.h"
+#include "util/u_inlines.h"
+
+
+/**
+ * Return an equivalent canonical format without "X" channels.
+ *
+ * Copying between incompatible formats is easier when the format is
+ * canonicalized, meaning that it is in a standard form.
+ *
+ * The returned format has the same component sizes and swizzles as
+ * the source format, the type is changed to UINT or UNORM, depending on
+ * which one has the most swizzle combinations in their group.
+ *
+ * If it's not an array format, return a memcpy-equivalent array format.
+ *
+ * The key feature is that swizzled versions of formats of the same
+ * component size always return the same component type.
+ *
+ * X returns A.
+ * Luminance, intensity, alpha, depth, stencil, and 8-bit and 16-bit packed
+ * formats are not supported. (same as ARB_copy_image)
+ */
+static enum pipe_format
+get_canonical_format(enum pipe_format format)
+{
+   const struct util_format_description *desc =
+  util_format_description(format);
+
+   /* Packed formats. Return the equivalent array format. */
+   if (format == PIPE_FORMAT_R11G11B10_FLOAT ||
+   format == PIPE_FORMAT_R9G9B9E5_FLOAT)
+  return get_canonical_format(PIPE_FORMAT_R8G8B8A8_UINT);
+
+   if (desc->nr_channels == 4 &&
+   desc->channel[0].size == 10 &&
+   desc->channel[1].size == 10 &&
+   desc->channel[2].size == 10 &&
+   desc->channel[3].size == 2) {
+  if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_X &&
+  desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_Y &&
+  desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_Z)
+ return get_canonical_format(PIPE_FORMAT_R8G8B8A8_UINT);
+
+  return PIPE_FORMAT_NONE;
+   }
+
+#define RETURN_FOR_SWIZZLE1(x, format) \
+   if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_##x) \
+  return format
+
+#define RETURN_FOR_SWIZZLE2(x, y, format) 

[Mesa-dev] [PATCH 3/3] st/mesa: implement ARB_copy_image

2015-10-25 Thread Marek Olšák
From: Marek Olšák 

I wonder if the craziness was worth it.
---
 src/mesa/Makefile.sources|   2 +
 src/mesa/state_tracker/st_cb_copyimage.c | 609 +++
 src/mesa/state_tracker/st_cb_copyimage.h |  33 ++
 src/mesa/state_tracker/st_cb_texture.c   |  51 ---
 src/mesa/state_tracker/st_context.c  |   2 +
 src/mesa/state_tracker/st_extensions.c   |   1 +
 6 files changed, 647 insertions(+), 51 deletions(-)
 create mode 100644 src/mesa/state_tracker/st_cb_copyimage.c
 create mode 100644 src/mesa/state_tracker/st_cb_copyimage.h

diff --git a/src/mesa/Makefile.sources b/src/mesa/Makefile.sources
index 4bcaa62..de0e330 100644
--- a/src/mesa/Makefile.sources
+++ b/src/mesa/Makefile.sources
@@ -423,6 +423,8 @@ STATETRACKER_FILES = \
state_tracker/st_cb_clear.h \
state_tracker/st_cb_condrender.c \
state_tracker/st_cb_condrender.h \
+   state_tracker/st_cb_copyimage.c \
+   state_tracker/st_cb_copyimage.h \
state_tracker/st_cb_drawpixels.c \
state_tracker/st_cb_drawpixels.h \
state_tracker/st_cb_drawpixels_shader.c \
diff --git a/src/mesa/state_tracker/st_cb_copyimage.c 
b/src/mesa/state_tracker/st_cb_copyimage.c
new file mode 100644
index 000..1740aaf
--- /dev/null
+++ b/src/mesa/state_tracker/st_cb_copyimage.c
@@ -0,0 +1,609 @@
+/*
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, 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 (including the next
+ * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS 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.
+ *
+ */
+
+#include "state_tracker/st_context.h"
+#include "state_tracker/st_cb_copyimage.h"
+#include "state_tracker/st_cb_fbo.h"
+#include "state_tracker/st_texture.h"
+
+#include "util/u_box.h"
+#include "util/u_format.h"
+#include "util/u_inlines.h"
+
+
+/**
+ * Return an equivalent canonical format without "X" channels.
+ *
+ * Copying between incompatible formats is easier when the format is
+ * canonicalized, meaning that it is in a standard form.
+ *
+ * The returned format has the same component sizes and swizzles as
+ * the source format, the type is changed to UINT or UNORM, depending on
+ * which one has the most swizzle combinations in their group.
+ *
+ * If it's not an array format, return a memcpy-equivalent array format.
+ *
+ * The key feature is that swizzled versions of formats of the same
+ * component size always return the same component type.
+ *
+ * X returns A.
+ * Luminance, intensity, alpha, depth, stencil, and 8-bit and 16-bit packed
+ * formats are not supported. (same as ARB_copy_image)
+ */
+static enum pipe_format
+get_canonical_format(enum pipe_format format)
+{
+   const struct util_format_description *desc =
+  util_format_description(format);
+
+   /* Packed formats. Return the equivalent array format. */
+   if (format == PIPE_FORMAT_R11G11B10_FLOAT ||
+   format == PIPE_FORMAT_R9G9B9E5_FLOAT)
+  return get_canonical_format(PIPE_FORMAT_R8G8B8A8_UINT);
+
+   if (desc->nr_channels == 4 &&
+   desc->channel[0].size == 10 &&
+   desc->channel[1].size == 10 &&
+   desc->channel[2].size == 10 &&
+   desc->channel[3].size == 2) {
+  if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_X &&
+  desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_Y &&
+  desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_Z)
+ return get_canonical_format(PIPE_FORMAT_R8G8B8A8_UINT);
+
+  return PIPE_FORMAT_NONE;
+   }
+
+#define RETURN_FOR_SWIZZLE1(x, format) \
+   if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_##x) \
+  return format
+
+#define RETURN_FOR_SWIZZLE2(x, y, format) \
+   if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_##x && \
+   desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_##y) \
+  return format
+
+#define RETURN_FOR_SWIZZLE3(x, y, z, format) \
+   if (desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_##x && \
+   desc->swizzle[1] == UTIL_FORMAT_SWIZZLE_##y && \
+   desc->swizzle[2] == UTIL_FORMAT_SWIZZLE_##z) \
+  return format
+
+#define