<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 12, 2015 at 9:24 PM, Jason Ekstrand <span dir="ltr"><<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div>Sean,<br></div>I got ready to push this and ran it against piglit and one of the tests errored out.  Looking into it further, it was a bug in the test.  I've sent a patch:<br><br><a href="http://lists.freedesktop.org/archives/piglit/2015-March/015156.html" target="_blank">http://lists.freedesktop.org/archives/piglit/2015-March/015156.html</a><br><br></div>I'll merge the mesa commit once we get piglit fixed.<span class="HOEnZb"><font color="#888888"><br></font></span></div><span class="HOEnZb"><font color="#888888">--Jason<br></font></span></div></blockquote><div><br></div><div>Pushed.  Thanks!<br> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><span class="HOEnZb"><font color="#888888"></font></span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 12, 2015 at 4:38 PM, Sean Burke <span dir="ltr"><<a href="mailto:leftmostcat@gmail.com" target="_blank">leftmostcat@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Jason,<br>
<br>
No worries. It looks like my mail client munged the patch in some way.<br>
I'm sending it as an attachment in the hopes that it will remain<br>
untouched.<br>
<span><font color="#888888"><br>
<br>
Sean Burke<br>
</font></span><div><div><br>
On Wed, Mar 11, 2015 at 2:53 PM, Jason Ekstrand <<a href="mailto:jason@jlekstrand.net" target="_blank">jason@jlekstrand.net</a>> wrote:<br>
> Sean,<br>
> Sorry it's taken so long for me to get to this, but I went to test/push this<br>
> today and it doesn't apply against current mesa master.  Can you please<br>
> either rebase on master and re-send or give me the SHA1 hash of the commit<br>
> this one is based on.  (Not the SHA1 of this commit but the previous one).<br>
> --Jason<br>
><br>
> On Sat, Mar 7, 2015 at 8:34 PM, Sean Burke <<a href="mailto:leftmostcat@gmail.com" target="_blank">leftmostcat@gmail.com</a>> wrote:<br>
>><br>
>> The memory layout of compatible internal formats may differ in bytes per<br>
>> block, so TexFormat is not a reliable measure of compatibility. For<br>
>> example,<br>
>> GL_RGB8 and GL_RGB8UI are compatible formats, but GL_RGB8 may be laid out<br>
>> in<br>
>> memory as B8G8R8X8. If GL_RGB8UI has a 3 byte-per-block memory layout, the<br>
>> existing compatibility check will fail.<br>
>><br>
>> Additionally, the current check allows any two compressed textures which<br>
>> share<br>
>> block size to be used, whereas the spec gives an explicit table of<br>
>> compatible<br>
>> formats.<br>
>><br>
>> v2: Use a switch instead of array iteration for block class and show the<br>
>>     correct GL error when internal formats are mismatched.<br>
>> v3: Include spec citations for new compatibility checks, rearrange check<br>
>>     order to ensure that compressed, view-compatible formats return the<br>
>>     correct result, and make style fixes. Original commit message amended<br>
>>     for clarity.<br>
>> v4: Reformatted spec citations.<br>
>><br>
>> Reviewed-by: Jason Ekstrand <<a href="mailto:jason.ekstrand@intel.com" target="_blank">jason.ekstrand@intel.com</a>><br>
>> ---<br>
>>  src/mesa/main/copyimage.c | 151<br>
>> +++++++++++++++++++++++++++++++++++++++-------<br>
>>  1 file changed, 130 insertions(+), 21 deletions(-)<br>
>><br>
>> diff --git a/src/mesa/main/copyimage.c b/src/mesa/main/copyimage.c<br>
>> index 455929d..fd22f28 100644<br>
>> --- a/src/mesa/main/copyimage.c<br>
>> +++ b/src/mesa/main/copyimage.c<br>
>> @@ -33,6 +33,12 @@<br>
>>  #include "texobj.h"<br>
>>  #include "fbobject.h"<br>
>>  #include "textureview.h"<br>
>> +#include "glformats.h"<br>
>> +<br>
>> +enum mesa_block_class {<br>
>> +   BLOCK_CLASS_128_BITS,<br>
>> +   BLOCK_CLASS_64_BITS<br>
>> +};<br>
>><br>
>>  static bool<br>
>>  prepare_target(struct gl_context *ctx, GLuint name, GLenum *target, int<br>
>> level,<br>
>> @@ -253,6 +259,124 @@ check_region_bounds(struct gl_context *ctx,<br>
>> struct gl_texture_image *tex_image,<br>
>>     return true;<br>
>>  }<br>
>><br>
>> +static bool<br>
>> +compressed_format_compatible(struct gl_context *ctx,<br>
>> +                             GLenum compressedFormat, GLenum otherFormat)<br>
>> +{<br>
>> +   enum mesa_block_class compressedClass, otherClass;<br>
>> +<br>
>> +   /* Two view-incompatible compressed formats are never compatible. */<br>
>> +   if (_mesa_is_compressed_format(ctx, otherFormat)) {<br>
>> +      return false;<br>
>> +   }<br>
>> +<br>
>> +   /*<br>
>> +    * From ARB_copy_image spec:<br>
>> +    *    Table 4.X.1 (Compatible internal formats for copying between<br>
>> +    *                 compressed and uncompressed internal formats)<br>
>> +    *<br>
>> ---------------------------------------------------------------------<br>
>> +    *    | Texel / | Uncompressed      |<br>
>> |<br>
>> +    *    | Block   | internal format   | Compressed internal format<br>
>> |<br>
>> +    *    | size    |                   |<br>
>> |<br>
>> +    *<br>
>> ---------------------------------------------------------------------<br>
>> +    *    | 128-bit | RGBA32UI,         | COMPRESSED_RGBA_S3TC_DXT3_EXT,<br>
>> |<br>
>> +    *    |         | RGBA32I,          |<br>
>> COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,|<br>
>> +    *    |         | RGBA32F           | COMPRESSED_RGBA_S3TC_DXT5_EXT,<br>
>> |<br>
>> +    *    |         |                   |<br>
>> COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,|<br>
>> +    *    |         |                   | COMPRESSED_RG_RGTC2,<br>
>> |<br>
>> +    *    |         |                   | COMPRESSED_SIGNED_RG_RGTC2,<br>
>> |<br>
>> +    *    |         |                   | COMPRESSED_RGBA_BPTC_UNORM,<br>
>> |<br>
>> +    *    |         |                   |<br>
>> COMPRESSED_SRGB_ALPHA_BPTC_UNORM,   |<br>
>> +    *    |         |                   |<br>
>> COMPRESSED_RGB_BPTC_SIGNED_FLOAT,   |<br>
>> +    *    |         |                   |<br>
>> COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT  |<br>
>> +    *<br>
>> ---------------------------------------------------------------------<br>
>> +    *    | 64-bit  | RGBA16F, RG32F,   | COMPRESSED_RGB_S3TC_DXT1_EXT,<br>
>> |<br>
>> +    *    |         | RGBA16UI, RG32UI, | COMPRESSED_SRGB_S3TC_DXT1_EXT,<br>
>> |<br>
>> +    *    |         | RGBA16I, RG32I,   | COMPRESSED_RGBA_S3TC_DXT1_EXT,<br>
>> |<br>
>> +    *    |         | RGBA16,           |<br>
>> COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,|<br>
>> +    *    |         | RGBA16_SNORM      | COMPRESSED_RED_RGTC1,<br>
>> |<br>
>> +    *    |         |                   | COMPRESSED_SIGNED_RED_RGTC1<br>
>> |<br>
>> +    *<br>
>> ---------------------------------------------------------------------<br>
>> +    */<br>
>> +<br>
>> +   switch (compressedFormat) {<br>
>> +      case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:<br>
>> +      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:<br>
>> +      case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:<br>
>> +      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:<br>
>> +      case GL_COMPRESSED_RG_RGTC2:<br>
>> +      case GL_COMPRESSED_SIGNED_RG_RGTC2:<br>
>> +      case GL_COMPRESSED_RGBA_BPTC_UNORM:<br>
>> +      case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:<br>
>> +      case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:<br>
>> +      case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:<br>
>> +         compressedClass = BLOCK_CLASS_128_BITS;<br>
>> +         break;<br>
>> +      case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:<br>
>> +      case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:<br>
>> +      case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:<br>
>> +      case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:<br>
>> +      case GL_COMPRESSED_RED_RGTC1:<br>
>> +      case GL_COMPRESSED_SIGNED_RED_RGTC1:<br>
>> +         compressedClass = BLOCK_CLASS_64_BITS;<br>
>> +         break;<br>
>> +      default:<br>
>> +         return false;<br>
>> +   }<br>
>> +<br>
>> +   switch (otherFormat) {<br>
>> +      case GL_RGBA32UI:<br>
>> +      case GL_RGBA32I:<br>
>> +      case GL_RGBA32F:<br>
>> +         otherClass = BLOCK_CLASS_128_BITS;<br>
>> +         break;<br>
>> +      case GL_RGBA16F:<br>
>> +      case GL_RG32F:<br>
>> +      case GL_RGBA16UI:<br>
>> +      case GL_RG32UI:<br>
>> +      case GL_RGBA16I:<br>
>> +      case GL_RG32I:<br>
>> +      case GL_RGBA16:<br>
>> +      case GL_RGBA16_SNORM:<br>
>> +         otherClass = BLOCK_CLASS_64_BITS;<br>
>> +         break;<br>
>> +      default:<br>
>> +         return false;<br>
>> +   }<br>
>> +<br>
>> +   return compressedClass == otherClass;<br>
>> +}<br>
>> +<br>
>> +static bool<br>
>> +copy_format_compatible(struct gl_context *ctx,<br>
>> +                                GLenum srcFormat, GLenum dstFormat)<br>
>> +{<br>
>> +   /*<br>
>> +    * From ARB_copy_image spec:<br>
>> +    *    For the purposes of CopyImageSubData, two internal formats<br>
>> +    *    are considered compatible if any of the following conditions are<br>
>> +    *    met:<br>
>> +    *    * the formats are the same,<br>
>> +    *    * the formats are considered compatible according to the<br>
>> +    *      compatibility rules used for texture views as defined in<br>
>> +    *      section 3.9.X. In particular, if both internal formats are<br>
>> listed<br>
>> +    *      in the same entry of Table 3.X.2, they are considered<br>
>> compatible, or<br>
>> +    *    * one format is compressed and the other is uncompressed and<br>
>> +    *      Table 4.X.1 lists the two formats in the same row.<br>
>> +    */<br>
>> +<br>
>> +   if (_mesa_texture_view_compatible_format(ctx, srcFormat, dstFormat)) {<br>
>> +      /* Also checks if formats are equal. */<br>
>> +      return true;<br>
>> +   } else if (_mesa_is_compressed_format(ctx, srcFormat)) {<br>
>> +      return compressed_format_compatible(ctx, srcFormat, dstFormat);<br>
>> +   } else if (_mesa_is_compressed_format(ctx, dstFormat)) {<br>
>> +      return compressed_format_compatible(ctx, dstFormat, srcFormat);<br>
>> +   }<br>
>> +<br>
>> +   return false;<br>
>> +}<br>
>> +<br>
>>  void GLAPIENTRY<br>
>>  _mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel,<br>
>>                         GLint srcX, GLint srcY, GLint srcZ,<br>
>> @@ -265,7 +389,7 @@ _mesa_CopyImageSubData(GLuint srcName, GLenum<br>
>> srcTarget, GLint srcLevel,<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>
>> +   int i, srcNewZ, dstNewZ;<br>
>><br>
>>     if (MESA_VERBOSE & VERBOSE_API)<br>
>>        _mesa_debug(ctx, "glCopyImageSubData(%u, %s, %d, %d, %d, %d, "<br>
>> @@ -306,15 +430,6 @@ _mesa_CopyImageSubData(GLuint srcName, GLenum<br>
>> srcTarget, GLint srcLevel,<br>
>>        goto cleanup;<br>
>>     }<br>
>><br>
>> -   /* Very simple sanity check.  This is sufficient if one of the<br>
>> 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>
>> @@ -324,17 +439,11 @@ _mesa_CopyImageSubData(GLuint srcName, GLenum<br>
>> srcTarget, GLint srcLevel,<br>
>>                              (srcHeight / src_bh) * dst_bh, srcDepth,<br>
>> "dst"))<br>
>>        goto cleanup;<br>
>><br>
>> -   if (_mesa_is_format_compressed(srcTexImage->TexFormat)) {<br>
>> -      /* XXX: Technically, we should probaby do some more specific<br>
>> checking<br>
>> -       * here.  However, this should be sufficient for all compressed<br>
>> -       * formats that mesa supports since it is a direct memory copy.<br>
>> -       */<br>
>> -   } else if (_mesa_is_format_compressed(dstTexImage->TexFormat)) {<br>
>> -   } else if (_mesa_texture_view_compatible_format(ctx,<br>
>> -<br>
>> srcTexImage->InternalFormat,<br>
>> -<br>
>> dstTexImage->InternalFormat)) {<br>
>> -   } else {<br>
>> -      return; /* Error logged by _mesa_texture_view_compatible_format */<br>
>> +   if (!copy_format_compatible(ctx, srcTexImage->InternalFormat,<br>
>> +                               dstTexImage->InternalFormat)) {<br>
>> +      _mesa_error(ctx, GL_INVALID_OPERATION,<br>
>> +                  "glCopyImageSubData(internalFormat mismatch)");<br>
>> +      goto cleanup;<br>
>>     }<br>
>><br>
>>     for (i = 0; i < srcDepth; ++i) {<br>
>> --<br>
>> 2.1.0<br>
><br>
><br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div></div>