mesa: remove duplicated code around framebuffer_renderbuffer()
[mesa.git] / src / mesa / main / texcompress_etc.c
index 7ad4ddeb6471ec29514ba9777e76b8e4278a1866..d4650109857171d6c114ca05fd3370d513b27227 100644 (file)
  */
 
 #include <stdbool.h>
-#include "mfeatures.h"
 #include "texcompress.h"
 #include "texcompress_etc.h"
 #include "texstore.h"
 #include "macros.h"
 #include "format_unpack.h"
+#include "util/format_srgb.h"
 
 
 struct etc2_block {
@@ -108,7 +108,7 @@ GLboolean
 _mesa_texstore_etc1_rgb8(TEXSTORE_PARAMS)
 {
    /* GL_ETC1_RGB8_OES is only valid in glCompressedTexImage2D */
-   ASSERT(0);
+   assert(0);
 
    return GL_FALSE;
 }
@@ -430,8 +430,7 @@ etc2_rgb8_parse_block(struct etc2_block *block,
       block->is_planar_mode = true;
 
       /* opaque bit must be set in planar mode */
-      if (!block->opaque)
-         block->opaque = true;
+      block->opaque = true;
 
       for (i = 0; i < 3; i++) {
          block->base_colors[0][i] = etc2_base_color_o_planar(src, i);
@@ -459,10 +458,10 @@ etc2_rgb8_parse_block(struct etc2_block *block,
       /* Use same modifier tables as for etc1 textures if opaque bit is set
        * or if non punchthrough texture format
        */
-      block->modifier_tables[0] = (block->opaque || !punchthrough_alpha) ?
+      block->modifier_tables[0] = (!punchthrough_alpha || block->opaque) ?
                                   etc1_modifier_tables[table1_idx] :
                                   etc2_modifier_tables_non_opaque[table1_idx];
-      block->modifier_tables[1] = (block->opaque || !punchthrough_alpha) ?
+      block->modifier_tables[1] = (!punchthrough_alpha || block->opaque) ?
                                   etc1_modifier_tables[table2_idx] :
                                   etc2_modifier_tables_non_opaque[table2_idx];
 
@@ -680,14 +679,25 @@ etc2_unpack_rgb8(uint8_t *dst_row,
 
    for (y = 0; y < height; y += bh) {
       const uint8_t *src = src_row;
+      /*
+       * Destination texture may not be a multiple of four texels in
+       * height. Compute a safe height to avoid writing outside the texture.
+       */
+      const unsigned h = MIN2(bh, height - y);
 
       for (x = 0; x < width; x+= bw) {
+         /*
+          * Destination texture may not be a multiple of four texels in
+          * width. Compute a safe width to avoid writing outside the texture.
+          */
+         const unsigned w = MIN2(bw, width - x);
+
          etc2_rgb8_parse_block(&block, src,
                                false /* punchthrough_alpha */);
 
-         for (j = 0; j < bh; j++) {
+         for (j = 0; j < h; j++) {
             uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
-            for (i = 0; i < bw; i++) {
+            for (i = 0; i < w; i++) {
                etc2_rgb8_fetch_texel(&block, i, j, dst,
                                      false /* punchthrough_alpha */);
                dst[3] = 255;
@@ -717,17 +727,20 @@ etc2_unpack_srgb8(uint8_t *dst_row,
 
    for (y = 0; y < height; y += bh) {
       const uint8_t *src = src_row;
+      const unsigned h = MIN2(bh, height - y);
 
       for (x = 0; x < width; x+= bw) {
+         const unsigned w = MIN2(bw, width - x);
          etc2_rgb8_parse_block(&block, src,
                                false /* punchthrough_alpha */);
 
-         for (j = 0; j < bh; j++) {
+
+         for (j = 0; j < h; j++) {
             uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
-            for (i = 0; i < bw; i++) {
+            for (i = 0; i < w; i++) {
                etc2_rgb8_fetch_texel(&block, i, j, dst,
                                      false /* punchthrough_alpha */);
-               /* Convert to MESA_FORMAT_SARGB8 */
+               /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */
                tmp = dst[0];
                dst[0] = dst[2];
                dst[2] = tmp;
@@ -761,13 +774,15 @@ etc2_unpack_rgba8(uint8_t *dst_row,
 
    for (y = 0; y < height; y += bh) {
       const uint8_t *src = src_row;
+      const unsigned h = MIN2(bh, height - y);
 
       for (x = 0; x < width; x+= bw) {
+         const unsigned w = MIN2(bw, width - x);
          etc2_rgba8_parse_block(&block, src);
 
-         for (j = 0; j < bh; j++) {
+         for (j = 0; j < h; j++) {
             uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
-            for (i = 0; i < bw; i++) {
+            for (i = 0; i < w; i++) {
                etc2_rgba8_fetch_texel(&block, i, j, dst);
                dst += comps;
             }
@@ -797,17 +812,19 @@ etc2_unpack_srgb8_alpha8(uint8_t *dst_row,
    uint8_t tmp;
 
    for (y = 0; y < height; y += bh) {
+      const unsigned h = MIN2(bh, height - y);
       const uint8_t *src = src_row;
 
       for (x = 0; x < width; x+= bw) {
+         const unsigned w = MIN2(bw, width - x);
          etc2_rgba8_parse_block(&block, src);
 
-         for (j = 0; j < bh; j++) {
+         for (j = 0; j < h; j++) {
             uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
-            for (i = 0; i < bw; i++) {
+            for (i = 0; i < w; i++) {
                etc2_rgba8_fetch_texel(&block, i, j, dst);
 
-               /* Convert to MESA_FORMAT_SARGB8 */
+               /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */
                tmp = dst[0];
                dst[0] = dst[2];
                dst[2] = tmp;
@@ -839,14 +856,16 @@ etc2_unpack_r11(uint8_t *dst_row,
    unsigned x, y, i, j;
 
    for (y = 0; y < height; y += bh) {
+      const unsigned h = MIN2(bh, height - y);
       const uint8_t *src = src_row;
 
       for (x = 0; x < width; x+= bw) {
+         const unsigned w = MIN2(bw, width - x);
          etc2_r11_parse_block(&block, src);
 
-         for (j = 0; j < bh; j++) {
+         for (j = 0; j < h; j++) {
             uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps * comp_size;
-            for (i = 0; i < bw; i++) {
+            for (i = 0; i < w; i++) {
                etc2_r11_fetch_texel(&block, i, j, dst);
                dst += comps * comp_size;
             }
@@ -874,16 +893,18 @@ etc2_unpack_rg11(uint8_t *dst_row,
    unsigned x, y, i, j;
 
    for (y = 0; y < height; y += bh) {
+      const unsigned h = MIN2(bh, height - y);
       const uint8_t *src = src_row;
 
       for (x = 0; x < width; x+= bw) {
+         const unsigned w = MIN2(bw, width - x);
          /* red component */
          etc2_r11_parse_block(&block, src);
 
-         for (j = 0; j < bh; j++) {
+         for (j = 0; j < h; j++) {
             uint8_t *dst = dst_row + (y + j) * dst_stride +
                            x * comps * comp_size;
-            for (i = 0; i < bw; i++) {
+            for (i = 0; i < w; i++) {
                etc2_r11_fetch_texel(&block, i, j, dst);
                dst += comps * comp_size;
             }
@@ -891,10 +912,10 @@ etc2_unpack_rg11(uint8_t *dst_row,
          /* green component */
          etc2_r11_parse_block(&block, src + 8);
 
-         for (j = 0; j < bh; j++) {
+         for (j = 0; j < h; j++) {
             uint8_t *dst = dst_row + (y + j) * dst_stride +
                            x * comps * comp_size;
-            for (i = 0; i < bw; i++) {
+            for (i = 0; i < w; i++) {
                etc2_r11_fetch_texel(&block, i, j, dst + comp_size);
                dst += comps * comp_size;
             }
@@ -922,15 +943,17 @@ etc2_unpack_signed_r11(uint8_t *dst_row,
    unsigned x, y, i, j;
 
    for (y = 0; y < height; y += bh) {
+      const unsigned h = MIN2(bh, height - y);
       const uint8_t *src = src_row;
 
       for (x = 0; x < width; x+= bw) {
+         const unsigned w = MIN2(bw, width - x);
          etc2_r11_parse_block(&block, src);
 
-         for (j = 0; j < bh; j++) {
+         for (j = 0; j < h; j++) {
             uint8_t *dst = dst_row + (y + j) * dst_stride +
                            x * comps * comp_size;
-            for (i = 0; i < bw; i++) {
+            for (i = 0; i < w; i++) {
                etc2_signed_r11_fetch_texel(&block, i, j, dst);
                dst += comps * comp_size;
             }
@@ -958,16 +981,18 @@ etc2_unpack_signed_rg11(uint8_t *dst_row,
    unsigned x, y, i, j;
 
    for (y = 0; y < height; y += bh) {
+      const unsigned h = MIN2(bh, height - y);
       const uint8_t *src = src_row;
 
       for (x = 0; x < width; x+= bw) {
+         const unsigned w = MIN2(bw, width - x);
          /* red component */
          etc2_r11_parse_block(&block, src);
 
-         for (j = 0; j < bh; j++) {
+         for (j = 0; j < h; j++) {
             uint8_t *dst = dst_row + (y + j) * dst_stride +
                           x * comps * comp_size;
-            for (i = 0; i < bw; i++) {
+            for (i = 0; i < w; i++) {
                etc2_signed_r11_fetch_texel(&block, i, j, dst);
                dst += comps * comp_size;
             }
@@ -975,10 +1000,10 @@ etc2_unpack_signed_rg11(uint8_t *dst_row,
          /* green component */
          etc2_r11_parse_block(&block, src + 8);
 
-         for (j = 0; j < bh; j++) {
+         for (j = 0; j < h; j++) {
             uint8_t *dst = dst_row + (y + j) * dst_stride +
                            x * comps * comp_size;
-            for (i = 0; i < bw; i++) {
+            for (i = 0; i < w; i++) {
                etc2_signed_r11_fetch_texel(&block, i, j, dst + comp_size);
                dst += comps * comp_size;
             }
@@ -1003,14 +1028,16 @@ etc2_unpack_rgb8_punchthrough_alpha1(uint8_t *dst_row,
    unsigned x, y, i, j;
 
    for (y = 0; y < height; y += bh) {
+      const unsigned h = MIN2(bh, height - y);
       const uint8_t *src = src_row;
 
       for (x = 0; x < width; x+= bw) {
+         const unsigned w = MIN2(bw, width - x);
          etc2_rgb8_parse_block(&block, src,
                                true /* punchthrough_alpha */);
-         for (j = 0; j < bh; j++) {
+         for (j = 0; j < h; j++) {
             uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
-            for (i = 0; i < bw; i++) {
+            for (i = 0; i < w; i++) {
                etc2_rgb8_fetch_texel(&block, i, j, dst,
                                      true /* punchthrough_alpha */);
                dst += comps;
@@ -1038,17 +1065,19 @@ etc2_unpack_srgb8_punchthrough_alpha1(uint8_t *dst_row,
    uint8_t tmp;
 
    for (y = 0; y < height; y += bh) {
+      const unsigned h = MIN2(bh, height - y);
       const uint8_t *src = src_row;
 
       for (x = 0; x < width; x+= bw) {
+         const unsigned w = MIN2(bw, width - x);
          etc2_rgb8_parse_block(&block, src,
                                true /* punchthrough_alpha */);
-         for (j = 0; j < bh; j++) {
+         for (j = 0; j < h; j++) {
             uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps;
-            for (i = 0; i < bw; i++) {
+            for (i = 0; i < w; i++) {
                etc2_rgb8_fetch_texel(&block, i, j, dst,
                                      true /* punchthrough_alpha */);
-               /* Convert to MESA_FORMAT_SARGB8 */
+               /* Convert to MESA_FORMAT_B8G8R8A8_SRGB */
                tmp = dst[0];
                dst[0] = dst[2];
                dst[2] = tmp;
@@ -1070,7 +1099,7 @@ etc2_unpack_srgb8_punchthrough_alpha1(uint8_t *dst_row,
 GLboolean
 _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS)
 {
-   ASSERT(0);
+   assert(0);
 
    return GL_FALSE;
 }
@@ -1078,7 +1107,7 @@ _mesa_texstore_etc2_rgb8(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS)
 {
-   ASSERT(0);
+   assert(0);
 
    return GL_FALSE;
 }
@@ -1086,7 +1115,7 @@ _mesa_texstore_etc2_srgb8(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS)
 {
-   ASSERT(0);
+   assert(0);
 
    return GL_FALSE;
 }
@@ -1094,7 +1123,7 @@ _mesa_texstore_etc2_rgba8_eac(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS)
 {
-   ASSERT(0);
+   assert(0);
 
    return GL_FALSE;
 }
@@ -1102,7 +1131,7 @@ _mesa_texstore_etc2_srgb8_alpha8_eac(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_etc2_r11_eac(TEXSTORE_PARAMS)
 {
-   ASSERT(0);
+   assert(0);
 
    return GL_FALSE;
 }
@@ -1110,7 +1139,7 @@ _mesa_texstore_etc2_r11_eac(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_etc2_signed_r11_eac(TEXSTORE_PARAMS)
 {
-   ASSERT(0);
+   assert(0);
 
    return GL_FALSE;
 }
@@ -1118,7 +1147,7 @@ _mesa_texstore_etc2_signed_r11_eac(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_etc2_rg11_eac(TEXSTORE_PARAMS)
 {
-   ASSERT(0);
+   assert(0);
 
    return GL_FALSE;
 }
@@ -1126,7 +1155,7 @@ _mesa_texstore_etc2_rg11_eac(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_etc2_signed_rg11_eac(TEXSTORE_PARAMS)
 {
-   ASSERT(0);
+   assert(0);
 
    return GL_FALSE;
 }
@@ -1134,7 +1163,7 @@ _mesa_texstore_etc2_signed_rg11_eac(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_etc2_rgb8_punchthrough_alpha1(TEXSTORE_PARAMS)
 {
-   ASSERT(0);
+   assert(0);
 
    return GL_FALSE;
 }
@@ -1142,7 +1171,7 @@ _mesa_texstore_etc2_rgb8_punchthrough_alpha1(TEXSTORE_PARAMS)
 GLboolean
 _mesa_texstore_etc2_srgb8_punchthrough_alpha1(TEXSTORE_PARAMS)
 {
-   ASSERT(0);
+   assert(0);
 
    return GL_FALSE;
 }
@@ -1176,7 +1205,7 @@ _mesa_unpack_etc2_format(uint8_t *dst_row,
                          unsigned src_stride,
                          unsigned src_width,
                          unsigned src_height,
-                         gl_format format)
+                         mesa_format format)
 {
    if (format == MESA_FORMAT_ETC2_RGB8)
       etc2_unpack_rgb8(dst_row, dst_stride,
@@ -1223,8 +1252,8 @@ _mesa_unpack_etc2_format(uint8_t *dst_row,
 
 
 static void
-fetch_etc1_rgb8(const GLubyte *map, const GLuint imageOffsets[],
-                GLint rowStride, GLint i, GLint j, GLint k,
+fetch_etc1_rgb8(const GLubyte *map,
+                GLint rowStride, GLint i, GLint j,
                 GLfloat *texel)
 {
    struct etc1_block block;
@@ -1244,9 +1273,8 @@ fetch_etc1_rgb8(const GLubyte *map, const GLuint imageOffsets[],
 
 
 static void
-fetch_etc2_rgb8(const GLubyte *map, const GLuint imageOffsets[],
-                GLint rowStride, GLint i, GLint j, GLint k,
-                GLfloat *texel)
+fetch_etc2_rgb8(const GLubyte *map,
+                GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    struct etc2_block block;
    uint8_t dst[3];
@@ -1266,9 +1294,8 @@ fetch_etc2_rgb8(const GLubyte *map, const GLuint imageOffsets[],
 }
 
 static void
-fetch_etc2_srgb8(const GLubyte *map, const GLuint imageOffsets[],
-                 GLint rowStride, GLint i, GLint j, GLint k,
-                 GLfloat *texel)
+fetch_etc2_srgb8(const GLubyte *map,
+                 GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    struct etc2_block block;
    uint8_t dst[3];
@@ -1281,16 +1308,15 @@ fetch_etc2_srgb8(const GLubyte *map, const GLuint imageOffsets[],
    etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst,
                          false /* punchthrough_alpha */);
 
-   texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]);
-   texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]);
-   texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]);
+   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]);
+   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]);
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]);
    texel[ACOMP] = 1.0f;
 }
 
 static void
-fetch_etc2_rgba8_eac(const GLubyte *map, const GLuint imageOffsets[],
-                     GLint rowStride, GLint i, GLint j, GLint k,
-                     GLfloat *texel)
+fetch_etc2_rgba8_eac(const GLubyte *map,
+                     GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    struct etc2_block block;
    uint8_t dst[4];
@@ -1308,9 +1334,8 @@ fetch_etc2_rgba8_eac(const GLubyte *map, const GLuint imageOffsets[],
 }
 
 static void
-fetch_etc2_srgb8_alpha8_eac(const GLubyte *map, const GLuint imageOffsets[],
-                            GLint rowStride, GLint i, GLint j, GLint k,
-                            GLfloat *texel)
+fetch_etc2_srgb8_alpha8_eac(const GLubyte *map,
+                            GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    struct etc2_block block;
    uint8_t dst[4];
@@ -1321,16 +1346,15 @@ fetch_etc2_srgb8_alpha8_eac(const GLubyte *map, const GLuint imageOffsets[],
    etc2_rgba8_parse_block(&block, src);
    etc2_rgba8_fetch_texel(&block, i % 4, j % 4, dst);
 
-   texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]);
-   texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]);
-   texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]);
+   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]);
+   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]);
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]);
    texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]);
 }
 
 static void
-fetch_etc2_r11_eac(const GLubyte *map, const GLuint imageOffsets[],
-                   GLint rowStride, GLint i, GLint j, GLint k,
-                   GLfloat *texel)
+fetch_etc2_r11_eac(const GLubyte *map,
+                   GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    struct etc2_block block;
    GLushort dst;
@@ -1348,9 +1372,8 @@ fetch_etc2_r11_eac(const GLubyte *map, const GLuint imageOffsets[],
 }
 
 static void
-fetch_etc2_rg11_eac(const GLubyte *map, const GLuint imageOffsets[],
-                    GLint rowStride, GLint i, GLint j, GLint k,
-                    GLfloat *texel)
+fetch_etc2_rg11_eac(const GLubyte *map,
+                    GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    struct etc2_block block;
    GLushort dst[2];
@@ -1373,9 +1396,8 @@ fetch_etc2_rg11_eac(const GLubyte *map, const GLuint imageOffsets[],
 }
 
 static void
-fetch_etc2_signed_r11_eac(const GLubyte *map, const GLuint imageOffsets[],
-                          GLint rowStride, GLint i, GLint j, GLint k,
-                          GLfloat *texel)
+fetch_etc2_signed_r11_eac(const GLubyte *map,
+                          GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    struct etc2_block block;
    GLushort dst;
@@ -1393,9 +1415,8 @@ fetch_etc2_signed_r11_eac(const GLubyte *map, const GLuint imageOffsets[],
 }
 
 static void
-fetch_etc2_signed_rg11_eac(const GLubyte *map, const GLuint imageOffsets[],
-                           GLint rowStride, GLint i, GLint j, GLint k,
-                           GLfloat *texel)
+fetch_etc2_signed_rg11_eac(const GLubyte *map,
+                           GLint rowStride, GLint i, GLint j, GLfloat *texel)
 {
    struct etc2_block block;
    GLushort dst[2];
@@ -1419,8 +1440,7 @@ fetch_etc2_signed_rg11_eac(const GLubyte *map, const GLuint imageOffsets[],
 
 static void
 fetch_etc2_rgb8_punchthrough_alpha1(const GLubyte *map,
-                                    const GLuint imageOffsets[],
-                                    GLint rowStride, GLint i, GLint j, GLint k,
+                                    GLint rowStride, GLint i, GLint j,
                                     GLfloat *texel)
 {
    struct etc2_block block;
@@ -1441,10 +1461,8 @@ fetch_etc2_rgb8_punchthrough_alpha1(const GLubyte *map,
 
 static void
 fetch_etc2_srgb8_punchthrough_alpha1(const GLubyte *map,
-                                     const GLuint imageOffsets[],
                                      GLint rowStride,
-                                     GLint i, GLint j, GLint k,
-                                     GLfloat *texel)
+                                     GLint i, GLint j, GLfloat *texel)
 {
    struct etc2_block block;
    uint8_t dst[4];
@@ -1456,15 +1474,15 @@ fetch_etc2_srgb8_punchthrough_alpha1(const GLubyte *map,
                          true /* punchthrough alpha */);
    etc2_rgb8_fetch_texel(&block, i % 4, j % 4, dst,
                          true /* punchthrough alpha */);
-   texel[RCOMP] = _mesa_nonlinear_to_linear(dst[0]);
-   texel[GCOMP] = _mesa_nonlinear_to_linear(dst[1]);
-   texel[BCOMP] = _mesa_nonlinear_to_linear(dst[2]);
+   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(dst[0]);
+   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(dst[1]);
+   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(dst[2]);
    texel[ACOMP] = UBYTE_TO_FLOAT(dst[3]);
 }
 
 
 compressed_fetch_func
-_mesa_get_etc_fetch_func(gl_format format)
+_mesa_get_etc_fetch_func(mesa_format format)
 {
    switch (format) {
    case MESA_FORMAT_ETC1_RGB8: