Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (C) 2011 Red Hat Inc.
  3.  *
  4.  * block compression parts are:
  5.  * Copyright (C) 2004  Roland Scheidegger   All Rights Reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  *
  14.  * The above copyright notice and this permission notice (including the next
  15.  * paragraph) shall be included in all copies or substantial portions of the
  16.  * Software.
  17.  *
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  21.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  23.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  24.  * DEALINGS IN THE SOFTWARE.
  25.  *
  26.  * Author:
  27.  *    Dave Airlie
  28.  */
  29.  
  30. /**
  31.  * \file texcompress_rgtc.c
  32.  * GL_EXT_texture_compression_rgtc support.
  33.  */
  34.  
  35.  
  36. #include "glheader.h"
  37. #include "imports.h"
  38. #include "colormac.h"
  39. #include "image.h"
  40. #include "macros.h"
  41. #include "mipmap.h"
  42. #include "texcompress.h"
  43. #include "texcompress_rgtc.h"
  44. #include "texstore.h"
  45.  
  46.  
  47. #define RGTC_DEBUG 0
  48.  
  49. static void unsigned_encode_rgtc_ubyte(GLubyte *blkaddr, GLubyte srccolors[4][4],
  50.                                         GLint numxpixels, GLint numypixels);
  51. static void signed_encode_rgtc_ubyte(GLbyte *blkaddr, GLbyte srccolors[4][4],
  52.                              GLint numxpixels, GLint numypixels);
  53.  
  54. static void unsigned_fetch_texel_rgtc(unsigned srcRowStride, const GLubyte *pixdata,
  55.                                       unsigned i, unsigned j, GLubyte *value, unsigned comps);
  56.  
  57. static void signed_fetch_texel_rgtc(unsigned srcRowStride, const GLbyte *pixdata,
  58.                                       unsigned i, unsigned j, GLbyte *value, unsigned comps);
  59.  
  60. static void extractsrc_u( GLubyte srcpixels[4][4], const GLubyte *srcaddr,
  61.                           GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
  62. {
  63.    GLubyte i, j;
  64.    const GLubyte *curaddr;
  65.    for (j = 0; j < numypixels; j++) {
  66.       curaddr = srcaddr + j * srcRowStride * comps;
  67.       for (i = 0; i < numxpixels; i++) {
  68.          srcpixels[j][i] = *curaddr;
  69.          curaddr += comps;
  70.       }
  71.    }
  72. }
  73.  
  74. static void extractsrc_s( GLbyte srcpixels[4][4], const GLfloat *srcaddr,
  75.                           GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
  76. {
  77.    GLubyte i, j;
  78.    const GLfloat *curaddr;
  79.    for (j = 0; j < numypixels; j++) {
  80.       curaddr = srcaddr + j * srcRowStride * comps;
  81.       for (i = 0; i < numxpixels; i++) {
  82.          srcpixels[j][i] = FLOAT_TO_BYTE_TEX(*curaddr);
  83.          curaddr += comps;
  84.       }
  85.    }
  86. }
  87.  
  88.  
  89. GLboolean
  90. _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS)
  91. {
  92.    GLubyte *dst;
  93.    const GLubyte *tempImage = NULL;
  94.    int i, j;
  95.    int numxpixels, numypixels;
  96.    const GLubyte *srcaddr;
  97.    GLubyte srcpixels[4][4];
  98.    GLubyte *blkaddr;
  99.    GLint dstRowDiff;
  100.    ASSERT(dstFormat == MESA_FORMAT_RED_RGTC1 ||
  101.           dstFormat == MESA_FORMAT_L_LATC1);
  102.  
  103.    tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
  104.                                           baseInternalFormat,
  105.                                           _mesa_get_format_base_format(dstFormat),
  106.                                           srcWidth, srcHeight, srcDepth,
  107.                                           srcFormat, srcType, srcAddr,
  108.                                           srcPacking);
  109.    if (!tempImage)
  110.       return GL_FALSE; /* out of memory */
  111.  
  112.    dst = dstSlices[0];
  113.  
  114.    blkaddr = dst;
  115.    dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
  116.    for (j = 0; j < srcHeight; j+=4) {
  117.       if (srcHeight > j + 3) numypixels = 4;
  118.       else numypixels = srcHeight - j;
  119.       srcaddr = tempImage + j * srcWidth;
  120.       for (i = 0; i < srcWidth; i += 4) {
  121.          if (srcWidth > i + 3) numxpixels = 4;
  122.          else numxpixels = srcWidth - i;
  123.          extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
  124.          unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
  125.          srcaddr += numxpixels;
  126.          blkaddr += 8;
  127.       }
  128.       blkaddr += dstRowDiff;
  129.    }
  130.  
  131.    free((void *) tempImage);
  132.  
  133.    return GL_TRUE;
  134. }
  135.  
  136. GLboolean
  137. _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS)
  138. {
  139.    GLbyte *dst;
  140.    const GLfloat *tempImage = NULL;
  141.    int i, j;
  142.    int numxpixels, numypixels;
  143.    const GLfloat *srcaddr;
  144.    GLbyte srcpixels[4][4];
  145.    GLbyte *blkaddr;
  146.    GLint dstRowDiff;
  147.    ASSERT(dstFormat == MESA_FORMAT_SIGNED_RED_RGTC1 ||
  148.           dstFormat == MESA_FORMAT_SIGNED_L_LATC1);
  149.  
  150.    tempImage = _mesa_make_temp_float_image(ctx, dims,
  151.                                            baseInternalFormat,
  152.                                            _mesa_get_format_base_format(dstFormat),
  153.                                            srcWidth, srcHeight, srcDepth,
  154.                                            srcFormat, srcType, srcAddr,
  155.                                            srcPacking, 0x0);
  156.    if (!tempImage)
  157.       return GL_FALSE; /* out of memory */
  158.  
  159.    dst = (GLbyte *) dstSlices[0];
  160.  
  161.    blkaddr = dst;
  162.    dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
  163.    for (j = 0; j < srcHeight; j+=4) {
  164.       if (srcHeight > j + 3) numypixels = 4;
  165.       else numypixels = srcHeight - j;
  166.       srcaddr = tempImage + j * srcWidth;
  167.       for (i = 0; i < srcWidth; i += 4) {
  168.          if (srcWidth > i + 3) numxpixels = 4;
  169.          else numxpixels = srcWidth - i;
  170.          extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
  171.          signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
  172.          srcaddr += numxpixels;
  173.          blkaddr += 8;
  174.       }
  175.       blkaddr += dstRowDiff;
  176.    }
  177.  
  178.    free((void *) tempImage);
  179.  
  180.    return GL_TRUE;
  181. }
  182.  
  183. GLboolean
  184. _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS)
  185. {
  186.    GLubyte *dst;
  187.    const GLubyte *tempImage = NULL;
  188.    int i, j;
  189.    int numxpixels, numypixels;
  190.    const GLubyte *srcaddr;
  191.    GLubyte srcpixels[4][4];
  192.    GLubyte *blkaddr;
  193.    GLint dstRowDiff;
  194.  
  195.    ASSERT(dstFormat == MESA_FORMAT_RG_RGTC2 ||
  196.           dstFormat == MESA_FORMAT_LA_LATC2);
  197.  
  198.    tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
  199.                                           baseInternalFormat,
  200.                                           _mesa_get_format_base_format(dstFormat),
  201.                                           srcWidth, srcHeight, srcDepth,
  202.                                           srcFormat, srcType, srcAddr,
  203.                                           srcPacking);
  204.    if (!tempImage)
  205.       return GL_FALSE; /* out of memory */
  206.  
  207.    dst = dstSlices[0];
  208.  
  209.    blkaddr = dst;
  210.    dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
  211.    for (j = 0; j < srcHeight; j+=4) {
  212.       if (srcHeight > j + 3) numypixels = 4;
  213.       else numypixels = srcHeight - j;
  214.       srcaddr = tempImage + j * srcWidth * 2;
  215.       for (i = 0; i < srcWidth; i += 4) {
  216.          if (srcWidth > i + 3) numxpixels = 4;
  217.          else numxpixels = srcWidth - i;
  218.          extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
  219.          unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
  220.  
  221.          blkaddr += 8;
  222.          extractsrc_u(srcpixels, (GLubyte *)srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
  223.          unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
  224.  
  225.          blkaddr += 8;
  226.  
  227.          srcaddr += numxpixels * 2;
  228.       }
  229.       blkaddr += dstRowDiff;
  230.    }
  231.  
  232.    free((void *) tempImage);
  233.  
  234.    return GL_TRUE;
  235. }
  236.  
  237. GLboolean
  238. _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS)
  239. {
  240.    GLbyte *dst;
  241.    const GLfloat *tempImage = NULL;
  242.    int i, j;
  243.    int numxpixels, numypixels;
  244.    const GLfloat *srcaddr;
  245.    GLbyte srcpixels[4][4];
  246.    GLbyte *blkaddr;
  247.    GLint dstRowDiff;
  248.  
  249.    ASSERT(dstFormat == MESA_FORMAT_SIGNED_RG_RGTC2 ||
  250.           dstFormat == MESA_FORMAT_SIGNED_LA_LATC2);
  251.  
  252.    tempImage = _mesa_make_temp_float_image(ctx, dims,
  253.                                            baseInternalFormat,
  254.                                            _mesa_get_format_base_format(dstFormat),
  255.                                            srcWidth, srcHeight, srcDepth,
  256.                                            srcFormat, srcType, srcAddr,
  257.                                            srcPacking, 0x0);
  258.    if (!tempImage)
  259.       return GL_FALSE; /* out of memory */
  260.  
  261.    dst = (GLbyte *) dstSlices[0];
  262.  
  263.    blkaddr = dst;
  264.    dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
  265.    for (j = 0; j < srcHeight; j += 4) {
  266.       if (srcHeight > j + 3) numypixels = 4;
  267.       else numypixels = srcHeight - j;
  268.       srcaddr = tempImage + j * srcWidth * 2;
  269.       for (i = 0; i < srcWidth; i += 4) {
  270.          if (srcWidth > i + 3) numxpixels = 4;
  271.          else numxpixels = srcWidth - i;
  272.  
  273.          extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
  274.          signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
  275.          blkaddr += 8;
  276.  
  277.          extractsrc_s(srcpixels, srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
  278.          signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
  279.          blkaddr += 8;
  280.  
  281.          srcaddr += numxpixels * 2;
  282.  
  283.       }
  284.       blkaddr += dstRowDiff;
  285.    }
  286.  
  287.    free((void *) tempImage);
  288.  
  289.    return GL_TRUE;
  290. }
  291.  
  292.  
  293. #define TAG(x) unsigned_##x
  294.  
  295. #define TYPE GLubyte
  296. #define T_MIN 0
  297. #define T_MAX 0xff
  298.  
  299. #include "texcompress_rgtc_tmp.h"
  300.  
  301. #undef TAG
  302. #undef TYPE
  303. #undef T_MIN
  304. #undef T_MAX
  305.  
  306. #define TAG(x) signed_##x
  307. #define TYPE GLbyte
  308. #define T_MIN (GLbyte)-128
  309. #define T_MAX (GLbyte)127
  310.  
  311. #include "texcompress_rgtc_tmp.h"
  312.  
  313. #undef TAG
  314. #undef TYPE
  315. #undef T_MIN
  316. #undef T_MAX
  317.  
  318.  
  319.  
  320. static void
  321. fetch_red_rgtc1(const GLubyte *map,
  322.                 GLint rowStride, GLint i, GLint j, GLfloat *texel)
  323. {
  324.    GLubyte red;
  325.    unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
  326.    texel[RCOMP] = UBYTE_TO_FLOAT(red);
  327.    texel[GCOMP] = 0.0;
  328.    texel[BCOMP] = 0.0;
  329.    texel[ACOMP] = 1.0;
  330. }
  331.  
  332. static void
  333. fetch_l_latc1(const GLubyte *map,
  334.               GLint rowStride, GLint i, GLint j, GLfloat *texel)
  335. {
  336.    GLubyte red;
  337.    unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
  338.    texel[RCOMP] =
  339.    texel[GCOMP] =
  340.    texel[BCOMP] = UBYTE_TO_FLOAT(red);
  341.    texel[ACOMP] = 1.0;
  342. }
  343.  
  344. static void
  345. fetch_signed_red_rgtc1(const GLubyte *map,
  346.                        GLint rowStride, GLint i, GLint j, GLfloat *texel)
  347. {
  348.    GLbyte red;
  349.    signed_fetch_texel_rgtc(rowStride, (const GLbyte *) map,
  350.                            i, j, &red, 1);
  351.    texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
  352.    texel[GCOMP] = 0.0;
  353.    texel[BCOMP] = 0.0;
  354.    texel[ACOMP] = 1.0;
  355. }
  356.  
  357. static void
  358. fetch_signed_l_latc1(const GLubyte *map,
  359.                      GLint rowStride, GLint i, GLint j, GLfloat *texel)
  360. {
  361.    GLbyte red;
  362.    signed_fetch_texel_rgtc(rowStride, (GLbyte *) map,
  363.                            i, j, &red, 1);
  364.    texel[RCOMP] =
  365.    texel[GCOMP] =
  366.    texel[BCOMP] = BYTE_TO_FLOAT(red);
  367.    texel[ACOMP] = 1.0;
  368. }
  369.  
  370. static void
  371. fetch_rg_rgtc2(const GLubyte *map,
  372.                GLint rowStride, GLint i, GLint j, GLfloat *texel)
  373. {
  374.    GLubyte red, green;
  375.    unsigned_fetch_texel_rgtc(rowStride,
  376.                              map,
  377.                              i, j, &red, 2);
  378.    unsigned_fetch_texel_rgtc(rowStride,
  379.                              map + 8,
  380.                              i, j, &green, 2);
  381.    texel[RCOMP] = UBYTE_TO_FLOAT(red);
  382.    texel[GCOMP] = UBYTE_TO_FLOAT(green);
  383.    texel[BCOMP] = 0.0;
  384.    texel[ACOMP] = 1.0;
  385. }
  386.  
  387. static void
  388. fetch_la_latc2(const GLubyte *map,
  389.                GLint rowStride, GLint i, GLint j, GLfloat *texel)
  390. {
  391.    GLubyte red, green;
  392.    unsigned_fetch_texel_rgtc(rowStride,
  393.                              map,
  394.                              i, j, &red, 2);
  395.    unsigned_fetch_texel_rgtc(rowStride,
  396.                              map + 8,
  397.                              i, j, &green, 2);
  398.    texel[RCOMP] =
  399.    texel[GCOMP] =
  400.    texel[BCOMP] = UBYTE_TO_FLOAT(red);
  401.    texel[ACOMP] = UBYTE_TO_FLOAT(green);
  402. }
  403.  
  404.  
  405. static void
  406. fetch_signed_rg_rgtc2(const GLubyte *map,
  407.                       GLint rowStride, GLint i, GLint j, GLfloat *texel)
  408. {
  409.    GLbyte red, green;
  410.    signed_fetch_texel_rgtc(rowStride,
  411.                            (GLbyte *) map,
  412.                            i, j, &red, 2);
  413.    signed_fetch_texel_rgtc(rowStride,
  414.                            (GLbyte *) map + 8,
  415.                            i, j, &green, 2);
  416.    texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
  417.    texel[GCOMP] = BYTE_TO_FLOAT_TEX(green);
  418.    texel[BCOMP] = 0.0;
  419.    texel[ACOMP] = 1.0;
  420. }
  421.  
  422.  
  423. static void
  424. fetch_signed_la_latc2(const GLubyte *map,
  425.                       GLint rowStride, GLint i, GLint j, GLfloat *texel)
  426. {
  427.    GLbyte red, green;
  428.    signed_fetch_texel_rgtc(rowStride,
  429.                            (GLbyte *) map,
  430.                            i, j, &red, 2);
  431.    signed_fetch_texel_rgtc(rowStride,
  432.                            (GLbyte *) map + 8,
  433.                            i, j, &green, 2);
  434.    texel[RCOMP] =
  435.    texel[GCOMP] =
  436.    texel[BCOMP] = BYTE_TO_FLOAT_TEX(red);
  437.    texel[ACOMP] = BYTE_TO_FLOAT_TEX(green);
  438. }
  439.  
  440.  
  441. compressed_fetch_func
  442. _mesa_get_compressed_rgtc_func(gl_format format)
  443. {
  444.    switch (format) {
  445.    case MESA_FORMAT_RED_RGTC1:
  446.       return fetch_red_rgtc1;
  447.    case MESA_FORMAT_L_LATC1:
  448.       return fetch_l_latc1;
  449.    case MESA_FORMAT_SIGNED_RED_RGTC1:
  450.       return fetch_signed_red_rgtc1;
  451.    case MESA_FORMAT_SIGNED_L_LATC1:
  452.       return fetch_signed_l_latc1;
  453.    case MESA_FORMAT_RG_RGTC2:
  454.       return fetch_rg_rgtc2;
  455.    case MESA_FORMAT_LA_LATC2:
  456.       return fetch_la_latc2;
  457.    case MESA_FORMAT_SIGNED_RG_RGTC2:
  458.       return fetch_signed_rg_rgtc2;
  459.    case MESA_FORMAT_SIGNED_LA_LATC2:
  460.       return fetch_signed_la_latc2;
  461.    default:
  462.       return NULL;
  463.    }
  464. }
  465.