1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright (C) 2014 Intel Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci/** 25bf215546Sopenharmony_ci * \file texcompress_bptc.c 26bf215546Sopenharmony_ci * GL_ARB_texture_compression_bptc support. 27bf215546Sopenharmony_ci */ 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include <stdbool.h> 30bf215546Sopenharmony_ci#include "texcompress.h" 31bf215546Sopenharmony_ci#include "texcompress_bptc.h" 32bf215546Sopenharmony_ci#include "texcompress_bptc_tmp.h" 33bf215546Sopenharmony_ci#include "texstore.h" 34bf215546Sopenharmony_ci#include "image.h" 35bf215546Sopenharmony_ci#include "mtypes.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_cistatic void 38bf215546Sopenharmony_cifetch_bptc_rgb_float(const GLubyte *map, 39bf215546Sopenharmony_ci GLint rowStride, GLint i, GLint j, 40bf215546Sopenharmony_ci GLfloat *texel, 41bf215546Sopenharmony_ci bool is_signed) 42bf215546Sopenharmony_ci{ 43bf215546Sopenharmony_ci const GLubyte *block; 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci block = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci fetch_rgb_float_from_block(block, texel, (i % 4) + (j % 4) * 4, is_signed); 48bf215546Sopenharmony_ci} 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_cistatic void 51bf215546Sopenharmony_cifetch_bptc_rgb_signed_float(const GLubyte *map, 52bf215546Sopenharmony_ci GLint rowStride, GLint i, GLint j, 53bf215546Sopenharmony_ci GLfloat *texel) 54bf215546Sopenharmony_ci{ 55bf215546Sopenharmony_ci fetch_bptc_rgb_float(map, rowStride, i, j, texel, true); 56bf215546Sopenharmony_ci} 57bf215546Sopenharmony_ci 58bf215546Sopenharmony_cistatic void 59bf215546Sopenharmony_cifetch_bptc_rgb_unsigned_float(const GLubyte *map, 60bf215546Sopenharmony_ci GLint rowStride, GLint i, GLint j, 61bf215546Sopenharmony_ci GLfloat *texel) 62bf215546Sopenharmony_ci{ 63bf215546Sopenharmony_ci fetch_bptc_rgb_float(map, rowStride, i, j, texel, false); 64bf215546Sopenharmony_ci} 65bf215546Sopenharmony_ci 66bf215546Sopenharmony_cistatic void 67bf215546Sopenharmony_cifetch_bptc_rgba_unorm_bytes(const GLubyte *map, 68bf215546Sopenharmony_ci GLint rowStride, GLint i, GLint j, 69bf215546Sopenharmony_ci GLubyte *texel) 70bf215546Sopenharmony_ci{ 71bf215546Sopenharmony_ci const GLubyte *block; 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_ci block = map + (((rowStride + 3) / 4) * (j / 4) + (i / 4)) * 16; 74bf215546Sopenharmony_ci 75bf215546Sopenharmony_ci fetch_rgba_unorm_from_block(block, texel, (i % 4) + (j % 4) * 4); 76bf215546Sopenharmony_ci} 77bf215546Sopenharmony_ci 78bf215546Sopenharmony_cistatic void 79bf215546Sopenharmony_cifetch_bptc_rgba_unorm(const GLubyte *map, 80bf215546Sopenharmony_ci GLint rowStride, GLint i, GLint j, 81bf215546Sopenharmony_ci GLfloat *texel) 82bf215546Sopenharmony_ci{ 83bf215546Sopenharmony_ci GLubyte texel_bytes[4]; 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_ci fetch_bptc_rgba_unorm_bytes(map, rowStride, i, j, texel_bytes); 86bf215546Sopenharmony_ci 87bf215546Sopenharmony_ci texel[RCOMP] = UBYTE_TO_FLOAT(texel_bytes[0]); 88bf215546Sopenharmony_ci texel[GCOMP] = UBYTE_TO_FLOAT(texel_bytes[1]); 89bf215546Sopenharmony_ci texel[BCOMP] = UBYTE_TO_FLOAT(texel_bytes[2]); 90bf215546Sopenharmony_ci texel[ACOMP] = UBYTE_TO_FLOAT(texel_bytes[3]); 91bf215546Sopenharmony_ci} 92bf215546Sopenharmony_ci 93bf215546Sopenharmony_cistatic void 94bf215546Sopenharmony_cifetch_bptc_srgb_alpha_unorm(const GLubyte *map, 95bf215546Sopenharmony_ci GLint rowStride, GLint i, GLint j, 96bf215546Sopenharmony_ci GLfloat *texel) 97bf215546Sopenharmony_ci{ 98bf215546Sopenharmony_ci GLubyte texel_bytes[4]; 99bf215546Sopenharmony_ci 100bf215546Sopenharmony_ci fetch_bptc_rgba_unorm_bytes(map, rowStride, i, j, texel_bytes); 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(texel_bytes[0]); 103bf215546Sopenharmony_ci texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(texel_bytes[1]); 104bf215546Sopenharmony_ci texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(texel_bytes[2]); 105bf215546Sopenharmony_ci texel[ACOMP] = UBYTE_TO_FLOAT(texel_bytes[3]); 106bf215546Sopenharmony_ci} 107bf215546Sopenharmony_ci 108bf215546Sopenharmony_cicompressed_fetch_func 109bf215546Sopenharmony_ci_mesa_get_bptc_fetch_func(mesa_format format) 110bf215546Sopenharmony_ci{ 111bf215546Sopenharmony_ci switch (format) { 112bf215546Sopenharmony_ci case MESA_FORMAT_BPTC_RGBA_UNORM: 113bf215546Sopenharmony_ci return fetch_bptc_rgba_unorm; 114bf215546Sopenharmony_ci case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM: 115bf215546Sopenharmony_ci return fetch_bptc_srgb_alpha_unorm; 116bf215546Sopenharmony_ci case MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT: 117bf215546Sopenharmony_ci return fetch_bptc_rgb_signed_float; 118bf215546Sopenharmony_ci case MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT: 119bf215546Sopenharmony_ci return fetch_bptc_rgb_unsigned_float; 120bf215546Sopenharmony_ci default: 121bf215546Sopenharmony_ci return NULL; 122bf215546Sopenharmony_ci } 123bf215546Sopenharmony_ci} 124bf215546Sopenharmony_ci 125bf215546Sopenharmony_ciGLboolean 126bf215546Sopenharmony_ci_mesa_texstore_bptc_rgba_unorm(TEXSTORE_PARAMS) 127bf215546Sopenharmony_ci{ 128bf215546Sopenharmony_ci const GLubyte *pixels; 129bf215546Sopenharmony_ci const GLubyte *tempImage = NULL; 130bf215546Sopenharmony_ci int rowstride; 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci if (srcFormat != GL_RGBA || 133bf215546Sopenharmony_ci srcType != GL_UNSIGNED_BYTE || 134bf215546Sopenharmony_ci ctx->_ImageTransferState || 135bf215546Sopenharmony_ci srcPacking->SwapBytes) { 136bf215546Sopenharmony_ci /* convert image to RGBA/ubyte */ 137bf215546Sopenharmony_ci GLubyte *tempImageSlices[1]; 138bf215546Sopenharmony_ci int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); 139bf215546Sopenharmony_ci tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte)); 140bf215546Sopenharmony_ci if (!tempImage) 141bf215546Sopenharmony_ci return GL_FALSE; /* out of memory */ 142bf215546Sopenharmony_ci tempImageSlices[0] = (GLubyte *) tempImage; 143bf215546Sopenharmony_ci _mesa_texstore(ctx, dims, 144bf215546Sopenharmony_ci baseInternalFormat, 145bf215546Sopenharmony_ci#if UTIL_ARCH_LITTLE_ENDIAN 146bf215546Sopenharmony_ci MESA_FORMAT_R8G8B8A8_UNORM, 147bf215546Sopenharmony_ci#else 148bf215546Sopenharmony_ci MESA_FORMAT_A8B8G8R8_UNORM, 149bf215546Sopenharmony_ci#endif 150bf215546Sopenharmony_ci rgbaRowStride, tempImageSlices, 151bf215546Sopenharmony_ci srcWidth, srcHeight, srcDepth, 152bf215546Sopenharmony_ci srcFormat, srcType, srcAddr, 153bf215546Sopenharmony_ci srcPacking); 154bf215546Sopenharmony_ci 155bf215546Sopenharmony_ci pixels = tempImage; 156bf215546Sopenharmony_ci rowstride = srcWidth * 4; 157bf215546Sopenharmony_ci } else { 158bf215546Sopenharmony_ci pixels = _mesa_image_address2d(srcPacking, srcAddr, srcWidth, srcHeight, 159bf215546Sopenharmony_ci srcFormat, srcType, 0, 0); 160bf215546Sopenharmony_ci rowstride = _mesa_image_row_stride(srcPacking, srcWidth, 161bf215546Sopenharmony_ci srcFormat, srcType); 162bf215546Sopenharmony_ci } 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci compress_rgba_unorm(srcWidth, srcHeight, 165bf215546Sopenharmony_ci pixels, rowstride, 166bf215546Sopenharmony_ci dstSlices[0], dstRowStride); 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci free((void *) tempImage); 169bf215546Sopenharmony_ci 170bf215546Sopenharmony_ci return GL_TRUE; 171bf215546Sopenharmony_ci} 172bf215546Sopenharmony_ci 173bf215546Sopenharmony_cistatic GLboolean 174bf215546Sopenharmony_citexstore_bptc_rgb_float(TEXSTORE_PARAMS, 175bf215546Sopenharmony_ci bool is_signed) 176bf215546Sopenharmony_ci{ 177bf215546Sopenharmony_ci const float *pixels; 178bf215546Sopenharmony_ci const float *tempImage = NULL; 179bf215546Sopenharmony_ci int rowstride; 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci if (srcFormat != GL_RGB || 182bf215546Sopenharmony_ci srcType != GL_FLOAT || 183bf215546Sopenharmony_ci ctx->_ImageTransferState || 184bf215546Sopenharmony_ci srcPacking->SwapBytes) { 185bf215546Sopenharmony_ci /* convert image to RGB/float */ 186bf215546Sopenharmony_ci GLfloat *tempImageSlices[1]; 187bf215546Sopenharmony_ci int rgbRowStride = 3 * srcWidth * sizeof(GLfloat); 188bf215546Sopenharmony_ci tempImage = malloc(srcWidth * srcHeight * 3 * sizeof(GLfloat)); 189bf215546Sopenharmony_ci if (!tempImage) 190bf215546Sopenharmony_ci return GL_FALSE; /* out of memory */ 191bf215546Sopenharmony_ci tempImageSlices[0] = (GLfloat *) tempImage; 192bf215546Sopenharmony_ci _mesa_texstore(ctx, dims, 193bf215546Sopenharmony_ci baseInternalFormat, 194bf215546Sopenharmony_ci MESA_FORMAT_RGB_FLOAT32, 195bf215546Sopenharmony_ci rgbRowStride, (GLubyte **)tempImageSlices, 196bf215546Sopenharmony_ci srcWidth, srcHeight, srcDepth, 197bf215546Sopenharmony_ci srcFormat, srcType, srcAddr, 198bf215546Sopenharmony_ci srcPacking); 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci pixels = tempImage; 201bf215546Sopenharmony_ci rowstride = srcWidth * sizeof(float) * 3; 202bf215546Sopenharmony_ci } else { 203bf215546Sopenharmony_ci pixels = _mesa_image_address2d(srcPacking, srcAddr, srcWidth, srcHeight, 204bf215546Sopenharmony_ci srcFormat, srcType, 0, 0); 205bf215546Sopenharmony_ci rowstride = _mesa_image_row_stride(srcPacking, srcWidth, 206bf215546Sopenharmony_ci srcFormat, srcType); 207bf215546Sopenharmony_ci } 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci compress_rgb_float(srcWidth, srcHeight, 210bf215546Sopenharmony_ci pixels, rowstride, 211bf215546Sopenharmony_ci dstSlices[0], dstRowStride, 212bf215546Sopenharmony_ci is_signed); 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci free((void *) tempImage); 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_ci return GL_TRUE; 217bf215546Sopenharmony_ci} 218bf215546Sopenharmony_ci 219bf215546Sopenharmony_ciGLboolean 220bf215546Sopenharmony_ci_mesa_texstore_bptc_rgb_signed_float(TEXSTORE_PARAMS) 221bf215546Sopenharmony_ci{ 222bf215546Sopenharmony_ci assert(dstFormat == MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT); 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci return texstore_bptc_rgb_float(ctx, dims, baseInternalFormat, 225bf215546Sopenharmony_ci dstFormat, dstRowStride, dstSlices, 226bf215546Sopenharmony_ci srcWidth, srcHeight, srcDepth, 227bf215546Sopenharmony_ci srcFormat, srcType, 228bf215546Sopenharmony_ci srcAddr, srcPacking, 229bf215546Sopenharmony_ci true /* signed */); 230bf215546Sopenharmony_ci} 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ciGLboolean 233bf215546Sopenharmony_ci_mesa_texstore_bptc_rgb_unsigned_float(TEXSTORE_PARAMS) 234bf215546Sopenharmony_ci{ 235bf215546Sopenharmony_ci assert(dstFormat == MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT); 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci return texstore_bptc_rgb_float(ctx, dims, baseInternalFormat, 238bf215546Sopenharmony_ci dstFormat, dstRowStride, dstSlices, 239bf215546Sopenharmony_ci srcWidth, srcHeight, srcDepth, 240bf215546Sopenharmony_ci srcFormat, srcType, 241bf215546Sopenharmony_ci srcAddr, srcPacking, 242bf215546Sopenharmony_ci false /* unsigned */); 243bf215546Sopenharmony_ci} 244