Subversion Repositories Kolibri OS

Rev

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 "image.h"
  39. #include "macros.h"
  40. #include "mipmap.h"
  41. #include "texcompress.h"
  42. #include "util/rgtc.h"
  43. #include "texcompress_rgtc.h"
  44. #include "texstore.h"
  45.  
  46. static void extractsrc_u( GLubyte srcpixels[4][4], const GLubyte *srcaddr,
  47.                           GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
  48. {
  49.    GLubyte i, j;
  50.    const GLubyte *curaddr;
  51.    for (j = 0; j < numypixels; j++) {
  52.       curaddr = srcaddr + j * srcRowStride * comps;
  53.       for (i = 0; i < numxpixels; i++) {
  54.          srcpixels[j][i] = *curaddr;
  55.          curaddr += comps;
  56.       }
  57.    }
  58. }
  59.  
  60. static void extractsrc_s( GLbyte srcpixels[4][4], const GLfloat *srcaddr,
  61.                           GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
  62. {
  63.    GLubyte i, j;
  64.    const GLfloat *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] = FLOAT_TO_BYTE_TEX(*curaddr);
  69.          curaddr += comps;
  70.       }
  71.    }
  72. }
  73.  
  74.  
  75. GLboolean
  76. _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS)
  77. {
  78.    GLubyte *dst;
  79.    const GLubyte *tempImage = NULL;
  80.    int i, j;
  81.    int numxpixels, numypixels;
  82.    const GLubyte *srcaddr;
  83.    GLubyte srcpixels[4][4];
  84.    GLubyte *blkaddr;
  85.    GLint dstRowDiff, redRowStride;
  86.    GLubyte *tempImageSlices[1];
  87.  
  88.    assert(dstFormat == MESA_FORMAT_R_RGTC1_UNORM ||
  89.           dstFormat == MESA_FORMAT_L_LATC1_UNORM);
  90.  
  91.    tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLubyte));
  92.    if (!tempImage)
  93.       return GL_FALSE; /* out of memory */
  94.    redRowStride = 1 * srcWidth * sizeof(GLubyte);
  95.    tempImageSlices[0] = (GLubyte *) tempImage;
  96.    _mesa_texstore(ctx, dims,
  97.                   baseInternalFormat,
  98.                   MESA_FORMAT_R_UNORM8,
  99.                   redRowStride, tempImageSlices,
  100.                   srcWidth, srcHeight, srcDepth,
  101.                   srcFormat, srcType, srcAddr,
  102.                   srcPacking);
  103.  
  104.    dst = dstSlices[0];
  105.  
  106.    blkaddr = dst;
  107.    dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
  108.    for (j = 0; j < srcHeight; j+=4) {
  109.       if (srcHeight > j + 3) numypixels = 4;
  110.       else numypixels = srcHeight - j;
  111.       srcaddr = tempImage + j * srcWidth;
  112.       for (i = 0; i < srcWidth; i += 4) {
  113.          if (srcWidth > i + 3) numxpixels = 4;
  114.          else numxpixels = srcWidth - i;
  115.          extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
  116.          util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
  117.          srcaddr += numxpixels;
  118.          blkaddr += 8;
  119.       }
  120.       blkaddr += dstRowDiff;
  121.    }
  122.  
  123.    free((void *) tempImage);
  124.  
  125.    return GL_TRUE;
  126. }
  127.  
  128. GLboolean
  129. _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS)
  130. {
  131.    GLbyte *dst;
  132.    const GLfloat *tempImage = NULL;
  133.    int i, j;
  134.    int numxpixels, numypixels;
  135.    const GLfloat *srcaddr;
  136.    GLbyte srcpixels[4][4];
  137.    GLbyte *blkaddr;
  138.    GLint dstRowDiff, redRowStride;
  139.    GLfloat *tempImageSlices[1];
  140.  
  141.    assert(dstFormat == MESA_FORMAT_R_RGTC1_SNORM ||
  142.           dstFormat == MESA_FORMAT_L_LATC1_SNORM);
  143.  
  144.    redRowStride = 1 * srcWidth * sizeof(GLfloat);
  145.    tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLfloat));
  146.    if (!tempImage)
  147.       return GL_FALSE; /* out of memory */
  148.    tempImageSlices[0] = (GLfloat *) tempImage;
  149.    _mesa_texstore(ctx, dims,
  150.                   baseInternalFormat,
  151.                   MESA_FORMAT_R_FLOAT32,
  152.                   redRowStride, (GLubyte **)tempImageSlices,
  153.                   srcWidth, srcHeight, srcDepth,
  154.                   srcFormat, srcType, srcAddr,
  155.                   srcPacking);
  156.  
  157.    dst = (GLbyte *) dstSlices[0];
  158.  
  159.    blkaddr = dst;
  160.    dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
  161.    for (j = 0; j < srcHeight; j+=4) {
  162.       if (srcHeight > j + 3) numypixels = 4;
  163.       else numypixels = srcHeight - j;
  164.       srcaddr = tempImage + j * srcWidth;
  165.       for (i = 0; i < srcWidth; i += 4) {
  166.          if (srcWidth > i + 3) numxpixels = 4;
  167.          else numxpixels = srcWidth - i;
  168.          extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
  169.          util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
  170.          srcaddr += numxpixels;
  171.          blkaddr += 8;
  172.       }
  173.       blkaddr += dstRowDiff;
  174.    }
  175.  
  176.    free((void *) tempImage);
  177.  
  178.    return GL_TRUE;
  179. }
  180.  
  181. GLboolean
  182. _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS)
  183. {
  184.    GLubyte *dst;
  185.    const GLubyte *tempImage = NULL;
  186.    int i, j;
  187.    int numxpixels, numypixels;
  188.    const GLubyte *srcaddr;
  189.    GLubyte srcpixels[4][4];
  190.    GLubyte *blkaddr;
  191.    GLint dstRowDiff, rgRowStride;
  192.    mesa_format tempFormat;
  193.    GLubyte *tempImageSlices[1];
  194.  
  195.    assert(dstFormat == MESA_FORMAT_RG_RGTC2_UNORM ||
  196.           dstFormat == MESA_FORMAT_LA_LATC2_UNORM);
  197.  
  198.    if (baseInternalFormat == GL_RG)
  199.       tempFormat = MESA_FORMAT_R8G8_UNORM;
  200.    else
  201.       tempFormat = MESA_FORMAT_L8A8_UNORM;
  202.  
  203.    rgRowStride = 2 * srcWidth * sizeof(GLubyte);
  204.    tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLubyte));
  205.    if (!tempImage)
  206.       return GL_FALSE; /* out of memory */
  207.    tempImageSlices[0] = (GLubyte *) tempImage;
  208.    _mesa_texstore(ctx, dims,
  209.                   baseInternalFormat,
  210.                   tempFormat,
  211.                   rgRowStride, tempImageSlices,
  212.                   srcWidth, srcHeight, srcDepth,
  213.                   srcFormat, srcType, srcAddr,
  214.                   srcPacking);
  215.  
  216.    dst = dstSlices[0];
  217.  
  218.    blkaddr = dst;
  219.    dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
  220.    for (j = 0; j < srcHeight; j+=4) {
  221.       if (srcHeight > j + 3) numypixels = 4;
  222.       else numypixels = srcHeight - j;
  223.       srcaddr = tempImage + j * srcWidth * 2;
  224.       for (i = 0; i < srcWidth; i += 4) {
  225.          if (srcWidth > i + 3) numxpixels = 4;
  226.          else numxpixels = srcWidth - i;
  227.          extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
  228.          util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
  229.  
  230.          blkaddr += 8;
  231.          extractsrc_u(srcpixels, (GLubyte *)srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
  232.          util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
  233.  
  234.          blkaddr += 8;
  235.  
  236.          srcaddr += numxpixels * 2;
  237.       }
  238.       blkaddr += dstRowDiff;
  239.    }
  240.  
  241.    free((void *) tempImage);
  242.  
  243.    return GL_TRUE;
  244. }
  245.  
  246. GLboolean
  247. _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS)
  248. {
  249.    GLbyte *dst;
  250.    const GLfloat *tempImage = NULL;
  251.    int i, j;
  252.    int numxpixels, numypixels;
  253.    const GLfloat *srcaddr;
  254.    GLbyte srcpixels[4][4];
  255.    GLbyte *blkaddr;
  256.    GLint dstRowDiff, rgRowStride;
  257.    mesa_format tempFormat;
  258.    GLfloat *tempImageSlices[1];
  259.  
  260.    assert(dstFormat == MESA_FORMAT_RG_RGTC2_SNORM ||
  261.           dstFormat == MESA_FORMAT_LA_LATC2_SNORM);
  262.  
  263.    if (baseInternalFormat == GL_RG)
  264.       tempFormat = MESA_FORMAT_RG_FLOAT32;
  265.    else
  266.       tempFormat = MESA_FORMAT_LA_FLOAT32;
  267.  
  268.    rgRowStride = 2 * srcWidth * sizeof(GLfloat);
  269.    tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLfloat));
  270.    if (!tempImage)
  271.       return GL_FALSE; /* out of memory */
  272.    tempImageSlices[0] = (GLfloat *) tempImage;
  273.    _mesa_texstore(ctx, dims,
  274.                   baseInternalFormat,
  275.                   tempFormat,
  276.                   rgRowStride, (GLubyte **)tempImageSlices,
  277.                   srcWidth, srcHeight, srcDepth,
  278.                   srcFormat, srcType, srcAddr,
  279.                   srcPacking);
  280.  
  281.    dst = (GLbyte *) dstSlices[0];
  282.  
  283.    blkaddr = dst;
  284.    dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
  285.    for (j = 0; j < srcHeight; j += 4) {
  286.       if (srcHeight > j + 3) numypixels = 4;
  287.       else numypixels = srcHeight - j;
  288.       srcaddr = tempImage + j * srcWidth * 2;
  289.       for (i = 0; i < srcWidth; i += 4) {
  290.          if (srcWidth > i + 3) numxpixels = 4;
  291.          else numxpixels = srcWidth - i;
  292.  
  293.          extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
  294.          util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
  295.          blkaddr += 8;
  296.  
  297.          extractsrc_s(srcpixels, srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
  298.          util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
  299.          blkaddr += 8;
  300.  
  301.          srcaddr += numxpixels * 2;
  302.  
  303.       }
  304.       blkaddr += dstRowDiff;
  305.    }
  306.  
  307.    free((void *) tempImage);
  308.  
  309.    return GL_TRUE;
  310. }
  311.  
  312. static void
  313. fetch_red_rgtc1(const GLubyte *map,
  314.                 GLint rowStride, GLint i, GLint j, GLfloat *texel)
  315. {
  316.    GLubyte red;
  317.    util_format_unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
  318.    texel[RCOMP] = UBYTE_TO_FLOAT(red);
  319.    texel[GCOMP] = 0.0;
  320.    texel[BCOMP] = 0.0;
  321.    texel[ACOMP] = 1.0;
  322. }
  323.  
  324. static void
  325. fetch_l_latc1(const GLubyte *map,
  326.               GLint rowStride, GLint i, GLint j, GLfloat *texel)
  327. {
  328.    GLubyte red;
  329.    util_format_unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
  330.    texel[RCOMP] =
  331.    texel[GCOMP] =
  332.    texel[BCOMP] = UBYTE_TO_FLOAT(red);
  333.    texel[ACOMP] = 1.0;
  334. }
  335.  
  336. static void
  337. fetch_signed_red_rgtc1(const GLubyte *map,
  338.                        GLint rowStride, GLint i, GLint j, GLfloat *texel)
  339. {
  340.    GLbyte red;
  341.    util_format_signed_fetch_texel_rgtc(rowStride, (const GLbyte *) map,
  342.                            i, j, &red, 1);
  343.    texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
  344.    texel[GCOMP] = 0.0;
  345.    texel[BCOMP] = 0.0;
  346.    texel[ACOMP] = 1.0;
  347. }
  348.  
  349. static void
  350. fetch_signed_l_latc1(const GLubyte *map,
  351.                      GLint rowStride, GLint i, GLint j, GLfloat *texel)
  352. {
  353.    GLbyte red;
  354.    util_format_signed_fetch_texel_rgtc(rowStride, (GLbyte *) map,
  355.                            i, j, &red, 1);
  356.    texel[RCOMP] =
  357.    texel[GCOMP] =
  358.    texel[BCOMP] = BYTE_TO_FLOAT(red);
  359.    texel[ACOMP] = 1.0;
  360. }
  361.  
  362. static void
  363. fetch_rg_rgtc2(const GLubyte *map,
  364.                GLint rowStride, GLint i, GLint j, GLfloat *texel)
  365. {
  366.    GLubyte red, green;
  367.    util_format_unsigned_fetch_texel_rgtc(rowStride,
  368.                              map,
  369.                              i, j, &red, 2);
  370.    util_format_unsigned_fetch_texel_rgtc(rowStride,
  371.                              map + 8,
  372.                              i, j, &green, 2);
  373.    texel[RCOMP] = UBYTE_TO_FLOAT(red);
  374.    texel[GCOMP] = UBYTE_TO_FLOAT(green);
  375.    texel[BCOMP] = 0.0;
  376.    texel[ACOMP] = 1.0;
  377. }
  378.  
  379. static void
  380. fetch_la_latc2(const GLubyte *map,
  381.                GLint rowStride, GLint i, GLint j, GLfloat *texel)
  382. {
  383.    GLubyte red, green;
  384.    util_format_unsigned_fetch_texel_rgtc(rowStride,
  385.                              map,
  386.                              i, j, &red, 2);
  387.    util_format_unsigned_fetch_texel_rgtc(rowStride,
  388.                              map + 8,
  389.                              i, j, &green, 2);
  390.    texel[RCOMP] =
  391.    texel[GCOMP] =
  392.    texel[BCOMP] = UBYTE_TO_FLOAT(red);
  393.    texel[ACOMP] = UBYTE_TO_FLOAT(green);
  394. }
  395.  
  396.  
  397. static void
  398. fetch_signed_rg_rgtc2(const GLubyte *map,
  399.                       GLint rowStride, GLint i, GLint j, GLfloat *texel)
  400. {
  401.    GLbyte red, green;
  402.    util_format_signed_fetch_texel_rgtc(rowStride,
  403.                            (GLbyte *) map,
  404.                            i, j, &red, 2);
  405.    util_format_signed_fetch_texel_rgtc(rowStride,
  406.                            (GLbyte *) map + 8,
  407.                            i, j, &green, 2);
  408.    texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
  409.    texel[GCOMP] = BYTE_TO_FLOAT_TEX(green);
  410.    texel[BCOMP] = 0.0;
  411.    texel[ACOMP] = 1.0;
  412. }
  413.  
  414.  
  415. static void
  416. fetch_signed_la_latc2(const GLubyte *map,
  417.                       GLint rowStride, GLint i, GLint j, GLfloat *texel)
  418. {
  419.    GLbyte red, green;
  420.    util_format_signed_fetch_texel_rgtc(rowStride,
  421.                            (GLbyte *) map,
  422.                            i, j, &red, 2);
  423.    util_format_signed_fetch_texel_rgtc(rowStride,
  424.                            (GLbyte *) map + 8,
  425.                            i, j, &green, 2);
  426.    texel[RCOMP] =
  427.    texel[GCOMP] =
  428.    texel[BCOMP] = BYTE_TO_FLOAT_TEX(red);
  429.    texel[ACOMP] = BYTE_TO_FLOAT_TEX(green);
  430. }
  431.  
  432.  
  433. compressed_fetch_func
  434. _mesa_get_compressed_rgtc_func(mesa_format format)
  435. {
  436.    switch (format) {
  437.    case MESA_FORMAT_R_RGTC1_UNORM:
  438.       return fetch_red_rgtc1;
  439.    case MESA_FORMAT_L_LATC1_UNORM:
  440.       return fetch_l_latc1;
  441.    case MESA_FORMAT_R_RGTC1_SNORM:
  442.       return fetch_signed_red_rgtc1;
  443.    case MESA_FORMAT_L_LATC1_SNORM:
  444.       return fetch_signed_l_latc1;
  445.    case MESA_FORMAT_RG_RGTC2_UNORM:
  446.       return fetch_rg_rgtc2;
  447.    case MESA_FORMAT_LA_LATC2_UNORM:
  448.       return fetch_la_latc2;
  449.    case MESA_FORMAT_RG_RGTC2_SNORM:
  450.       return fetch_signed_rg_rgtc2;
  451.    case MESA_FORMAT_LA_LATC2_SNORM:
  452.       return fetch_signed_la_latc2;
  453.    default:
  454.       return NULL;
  455.    }
  456. }
  457.