1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Mesa 3-D graphics library 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Copyright (C) 2013 LunarG, Inc. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 8bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 9bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 11bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 12bf215546Sopenharmony_ci * 13bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 14bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci * 24bf215546Sopenharmony_ci * Authors: 25bf215546Sopenharmony_ci * Courtney Goeltzenleuchter <courtney@lunarg.com> 26bf215546Sopenharmony_ci */ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci/** 30bf215546Sopenharmony_ci * \file textureview.c 31bf215546Sopenharmony_ci * GL_ARB_texture_view functions 32bf215546Sopenharmony_ci */ 33bf215546Sopenharmony_ci 34bf215546Sopenharmony_ci#include "glheader.h" 35bf215546Sopenharmony_ci#include "context.h" 36bf215546Sopenharmony_ci#include "enums.h" 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci#include "macros.h" 39bf215546Sopenharmony_ci#include "teximage.h" 40bf215546Sopenharmony_ci#include "texobj.h" 41bf215546Sopenharmony_ci#include "mipmap.h" 42bf215546Sopenharmony_ci#include "texstorage.h" 43bf215546Sopenharmony_ci#include "textureview.h" 44bf215546Sopenharmony_ci#include "stdbool.h" 45bf215546Sopenharmony_ci#include "mtypes.h" 46bf215546Sopenharmony_ci#include "api_exec_decl.h" 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci#include "state_tracker/st_cb_texture.h" 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_ci/* Table 3.X.2 (Compatible internal formats for TextureView) 51bf215546Sopenharmony_ci --------------------------------------------------------------------------- 52bf215546Sopenharmony_ci | Class | Internal formats | 53bf215546Sopenharmony_ci --------------------------------------------------------------------------- 54bf215546Sopenharmony_ci | VIEW_CLASS_128_BITS | RGBA32F, RGBA32UI, RGBA32I | 55bf215546Sopenharmony_ci --------------------------------------------------------------------------- 56bf215546Sopenharmony_ci | VIEW_CLASS_96_BITS | RGB32F, RGB32UI, RGB32I | 57bf215546Sopenharmony_ci --------------------------------------------------------------------------- 58bf215546Sopenharmony_ci | VIEW_CLASS_64_BITS | RGBA16F, RG32F, RGBA16UI, RG32UI, RGBA16I, | 59bf215546Sopenharmony_ci | | RG32I, RGBA16, RGBA16_SNORM | 60bf215546Sopenharmony_ci --------------------------------------------------------------------------- 61bf215546Sopenharmony_ci | VIEW_CLASS_48_BITS | RGB16, RGB16_SNORM, RGB16F, RGB16UI, RGB16I | 62bf215546Sopenharmony_ci --------------------------------------------------------------------------- 63bf215546Sopenharmony_ci | VIEW_CLASS_32_BITS | RG16F, R11F_G11F_B10F, R32F, | 64bf215546Sopenharmony_ci | | RGB10_A2UI, RGBA8UI, RG16UI, R32UI, | 65bf215546Sopenharmony_ci | | RGBA8I, RG16I, R32I, RGB10_A2, RGBA8, RG16, | 66bf215546Sopenharmony_ci | | RGBA8_SNORM, RG16_SNORM, SRGB8_ALPHA8, RGB9_E5 | 67bf215546Sopenharmony_ci --------------------------------------------------------------------------- 68bf215546Sopenharmony_ci | VIEW_CLASS_24_BITS | RGB8, RGB8_SNORM, SRGB8, RGB8UI, RGB8I | 69bf215546Sopenharmony_ci --------------------------------------------------------------------------- 70bf215546Sopenharmony_ci | VIEW_CLASS_16_BITS | R16F, RG8UI, R16UI, RG8I, R16I, RG8, R16, | 71bf215546Sopenharmony_ci | | RG8_SNORM, R16_SNORM | 72bf215546Sopenharmony_ci --------------------------------------------------------------------------- 73bf215546Sopenharmony_ci | VIEW_CLASS_8_BITS | R8UI, R8I, R8, R8_SNORM | 74bf215546Sopenharmony_ci --------------------------------------------------------------------------- 75bf215546Sopenharmony_ci | VIEW_CLASS_RGTC1_RED | COMPRESSED_RED_RGTC1, | 76bf215546Sopenharmony_ci | | COMPRESSED_SIGNED_RED_RGTC1 | 77bf215546Sopenharmony_ci --------------------------------------------------------------------------- 78bf215546Sopenharmony_ci | VIEW_CLASS_RGTC2_RG | COMPRESSED_RG_RGTC2, | 79bf215546Sopenharmony_ci | | COMPRESSED_SIGNED_RG_RGTC2 | 80bf215546Sopenharmony_ci --------------------------------------------------------------------------- 81bf215546Sopenharmony_ci | VIEW_CLASS_BPTC_UNORM | COMPRESSED_RGBA_BPTC_UNORM, | 82bf215546Sopenharmony_ci | | COMPRESSED_SRGB_ALPHA_BPTC_UNORM | 83bf215546Sopenharmony_ci --------------------------------------------------------------------------- 84bf215546Sopenharmony_ci | VIEW_CLASS_BPTC_FLOAT | COMPRESSED_RGB_BPTC_SIGNED_FLOAT, | 85bf215546Sopenharmony_ci | | COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT | 86bf215546Sopenharmony_ci --------------------------------------------------------------------------- 87bf215546Sopenharmony_ci */ 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci#define VIEW_CLASS_GLES(x) (GL_VIEW_CLASS_BPTC_FLOAT + 1 + x) 90bf215546Sopenharmony_ci#define VIEW_CLASS_EAC_R11 VIEW_CLASS_GLES(0) 91bf215546Sopenharmony_ci#define VIEW_CLASS_EAC_RG11 VIEW_CLASS_GLES(1) 92bf215546Sopenharmony_ci#define VIEW_CLASS_ETC2_RGB VIEW_CLASS_GLES(2) 93bf215546Sopenharmony_ci#define VIEW_CLASS_ETC2_RGBA VIEW_CLASS_GLES(3) 94bf215546Sopenharmony_ci#define VIEW_CLASS_ETC2_EAC_RGBA VIEW_CLASS_GLES(4) 95bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_4x4_RGBA VIEW_CLASS_GLES(5) 96bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_5x4_RGBA VIEW_CLASS_GLES(6) 97bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_5x5_RGBA VIEW_CLASS_GLES(7) 98bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_6x5_RGBA VIEW_CLASS_GLES(8) 99bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_6x6_RGBA VIEW_CLASS_GLES(9) 100bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_8x5_RGBA VIEW_CLASS_GLES(10) 101bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_8x6_RGBA VIEW_CLASS_GLES(11) 102bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_8x8_RGBA VIEW_CLASS_GLES(12) 103bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_10x5_RGBA VIEW_CLASS_GLES(13) 104bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_10x6_RGBA VIEW_CLASS_GLES(14) 105bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_10x8_RGBA VIEW_CLASS_GLES(15) 106bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_10x10_RGBA VIEW_CLASS_GLES(16) 107bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_12x10_RGBA VIEW_CLASS_GLES(17) 108bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_12x12_RGBA VIEW_CLASS_GLES(18) 109bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_3x3x3_RGBA VIEW_CLASS_GLES(19) 110bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_4x3x3_RGBA VIEW_CLASS_GLES(20) 111bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_4x4x3_RGBA VIEW_CLASS_GLES(21) 112bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_4x4x4_RGBA VIEW_CLASS_GLES(22) 113bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_5x4x4_RGBA VIEW_CLASS_GLES(23) 114bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_5x5x4_RGBA VIEW_CLASS_GLES(24) 115bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_5x5x5_RGBA VIEW_CLASS_GLES(25) 116bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_6x5x5_RGBA VIEW_CLASS_GLES(26) 117bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_6x6x5_RGBA VIEW_CLASS_GLES(27) 118bf215546Sopenharmony_ci#define VIEW_CLASS_ASTC_6x6x6_RGBA VIEW_CLASS_GLES(28) 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_cistruct internal_format_class_info { 122bf215546Sopenharmony_ci GLenum view_class; 123bf215546Sopenharmony_ci GLenum internal_format; 124bf215546Sopenharmony_ci}; 125bf215546Sopenharmony_cistatic const struct internal_format_class_info compatible_internal_formats[] = { 126bf215546Sopenharmony_ci {GL_VIEW_CLASS_128_BITS, GL_RGBA32F}, 127bf215546Sopenharmony_ci {GL_VIEW_CLASS_128_BITS, GL_RGBA32UI}, 128bf215546Sopenharmony_ci {GL_VIEW_CLASS_128_BITS, GL_RGBA32I}, 129bf215546Sopenharmony_ci {GL_VIEW_CLASS_96_BITS, GL_RGB32F}, 130bf215546Sopenharmony_ci {GL_VIEW_CLASS_96_BITS, GL_RGB32UI}, 131bf215546Sopenharmony_ci {GL_VIEW_CLASS_96_BITS, GL_RGB32I}, 132bf215546Sopenharmony_ci {GL_VIEW_CLASS_64_BITS, GL_RGBA16F}, 133bf215546Sopenharmony_ci {GL_VIEW_CLASS_64_BITS, GL_RG32F}, 134bf215546Sopenharmony_ci {GL_VIEW_CLASS_64_BITS, GL_RGBA16UI}, 135bf215546Sopenharmony_ci {GL_VIEW_CLASS_64_BITS, GL_RG32UI}, 136bf215546Sopenharmony_ci {GL_VIEW_CLASS_64_BITS, GL_RGBA16I}, 137bf215546Sopenharmony_ci {GL_VIEW_CLASS_64_BITS, GL_RG32I}, 138bf215546Sopenharmony_ci {GL_VIEW_CLASS_64_BITS, GL_RGBA16}, 139bf215546Sopenharmony_ci {GL_VIEW_CLASS_64_BITS, GL_RGBA16_SNORM}, 140bf215546Sopenharmony_ci {GL_VIEW_CLASS_48_BITS, GL_RGB16}, 141bf215546Sopenharmony_ci {GL_VIEW_CLASS_48_BITS, GL_RGB16_SNORM}, 142bf215546Sopenharmony_ci {GL_VIEW_CLASS_48_BITS, GL_RGB16F}, 143bf215546Sopenharmony_ci {GL_VIEW_CLASS_48_BITS, GL_RGB16UI}, 144bf215546Sopenharmony_ci {GL_VIEW_CLASS_48_BITS, GL_RGB16I}, 145bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_RG16F}, 146bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_R11F_G11F_B10F}, 147bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_R32F}, 148bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_RGB10_A2UI}, 149bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_RGBA8UI}, 150bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_RG16UI}, 151bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_R32UI}, 152bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_RGBA8I}, 153bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_RG16I}, 154bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_R32I}, 155bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_RGB10_A2}, 156bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_RGBA8}, 157bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_RG16}, 158bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_RGBA8_SNORM}, 159bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_RG16_SNORM}, 160bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_SRGB8_ALPHA8}, 161bf215546Sopenharmony_ci {GL_VIEW_CLASS_32_BITS, GL_RGB9_E5}, 162bf215546Sopenharmony_ci {GL_VIEW_CLASS_24_BITS, GL_RGB8}, 163bf215546Sopenharmony_ci {GL_VIEW_CLASS_24_BITS, GL_RGB8_SNORM}, 164bf215546Sopenharmony_ci {GL_VIEW_CLASS_24_BITS, GL_SRGB8}, 165bf215546Sopenharmony_ci {GL_VIEW_CLASS_24_BITS, GL_RGB8UI}, 166bf215546Sopenharmony_ci {GL_VIEW_CLASS_24_BITS, GL_RGB8I}, 167bf215546Sopenharmony_ci {GL_VIEW_CLASS_16_BITS, GL_R16F}, 168bf215546Sopenharmony_ci {GL_VIEW_CLASS_16_BITS, GL_RG8UI}, 169bf215546Sopenharmony_ci {GL_VIEW_CLASS_16_BITS, GL_R16UI}, 170bf215546Sopenharmony_ci {GL_VIEW_CLASS_16_BITS, GL_RG8I}, 171bf215546Sopenharmony_ci {GL_VIEW_CLASS_16_BITS, GL_R16I}, 172bf215546Sopenharmony_ci {GL_VIEW_CLASS_16_BITS, GL_RG8}, 173bf215546Sopenharmony_ci {GL_VIEW_CLASS_16_BITS, GL_R16}, 174bf215546Sopenharmony_ci {GL_VIEW_CLASS_16_BITS, GL_RG8_SNORM}, 175bf215546Sopenharmony_ci {GL_VIEW_CLASS_16_BITS, GL_SRG8_EXT}, 176bf215546Sopenharmony_ci {GL_VIEW_CLASS_16_BITS, GL_R16_SNORM}, 177bf215546Sopenharmony_ci {GL_VIEW_CLASS_8_BITS, GL_R8UI}, 178bf215546Sopenharmony_ci {GL_VIEW_CLASS_8_BITS, GL_R8I}, 179bf215546Sopenharmony_ci {GL_VIEW_CLASS_8_BITS, GL_R8}, 180bf215546Sopenharmony_ci {GL_VIEW_CLASS_8_BITS, GL_R8_SNORM}, 181bf215546Sopenharmony_ci {GL_VIEW_CLASS_8_BITS, GL_SR8_EXT}, 182bf215546Sopenharmony_ci {GL_VIEW_CLASS_RGTC1_RED, GL_COMPRESSED_RED_RGTC1}, 183bf215546Sopenharmony_ci {GL_VIEW_CLASS_RGTC1_RED, GL_COMPRESSED_SIGNED_RED_RGTC1}, 184bf215546Sopenharmony_ci {GL_VIEW_CLASS_RGTC2_RG, GL_COMPRESSED_RG_RGTC2}, 185bf215546Sopenharmony_ci {GL_VIEW_CLASS_RGTC2_RG, GL_COMPRESSED_SIGNED_RG_RGTC2}, 186bf215546Sopenharmony_ci {GL_VIEW_CLASS_BPTC_UNORM, GL_COMPRESSED_RGBA_BPTC_UNORM_ARB}, 187bf215546Sopenharmony_ci {GL_VIEW_CLASS_BPTC_UNORM, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB}, 188bf215546Sopenharmony_ci {GL_VIEW_CLASS_BPTC_FLOAT, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB}, 189bf215546Sopenharmony_ci {GL_VIEW_CLASS_BPTC_FLOAT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB}, 190bf215546Sopenharmony_ci}; 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_cistatic const struct internal_format_class_info s3tc_compatible_internal_formats[] = { 193bf215546Sopenharmony_ci {GL_VIEW_CLASS_S3TC_DXT1_RGB, GL_COMPRESSED_RGB_S3TC_DXT1_EXT}, 194bf215546Sopenharmony_ci {GL_VIEW_CLASS_S3TC_DXT1_RGB, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT}, 195bf215546Sopenharmony_ci {GL_VIEW_CLASS_S3TC_DXT1_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT}, 196bf215546Sopenharmony_ci {GL_VIEW_CLASS_S3TC_DXT1_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT}, 197bf215546Sopenharmony_ci {GL_VIEW_CLASS_S3TC_DXT3_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT}, 198bf215546Sopenharmony_ci {GL_VIEW_CLASS_S3TC_DXT3_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT}, 199bf215546Sopenharmony_ci {GL_VIEW_CLASS_S3TC_DXT5_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT}, 200bf215546Sopenharmony_ci {GL_VIEW_CLASS_S3TC_DXT5_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}, 201bf215546Sopenharmony_ci}; 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_cistatic const struct internal_format_class_info gles_etc2_compatible_internal_formats[] = { 204bf215546Sopenharmony_ci {VIEW_CLASS_EAC_R11, GL_COMPRESSED_R11_EAC}, 205bf215546Sopenharmony_ci {VIEW_CLASS_EAC_R11, GL_COMPRESSED_SIGNED_R11_EAC}, 206bf215546Sopenharmony_ci {VIEW_CLASS_EAC_RG11, GL_COMPRESSED_RG11_EAC}, 207bf215546Sopenharmony_ci {VIEW_CLASS_EAC_RG11, GL_COMPRESSED_SIGNED_RG11_EAC}, 208bf215546Sopenharmony_ci {VIEW_CLASS_ETC2_RGB, GL_COMPRESSED_RGB8_ETC2}, 209bf215546Sopenharmony_ci {VIEW_CLASS_ETC2_RGB, GL_COMPRESSED_SRGB8_ETC2}, 210bf215546Sopenharmony_ci {VIEW_CLASS_ETC2_RGBA, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2}, 211bf215546Sopenharmony_ci {VIEW_CLASS_ETC2_RGBA, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2}, 212bf215546Sopenharmony_ci {VIEW_CLASS_ETC2_EAC_RGBA, GL_COMPRESSED_RGBA8_ETC2_EAC}, 213bf215546Sopenharmony_ci {VIEW_CLASS_ETC2_EAC_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC}, 214bf215546Sopenharmony_ci}; 215bf215546Sopenharmony_ci 216bf215546Sopenharmony_cistatic const struct internal_format_class_info gles_astc_compatible_internal_formats[] = { 217bf215546Sopenharmony_ci#define ASTC_FMT(size) \ 218bf215546Sopenharmony_ci {VIEW_CLASS_ASTC_##size##_RGBA, GL_COMPRESSED_RGBA_ASTC_##size##_KHR}, \ 219bf215546Sopenharmony_ci {VIEW_CLASS_ASTC_##size##_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_##size##_KHR} 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci ASTC_FMT(4x4), 222bf215546Sopenharmony_ci ASTC_FMT(5x4), 223bf215546Sopenharmony_ci ASTC_FMT(5x5), 224bf215546Sopenharmony_ci ASTC_FMT(6x5), 225bf215546Sopenharmony_ci ASTC_FMT(6x6), 226bf215546Sopenharmony_ci ASTC_FMT(8x5), 227bf215546Sopenharmony_ci ASTC_FMT(8x6), 228bf215546Sopenharmony_ci ASTC_FMT(8x8), 229bf215546Sopenharmony_ci ASTC_FMT(10x5), 230bf215546Sopenharmony_ci ASTC_FMT(10x6), 231bf215546Sopenharmony_ci ASTC_FMT(10x8), 232bf215546Sopenharmony_ci ASTC_FMT(10x10), 233bf215546Sopenharmony_ci ASTC_FMT(12x10), 234bf215546Sopenharmony_ci ASTC_FMT(12x12), 235bf215546Sopenharmony_ci#undef ASTC_FMT 236bf215546Sopenharmony_ci}; 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_cistatic const struct internal_format_class_info gles_astc_3d_compatible_internal_formats[] = { 239bf215546Sopenharmony_ci#define ASTC_FMT(size) \ 240bf215546Sopenharmony_ci {VIEW_CLASS_ASTC_##size##_RGBA, GL_COMPRESSED_RGBA_ASTC_##size##_OES}, \ 241bf215546Sopenharmony_ci {VIEW_CLASS_ASTC_##size##_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_##size##_OES} 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci ASTC_FMT(3x3x3), 244bf215546Sopenharmony_ci ASTC_FMT(4x3x3), 245bf215546Sopenharmony_ci ASTC_FMT(4x4x3), 246bf215546Sopenharmony_ci ASTC_FMT(4x4x4), 247bf215546Sopenharmony_ci ASTC_FMT(5x4x4), 248bf215546Sopenharmony_ci ASTC_FMT(5x5x4), 249bf215546Sopenharmony_ci ASTC_FMT(5x5x5), 250bf215546Sopenharmony_ci ASTC_FMT(6x5x5), 251bf215546Sopenharmony_ci ASTC_FMT(6x6x5), 252bf215546Sopenharmony_ci ASTC_FMT(6x6x6), 253bf215546Sopenharmony_ci#undef ASTC_FMT 254bf215546Sopenharmony_ci}; 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ciGLenum 257bf215546Sopenharmony_ci_mesa_texture_view_lookup_view_class(const struct gl_context *ctx, GLenum internalformat) 258bf215546Sopenharmony_ci{ 259bf215546Sopenharmony_ci GLuint i; 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(compatible_internal_formats); i++) { 262bf215546Sopenharmony_ci if (compatible_internal_formats[i].internal_format == internalformat) 263bf215546Sopenharmony_ci return compatible_internal_formats[i].view_class; 264bf215546Sopenharmony_ci } 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci if (ctx->Extensions.EXT_texture_compression_s3tc && 267bf215546Sopenharmony_ci ctx->Extensions.EXT_texture_sRGB) { 268bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(s3tc_compatible_internal_formats); i++) { 269bf215546Sopenharmony_ci if (s3tc_compatible_internal_formats[i].internal_format 270bf215546Sopenharmony_ci == internalformat) 271bf215546Sopenharmony_ci return s3tc_compatible_internal_formats[i].view_class; 272bf215546Sopenharmony_ci } 273bf215546Sopenharmony_ci } 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ci if (_mesa_is_gles3(ctx)) { 276bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(gles_etc2_compatible_internal_formats); i++) { 277bf215546Sopenharmony_ci if (gles_etc2_compatible_internal_formats[i].internal_format 278bf215546Sopenharmony_ci == internalformat) 279bf215546Sopenharmony_ci return gles_etc2_compatible_internal_formats[i].view_class; 280bf215546Sopenharmony_ci } 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci if (ctx->Extensions.KHR_texture_compression_astc_ldr) { 283bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(gles_astc_compatible_internal_formats); i++) { 284bf215546Sopenharmony_ci if (gles_astc_compatible_internal_formats[i].internal_format 285bf215546Sopenharmony_ci == internalformat) 286bf215546Sopenharmony_ci return gles_astc_compatible_internal_formats[i].view_class; 287bf215546Sopenharmony_ci } 288bf215546Sopenharmony_ci } 289bf215546Sopenharmony_ci 290bf215546Sopenharmony_ci if (ctx->Extensions.OES_texture_compression_astc) { 291bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(gles_astc_3d_compatible_internal_formats); i++) { 292bf215546Sopenharmony_ci if (gles_astc_3d_compatible_internal_formats[i].internal_format 293bf215546Sopenharmony_ci == internalformat) 294bf215546Sopenharmony_ci return gles_astc_3d_compatible_internal_formats[i].view_class; 295bf215546Sopenharmony_ci } 296bf215546Sopenharmony_ci } 297bf215546Sopenharmony_ci } 298bf215546Sopenharmony_ci return GL_FALSE; 299bf215546Sopenharmony_ci} 300bf215546Sopenharmony_ci 301bf215546Sopenharmony_ci/** 302bf215546Sopenharmony_ci * Initialize new texture's gl_texture_image structures. Will not call driver 303bf215546Sopenharmony_ci * to allocate new space, simply record relevant layer, face, format, etc. 304bf215546Sopenharmony_ci * \return GL_FALSE if any error, GL_TRUE otherwise. 305bf215546Sopenharmony_ci */ 306bf215546Sopenharmony_cistatic GLboolean 307bf215546Sopenharmony_ciinitialize_texture_fields(struct gl_context *ctx, 308bf215546Sopenharmony_ci GLenum target, 309bf215546Sopenharmony_ci struct gl_texture_object *texObj, 310bf215546Sopenharmony_ci GLint levels, 311bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 312bf215546Sopenharmony_ci GLenum internalFormat, mesa_format texFormat, 313bf215546Sopenharmony_ci GLuint numSamples, GLboolean fixedSampleLocations) 314bf215546Sopenharmony_ci{ 315bf215546Sopenharmony_ci const GLuint numFaces = _mesa_num_tex_faces(target); 316bf215546Sopenharmony_ci GLint level, levelWidth = width, levelHeight = height, levelDepth = depth; 317bf215546Sopenharmony_ci GLuint face; 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci /* Pretend we are bound to initialize the gl_texture_image structs */ 320bf215546Sopenharmony_ci texObj->Target = target; 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci /* Set up all the texture object's gl_texture_images */ 323bf215546Sopenharmony_ci for (level = 0; level < levels; level++) { 324bf215546Sopenharmony_ci for (face = 0; face < numFaces; face++) { 325bf215546Sopenharmony_ci struct gl_texture_image *texImage; 326bf215546Sopenharmony_ci const GLenum faceTarget = _mesa_cube_face_target(target, face); 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_ci texImage = _mesa_get_tex_image(ctx, texObj, faceTarget, level); 329bf215546Sopenharmony_ci 330bf215546Sopenharmony_ci if (!texImage) { 331bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage"); 332bf215546Sopenharmony_ci return GL_FALSE; 333bf215546Sopenharmony_ci } 334bf215546Sopenharmony_ci 335bf215546Sopenharmony_ci _mesa_init_teximage_fields_ms(ctx, texImage, 336bf215546Sopenharmony_ci levelWidth, levelHeight, levelDepth, 337bf215546Sopenharmony_ci 0, internalFormat, texFormat, 338bf215546Sopenharmony_ci numSamples, fixedSampleLocations); 339bf215546Sopenharmony_ci } 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci _mesa_next_mipmap_level_size(target, 0, 342bf215546Sopenharmony_ci levelWidth, levelHeight, levelDepth, 343bf215546Sopenharmony_ci &levelWidth, &levelHeight, &levelDepth); 344bf215546Sopenharmony_ci } 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci /* "unbind" */ 347bf215546Sopenharmony_ci texObj->Target = 0; 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_ci return GL_TRUE; 350bf215546Sopenharmony_ci} 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_ci#define RETURN_IF_SUPPORTED(t) do { \ 353bf215546Sopenharmony_ci if (newTarget == GL_ ## t) \ 354bf215546Sopenharmony_ci return true; \ 355bf215546Sopenharmony_ci} while (0) 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ci/** 358bf215546Sopenharmony_ci * Check for compatible target 359bf215546Sopenharmony_ci * If an error is found, record it with _mesa_error() 360bf215546Sopenharmony_ci * \return false if any error, true otherwise. 361bf215546Sopenharmony_ci */ 362bf215546Sopenharmony_cistatic bool 363bf215546Sopenharmony_citarget_valid(struct gl_context *ctx, GLenum origTarget, GLenum newTarget) 364bf215546Sopenharmony_ci{ 365bf215546Sopenharmony_ci /* 366bf215546Sopenharmony_ci * From ARB_texture_view spec: 367bf215546Sopenharmony_ci --------------------------------------------------------------------------------------------------------- 368bf215546Sopenharmony_ci | Original target | Valid new targets | 369bf215546Sopenharmony_ci --------------------------------------------------------------------------------------------------------- 370bf215546Sopenharmony_ci | TEXTURE_1D | TEXTURE_1D, TEXTURE_1D_ARRAY | 371bf215546Sopenharmony_ci | ------------------------------------------------------------------------------------------------------- | 372bf215546Sopenharmony_ci | TEXTURE_2D | TEXTURE_2D, TEXTURE_2D_ARRAY | 373bf215546Sopenharmony_ci | ------------------------------------------------------------------------------------------------------- | 374bf215546Sopenharmony_ci | TEXTURE_3D | TEXTURE_3D | 375bf215546Sopenharmony_ci | ------------------------------------------------------------------------------------------------------- | 376bf215546Sopenharmony_ci | TEXTURE_CUBE_MAP | TEXTURE_CUBE_MAP, TEXTURE_2D, TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY | 377bf215546Sopenharmony_ci | ------------------------------------------------------------------------------------------------------- | 378bf215546Sopenharmony_ci | TEXTURE_RECTANGLE | TEXTURE_RECTANGLE | 379bf215546Sopenharmony_ci | ------------------------------------------------------------------------------------------------------- | 380bf215546Sopenharmony_ci | TEXTURE_BUFFER | <none> | 381bf215546Sopenharmony_ci | ------------------------------------------------------------------------------------------------------- | 382bf215546Sopenharmony_ci | TEXTURE_1D_ARRAY | TEXTURE_1D_ARRAY, TEXTURE_1D | 383bf215546Sopenharmony_ci | ------------------------------------------------------------------------------------------------------- | 384bf215546Sopenharmony_ci | TEXTURE_2D_ARRAY | TEXTURE_2D_ARRAY, TEXTURE_2D, TEXTURE_CUBE_MAP, TEXTURE_CUBE_MAP_ARRAY | 385bf215546Sopenharmony_ci | ------------------------------------------------------------------------------------------------------- | 386bf215546Sopenharmony_ci | TEXTURE_CUBE_MAP_ARRAY | TEXTURE_CUBE_MAP_ARRAY, TEXTURE_2D_ARRAY, TEXTURE_2D, TEXTURE_CUBE_MAP | 387bf215546Sopenharmony_ci | ------------------------------------------------------------------------------------------------------- | 388bf215546Sopenharmony_ci | TEXTURE_2D_MULTISAMPLE | TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY | 389bf215546Sopenharmony_ci | ------------------------------------------------------------------------------------------------------- | 390bf215546Sopenharmony_ci | TEXTURE_2D_MULTISAMPLE_ARRAY | TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY | 391bf215546Sopenharmony_ci --------------------------------------------------------------------------------------------------------- 392bf215546Sopenharmony_ci */ 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci switch (origTarget) { 395bf215546Sopenharmony_ci case GL_TEXTURE_1D: 396bf215546Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 397bf215546Sopenharmony_ci RETURN_IF_SUPPORTED(TEXTURE_1D); 398bf215546Sopenharmony_ci RETURN_IF_SUPPORTED(TEXTURE_1D_ARRAY); 399bf215546Sopenharmony_ci break; 400bf215546Sopenharmony_ci case GL_TEXTURE_2D: 401bf215546Sopenharmony_ci RETURN_IF_SUPPORTED(TEXTURE_2D); 402bf215546Sopenharmony_ci RETURN_IF_SUPPORTED(TEXTURE_2D_ARRAY); 403bf215546Sopenharmony_ci break; 404bf215546Sopenharmony_ci case GL_TEXTURE_3D: 405bf215546Sopenharmony_ci RETURN_IF_SUPPORTED(TEXTURE_3D); 406bf215546Sopenharmony_ci break; 407bf215546Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 408bf215546Sopenharmony_ci RETURN_IF_SUPPORTED(TEXTURE_RECTANGLE); 409bf215546Sopenharmony_ci break; 410bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 411bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 412bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 413bf215546Sopenharmony_ci RETURN_IF_SUPPORTED(TEXTURE_2D); 414bf215546Sopenharmony_ci RETURN_IF_SUPPORTED(TEXTURE_2D_ARRAY); 415bf215546Sopenharmony_ci RETURN_IF_SUPPORTED(TEXTURE_CUBE_MAP); 416bf215546Sopenharmony_ci RETURN_IF_SUPPORTED(TEXTURE_CUBE_MAP_ARRAY); 417bf215546Sopenharmony_ci break; 418bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 419bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 420bf215546Sopenharmony_ci RETURN_IF_SUPPORTED(TEXTURE_2D_MULTISAMPLE); 421bf215546Sopenharmony_ci RETURN_IF_SUPPORTED(TEXTURE_2D_MULTISAMPLE_ARRAY); 422bf215546Sopenharmony_ci break; 423bf215546Sopenharmony_ci } 424bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 425bf215546Sopenharmony_ci "glTextureView(illegal target=%s)", 426bf215546Sopenharmony_ci _mesa_enum_to_string(newTarget)); 427bf215546Sopenharmony_ci return false; 428bf215546Sopenharmony_ci} 429bf215546Sopenharmony_ci#undef RETURN_IF_SUPPORTED 430bf215546Sopenharmony_ci 431bf215546Sopenharmony_ci/** 432bf215546Sopenharmony_ci * Check for compatible format 433bf215546Sopenharmony_ci * If an error is found, record it with _mesa_error() 434bf215546Sopenharmony_ci * \return false if any error, true otherwise. 435bf215546Sopenharmony_ci */ 436bf215546Sopenharmony_cibool 437bf215546Sopenharmony_ci_mesa_texture_view_compatible_format(const struct gl_context *ctx, 438bf215546Sopenharmony_ci GLenum origInternalFormat, 439bf215546Sopenharmony_ci GLenum newInternalFormat) 440bf215546Sopenharmony_ci{ 441bf215546Sopenharmony_ci unsigned int origViewClass, newViewClass; 442bf215546Sopenharmony_ci 443bf215546Sopenharmony_ci /* The two textures' internal formats must be compatible according to 444bf215546Sopenharmony_ci * Table 3.X.2 (Compatible internal formats for TextureView) 445bf215546Sopenharmony_ci * if the internal format exists in that table the view class must match. 446bf215546Sopenharmony_ci * The internal formats must be identical if not in that table, 447bf215546Sopenharmony_ci * or an INVALID_OPERATION error is generated. 448bf215546Sopenharmony_ci */ 449bf215546Sopenharmony_ci if (origInternalFormat == newInternalFormat) 450bf215546Sopenharmony_ci return true; 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci origViewClass = _mesa_texture_view_lookup_view_class(ctx, origInternalFormat); 453bf215546Sopenharmony_ci newViewClass = _mesa_texture_view_lookup_view_class(ctx, newInternalFormat); 454bf215546Sopenharmony_ci if ((origViewClass == newViewClass) && origViewClass != false) 455bf215546Sopenharmony_ci return true; 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci return false; 458bf215546Sopenharmony_ci} 459bf215546Sopenharmony_ci 460bf215546Sopenharmony_ci/** 461bf215546Sopenharmony_ci * Helper function for TexStorage and teximagemultisample to set immutable 462bf215546Sopenharmony_ci * texture state needed by ARB_texture_view. 463bf215546Sopenharmony_ci */ 464bf215546Sopenharmony_civoid 465bf215546Sopenharmony_ci_mesa_set_texture_view_state(struct gl_context *ctx, 466bf215546Sopenharmony_ci struct gl_texture_object *texObj, 467bf215546Sopenharmony_ci GLenum target, GLuint levels) 468bf215546Sopenharmony_ci{ 469bf215546Sopenharmony_ci struct gl_texture_image *texImage; 470bf215546Sopenharmony_ci 471bf215546Sopenharmony_ci /* Get a reference to what will become this View's base level */ 472bf215546Sopenharmony_ci texImage = _mesa_select_tex_image(texObj, target, 0); 473bf215546Sopenharmony_ci 474bf215546Sopenharmony_ci /* When an immutable texture is created via glTexStorage or 475bf215546Sopenharmony_ci * glTexImageMultisample, 476bf215546Sopenharmony_ci * TEXTURE_IMMUTABLE_FORMAT becomes TRUE. 477bf215546Sopenharmony_ci * TEXTURE_IMMUTABLE_LEVELS and TEXTURE_VIEW_NUM_LEVELS become levels. 478bf215546Sopenharmony_ci * If the texture target is TEXTURE_1D_ARRAY then 479bf215546Sopenharmony_ci * TEXTURE_VIEW_NUM_LAYERS becomes height. 480bf215546Sopenharmony_ci * If the texture target is TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY, 481bf215546Sopenharmony_ci * or TEXTURE_2D_MULTISAMPLE_ARRAY then TEXTURE_VIEW_NUM_LAYERS becomes 482bf215546Sopenharmony_ci * depth. 483bf215546Sopenharmony_ci * If the texture target is TEXTURE_CUBE_MAP, then 484bf215546Sopenharmony_ci * TEXTURE_VIEW_NUM_LAYERS becomes 6. 485bf215546Sopenharmony_ci * For any other texture target, TEXTURE_VIEW_NUM_LAYERS becomes 1. 486bf215546Sopenharmony_ci * 487bf215546Sopenharmony_ci * ARB_texture_multisample: Multisample textures do 488bf215546Sopenharmony_ci * not have multiple image levels. 489bf215546Sopenharmony_ci */ 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci texObj->Immutable = GL_TRUE; 492bf215546Sopenharmony_ci texObj->External = GL_FALSE; 493bf215546Sopenharmony_ci texObj->Attrib.ImmutableLevels = levels; 494bf215546Sopenharmony_ci texObj->Attrib.MinLevel = 0; 495bf215546Sopenharmony_ci texObj->Attrib.NumLevels = levels; 496bf215546Sopenharmony_ci texObj->Attrib.MinLayer = 0; 497bf215546Sopenharmony_ci texObj->Attrib.NumLayers = 1; 498bf215546Sopenharmony_ci switch (target) { 499bf215546Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 500bf215546Sopenharmony_ci texObj->Attrib.NumLayers = texImage->Height; 501bf215546Sopenharmony_ci break; 502bf215546Sopenharmony_ci 503bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 504bf215546Sopenharmony_ci texObj->Attrib.NumLevels = 1; 505bf215546Sopenharmony_ci texObj->Attrib.ImmutableLevels = 1; 506bf215546Sopenharmony_ci break; 507bf215546Sopenharmony_ci 508bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 509bf215546Sopenharmony_ci texObj->Attrib.NumLevels = 1; 510bf215546Sopenharmony_ci texObj->Attrib.ImmutableLevels = 1; 511bf215546Sopenharmony_ci FALLTHROUGH; 512bf215546Sopenharmony_ci /* fallthrough to set NumLayers */ 513bf215546Sopenharmony_ci 514bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 515bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 516bf215546Sopenharmony_ci texObj->Attrib.NumLayers = texImage->Depth; 517bf215546Sopenharmony_ci break; 518bf215546Sopenharmony_ci 519bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 520bf215546Sopenharmony_ci texObj->Attrib.NumLayers = 6; 521bf215546Sopenharmony_ci break; 522bf215546Sopenharmony_ci } 523bf215546Sopenharmony_ci} 524bf215546Sopenharmony_ci 525bf215546Sopenharmony_ci/** 526bf215546Sopenharmony_ci * glTextureView (ARB_texture_view) 527bf215546Sopenharmony_ci * If an error is found, record it with _mesa_error() 528bf215546Sopenharmony_ci * \return none. 529bf215546Sopenharmony_ci */ 530bf215546Sopenharmony_cistatic ALWAYS_INLINE void 531bf215546Sopenharmony_citexture_view(struct gl_context *ctx, struct gl_texture_object *origTexObj, 532bf215546Sopenharmony_ci struct gl_texture_object *texObj, GLenum target, 533bf215546Sopenharmony_ci GLenum internalformat, GLuint minlevel, GLuint numlevels, 534bf215546Sopenharmony_ci GLuint minlayer, GLuint numlayers, bool no_error) 535bf215546Sopenharmony_ci{ 536bf215546Sopenharmony_ci struct gl_texture_image *origTexImage; 537bf215546Sopenharmony_ci GLuint newViewNumLevels, newViewNumLayers; 538bf215546Sopenharmony_ci GLsizei width, height, depth; 539bf215546Sopenharmony_ci mesa_format texFormat; 540bf215546Sopenharmony_ci GLboolean sizeOK, dimensionsOK; 541bf215546Sopenharmony_ci GLenum faceTarget; 542bf215546Sopenharmony_ci 543bf215546Sopenharmony_ci texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, 544bf215546Sopenharmony_ci internalformat, GL_NONE, GL_NONE); 545bf215546Sopenharmony_ci if (texFormat == MESA_FORMAT_NONE) return; 546bf215546Sopenharmony_ci 547bf215546Sopenharmony_ci newViewNumLevels = MIN2(numlevels, origTexObj->Attrib.NumLevels - minlevel); 548bf215546Sopenharmony_ci newViewNumLayers = MIN2(numlayers, origTexObj->Attrib.NumLayers - minlayer); 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_ci faceTarget = _mesa_cube_face_target(origTexObj->Target, minlayer); 551bf215546Sopenharmony_ci 552bf215546Sopenharmony_ci /* Get a reference to what will become this View's base level */ 553bf215546Sopenharmony_ci origTexImage = _mesa_select_tex_image(origTexObj, faceTarget, minlevel); 554bf215546Sopenharmony_ci width = origTexImage->Width; 555bf215546Sopenharmony_ci height = origTexImage->Height; 556bf215546Sopenharmony_ci depth = origTexImage->Depth; 557bf215546Sopenharmony_ci 558bf215546Sopenharmony_ci /* Adjust width, height, depth to be appropriate for new target */ 559bf215546Sopenharmony_ci switch (target) { 560bf215546Sopenharmony_ci case GL_TEXTURE_1D: 561bf215546Sopenharmony_ci height = 1; 562bf215546Sopenharmony_ci break; 563bf215546Sopenharmony_ci 564bf215546Sopenharmony_ci case GL_TEXTURE_3D: 565bf215546Sopenharmony_ci break; 566bf215546Sopenharmony_ci 567bf215546Sopenharmony_ci case GL_TEXTURE_1D_ARRAY: 568bf215546Sopenharmony_ci height = (GLsizei) newViewNumLayers; 569bf215546Sopenharmony_ci break; 570bf215546Sopenharmony_ci 571bf215546Sopenharmony_ci case GL_TEXTURE_2D: 572bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 573bf215546Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 574bf215546Sopenharmony_ci depth = 1; 575bf215546Sopenharmony_ci break; 576bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 577bf215546Sopenharmony_ci /* If the new texture's target is TEXTURE_CUBE_MAP, the clamped 578bf215546Sopenharmony_ci * <numlayers> must be equal to 6. 579bf215546Sopenharmony_ci */ 580bf215546Sopenharmony_ci if (!no_error && newViewNumLayers != 6) { 581bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 582bf215546Sopenharmony_ci "glTextureView(clamped numlayers %d != 6)", 583bf215546Sopenharmony_ci newViewNumLayers); 584bf215546Sopenharmony_ci return; 585bf215546Sopenharmony_ci } 586bf215546Sopenharmony_ci depth = 1; 587bf215546Sopenharmony_ci break; 588bf215546Sopenharmony_ci 589bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY: 590bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 591bf215546Sopenharmony_ci depth = newViewNumLayers; 592bf215546Sopenharmony_ci break; 593bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 594bf215546Sopenharmony_ci /* If the new texture's target is TEXTURE_CUBE_MAP_ARRAY, 595bf215546Sopenharmony_ci * then <numlayers> counts layer-faces rather than layers, 596bf215546Sopenharmony_ci * and the clamped <numlayers> must be a multiple of 6. 597bf215546Sopenharmony_ci * Otherwise, the error INVALID_VALUE is generated. 598bf215546Sopenharmony_ci */ 599bf215546Sopenharmony_ci if (!no_error && (newViewNumLayers % 6) != 0) { 600bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 601bf215546Sopenharmony_ci "glTextureView(clamped numlayers %d is not" 602bf215546Sopenharmony_ci " a multiple of 6)", 603bf215546Sopenharmony_ci newViewNumLayers); 604bf215546Sopenharmony_ci return; 605bf215546Sopenharmony_ci } 606bf215546Sopenharmony_ci depth = newViewNumLayers; 607bf215546Sopenharmony_ci break; 608bf215546Sopenharmony_ci } 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci if (!no_error) { 611bf215546Sopenharmony_ci /* If the dimensions of the original texture are larger than the maximum 612bf215546Sopenharmony_ci * supported dimensions of the new target, the error INVALID_OPERATION is 613bf215546Sopenharmony_ci * generated. For example, if the original texture has a TEXTURE_2D_ARRAY 614bf215546Sopenharmony_ci * target and its width is greater than MAX_CUBE_MAP_TEXTURE_SIZE, an 615bf215546Sopenharmony_ci * error will be generated if TextureView is called to create a 616bf215546Sopenharmony_ci * TEXTURE_CUBE_MAP view. 617bf215546Sopenharmony_ci */ 618bf215546Sopenharmony_ci dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0, 619bf215546Sopenharmony_ci width, height, depth, 0); 620bf215546Sopenharmony_ci if (!dimensionsOK) { 621bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 622bf215546Sopenharmony_ci "glTextureView(invalid width or height or depth)"); 623bf215546Sopenharmony_ci return; 624bf215546Sopenharmony_ci } 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci sizeOK = st_TestProxyTexImage(ctx, target, 1, 0, texFormat, 627bf215546Sopenharmony_ci origTexImage->NumSamples, 628bf215546Sopenharmony_ci width, height, depth); 629bf215546Sopenharmony_ci if (!sizeOK) { 630bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 631bf215546Sopenharmony_ci "glTextureView(invalid texture size)"); 632bf215546Sopenharmony_ci return; 633bf215546Sopenharmony_ci } 634bf215546Sopenharmony_ci 635bf215546Sopenharmony_ci /* If <target> is TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_RECTANGLE, 636bf215546Sopenharmony_ci * or TEXTURE_2D_MULTISAMPLE and <numlayers> does not equal 1, the error 637bf215546Sopenharmony_ci * INVALID_VALUE is generated. 638bf215546Sopenharmony_ci */ 639bf215546Sopenharmony_ci switch (target) { 640bf215546Sopenharmony_ci case GL_TEXTURE_1D: 641bf215546Sopenharmony_ci case GL_TEXTURE_2D: 642bf215546Sopenharmony_ci case GL_TEXTURE_3D: 643bf215546Sopenharmony_ci case GL_TEXTURE_RECTANGLE: 644bf215546Sopenharmony_ci case GL_TEXTURE_2D_MULTISAMPLE: 645bf215546Sopenharmony_ci if (numlayers != 1) { 646bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(numlayers %d != 1)", 647bf215546Sopenharmony_ci numlayers); 648bf215546Sopenharmony_ci return; 649bf215546Sopenharmony_ci } 650bf215546Sopenharmony_ci break; 651bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP: 652bf215546Sopenharmony_ci break; 653bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 654bf215546Sopenharmony_ci break; 655bf215546Sopenharmony_ci } 656bf215546Sopenharmony_ci 657bf215546Sopenharmony_ci /* If the new texture's target is TEXTURE_CUBE_MAP or 658bf215546Sopenharmony_ci * TEXTURE_CUBE_MAP_ARRAY, the width and height of the original texture's 659bf215546Sopenharmony_ci * levels must be equal otherwise the error INVALID_OPERATION is 660bf215546Sopenharmony_ci * generated. 661bf215546Sopenharmony_ci */ 662bf215546Sopenharmony_ci if ((target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) 663bf215546Sopenharmony_ci && (origTexImage->Width != origTexImage->Height)) { 664bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 665bf215546Sopenharmony_ci "glTextureView(origtexture width (%d) != height (%d))", 666bf215546Sopenharmony_ci origTexImage->Width, origTexImage->Height); 667bf215546Sopenharmony_ci return; 668bf215546Sopenharmony_ci } 669bf215546Sopenharmony_ci } 670bf215546Sopenharmony_ci 671bf215546Sopenharmony_ci /* When the original texture's target is TEXTURE_CUBE_MAP, the layer 672bf215546Sopenharmony_ci * parameters are interpreted in the same order as if it were a 673bf215546Sopenharmony_ci * TEXTURE_CUBE_MAP_ARRAY with 6 layer-faces. 674bf215546Sopenharmony_ci */ 675bf215546Sopenharmony_ci 676bf215546Sopenharmony_ci /* If the internal format does not exactly match the internal format of the 677bf215546Sopenharmony_ci * original texture, the contents of the memory are reinterpreted in the 678bf215546Sopenharmony_ci * same manner as for image bindings described in 679bf215546Sopenharmony_ci * section 3.9.20 (Texture Image Loads and Stores). 680bf215546Sopenharmony_ci */ 681bf215546Sopenharmony_ci 682bf215546Sopenharmony_ci /* TEXTURE_BASE_LEVEL and TEXTURE_MAX_LEVEL are interpreted 683bf215546Sopenharmony_ci * relative to the view and not relative to the original data store. 684bf215546Sopenharmony_ci */ 685bf215546Sopenharmony_ci 686bf215546Sopenharmony_ci if (!initialize_texture_fields(ctx, target, texObj, newViewNumLevels, 687bf215546Sopenharmony_ci width, height, depth, 688bf215546Sopenharmony_ci internalformat, texFormat, 689bf215546Sopenharmony_ci origTexImage->NumSamples, 690bf215546Sopenharmony_ci origTexImage->FixedSampleLocations)) { 691bf215546Sopenharmony_ci return; /* Already recorded error */ 692bf215546Sopenharmony_ci } 693bf215546Sopenharmony_ci 694bf215546Sopenharmony_ci texObj->Attrib.MinLevel = origTexObj->Attrib.MinLevel + minlevel; 695bf215546Sopenharmony_ci texObj->Attrib.MinLayer = origTexObj->Attrib.MinLayer + minlayer; 696bf215546Sopenharmony_ci texObj->Attrib.NumLevels = newViewNumLevels; 697bf215546Sopenharmony_ci texObj->Attrib.NumLayers = newViewNumLayers; 698bf215546Sopenharmony_ci texObj->Immutable = GL_TRUE; 699bf215546Sopenharmony_ci texObj->External = GL_FALSE; 700bf215546Sopenharmony_ci texObj->Attrib.ImmutableLevels = origTexObj->Attrib.ImmutableLevels; 701bf215546Sopenharmony_ci texObj->Target = target; 702bf215546Sopenharmony_ci texObj->TargetIndex = _mesa_tex_target_to_index(ctx, target); 703bf215546Sopenharmony_ci assert(texObj->TargetIndex < NUM_TEXTURE_TARGETS); 704bf215546Sopenharmony_ci 705bf215546Sopenharmony_ci if (!st_TextureView(ctx, texObj, origTexObj)) { 706bf215546Sopenharmony_ci return; /* driver recorded error */ 707bf215546Sopenharmony_ci } 708bf215546Sopenharmony_ci} 709bf215546Sopenharmony_ci 710bf215546Sopenharmony_civoid GLAPIENTRY 711bf215546Sopenharmony_ci_mesa_TextureView_no_error(GLuint texture, GLenum target, GLuint origtexture, 712bf215546Sopenharmony_ci GLenum internalformat, 713bf215546Sopenharmony_ci GLuint minlevel, GLuint numlevels, 714bf215546Sopenharmony_ci GLuint minlayer, GLuint numlayers) 715bf215546Sopenharmony_ci{ 716bf215546Sopenharmony_ci struct gl_texture_object *texObj; 717bf215546Sopenharmony_ci struct gl_texture_object *origTexObj; 718bf215546Sopenharmony_ci 719bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 720bf215546Sopenharmony_ci 721bf215546Sopenharmony_ci origTexObj = _mesa_lookup_texture(ctx, origtexture); 722bf215546Sopenharmony_ci texObj = _mesa_lookup_texture(ctx, texture); 723bf215546Sopenharmony_ci 724bf215546Sopenharmony_ci texture_view(ctx, origTexObj, texObj, target, internalformat, minlevel, 725bf215546Sopenharmony_ci numlevels, minlayer, numlayers, true); 726bf215546Sopenharmony_ci} 727bf215546Sopenharmony_ci 728bf215546Sopenharmony_civoid GLAPIENTRY 729bf215546Sopenharmony_ci_mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture, 730bf215546Sopenharmony_ci GLenum internalformat, 731bf215546Sopenharmony_ci GLuint minlevel, GLuint numlevels, 732bf215546Sopenharmony_ci GLuint minlayer, GLuint numlayers) 733bf215546Sopenharmony_ci{ 734bf215546Sopenharmony_ci struct gl_texture_object *texObj; 735bf215546Sopenharmony_ci struct gl_texture_object *origTexObj; 736bf215546Sopenharmony_ci GLuint newViewMinLevel, newViewMinLayer; 737bf215546Sopenharmony_ci 738bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 739bf215546Sopenharmony_ci 740bf215546Sopenharmony_ci if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) 741bf215546Sopenharmony_ci _mesa_debug(ctx, "glTextureView %d %s %d %s %d %d %d %d\n", 742bf215546Sopenharmony_ci texture, _mesa_enum_to_string(target), origtexture, 743bf215546Sopenharmony_ci _mesa_enum_to_string(internalformat), 744bf215546Sopenharmony_ci minlevel, numlevels, minlayer, numlayers); 745bf215546Sopenharmony_ci 746bf215546Sopenharmony_ci if (origtexture == 0) { 747bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)", 748bf215546Sopenharmony_ci origtexture); 749bf215546Sopenharmony_ci return; 750bf215546Sopenharmony_ci } 751bf215546Sopenharmony_ci 752bf215546Sopenharmony_ci /* Need original texture information to validate arguments */ 753bf215546Sopenharmony_ci origTexObj = _mesa_lookup_texture(ctx, origtexture); 754bf215546Sopenharmony_ci 755bf215546Sopenharmony_ci /* If <origtexture> is not the name of a texture, INVALID_VALUE 756bf215546Sopenharmony_ci * is generated. 757bf215546Sopenharmony_ci */ 758bf215546Sopenharmony_ci if (!origTexObj) { 759bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)", 760bf215546Sopenharmony_ci origtexture); 761bf215546Sopenharmony_ci return; 762bf215546Sopenharmony_ci } 763bf215546Sopenharmony_ci 764bf215546Sopenharmony_ci /* If <origtexture>'s TEXTURE_IMMUTABLE_FORMAT value is not TRUE, 765bf215546Sopenharmony_ci * INVALID_OPERATION is generated. 766bf215546Sopenharmony_ci */ 767bf215546Sopenharmony_ci if (!origTexObj->Immutable) { 768bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 769bf215546Sopenharmony_ci "glTextureView(origtexture not immutable)"); 770bf215546Sopenharmony_ci return; 771bf215546Sopenharmony_ci } 772bf215546Sopenharmony_ci 773bf215546Sopenharmony_ci /* If <texture> is 0, INVALID_VALUE is generated. */ 774bf215546Sopenharmony_ci if (texture == 0) { 775bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(texture = 0)"); 776bf215546Sopenharmony_ci return; 777bf215546Sopenharmony_ci } 778bf215546Sopenharmony_ci 779bf215546Sopenharmony_ci /* If <texture> is not a valid name returned by GenTextures, 780bf215546Sopenharmony_ci * the error INVALID_OPERATION is generated. 781bf215546Sopenharmony_ci */ 782bf215546Sopenharmony_ci texObj = _mesa_lookup_texture(ctx, texture); 783bf215546Sopenharmony_ci if (texObj == NULL) { 784bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 785bf215546Sopenharmony_ci "glTextureView(texture = %u non-gen name)", texture); 786bf215546Sopenharmony_ci return; 787bf215546Sopenharmony_ci } 788bf215546Sopenharmony_ci 789bf215546Sopenharmony_ci /* If <texture> has already been bound and given a target, then 790bf215546Sopenharmony_ci * the error INVALID_OPERATION is generated. 791bf215546Sopenharmony_ci */ 792bf215546Sopenharmony_ci if (texObj->Target) { 793bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 794bf215546Sopenharmony_ci "glTextureView(texture = %u already bound)", texture); 795bf215546Sopenharmony_ci return; 796bf215546Sopenharmony_ci } 797bf215546Sopenharmony_ci 798bf215546Sopenharmony_ci /* Check for compatible target */ 799bf215546Sopenharmony_ci if (!target_valid(ctx, origTexObj->Target, target)) { 800bf215546Sopenharmony_ci return; /* error was recorded */ 801bf215546Sopenharmony_ci } 802bf215546Sopenharmony_ci 803bf215546Sopenharmony_ci /* minlevel and minlayer are relative to the view of origtexture. 804bf215546Sopenharmony_ci * If minlevel or minlayer is greater than level or layer, respectively, 805bf215546Sopenharmony_ci * return INVALID_VALUE. 806bf215546Sopenharmony_ci */ 807bf215546Sopenharmony_ci newViewMinLevel = origTexObj->Attrib.MinLevel + minlevel; 808bf215546Sopenharmony_ci newViewMinLayer = origTexObj->Attrib.MinLayer + minlayer; 809bf215546Sopenharmony_ci if (newViewMinLevel >= (origTexObj->Attrib.MinLevel + 810bf215546Sopenharmony_ci origTexObj->Attrib.NumLevels)) { 811bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 812bf215546Sopenharmony_ci "glTextureView(new minlevel (%d) > orig minlevel (%d)" 813bf215546Sopenharmony_ci " + orig numlevels (%d))", 814bf215546Sopenharmony_ci newViewMinLevel, origTexObj->Attrib.MinLevel, 815bf215546Sopenharmony_ci origTexObj->Attrib.NumLevels); 816bf215546Sopenharmony_ci return; 817bf215546Sopenharmony_ci } 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_ci if (newViewMinLayer >= (origTexObj->Attrib.MinLayer + 820bf215546Sopenharmony_ci origTexObj->Attrib.NumLayers)) { 821bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, 822bf215546Sopenharmony_ci "glTextureView(new minlayer (%d) > orig minlayer (%d)" 823bf215546Sopenharmony_ci " + orig numlayers (%d))", 824bf215546Sopenharmony_ci newViewMinLayer, origTexObj->Attrib.MinLayer, 825bf215546Sopenharmony_ci origTexObj->Attrib.NumLayers); 826bf215546Sopenharmony_ci return; 827bf215546Sopenharmony_ci } 828bf215546Sopenharmony_ci 829bf215546Sopenharmony_ci if (!_mesa_texture_view_compatible_format(ctx, 830bf215546Sopenharmony_ci origTexObj->Image[0][0]->InternalFormat, 831bf215546Sopenharmony_ci internalformat)) { 832bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 833bf215546Sopenharmony_ci "glTextureView(internalformat %s not compatible with origtexture %s)", 834bf215546Sopenharmony_ci _mesa_enum_to_string(internalformat), 835bf215546Sopenharmony_ci _mesa_enum_to_string(origTexObj->Image[0][0]->InternalFormat)); 836bf215546Sopenharmony_ci return; 837bf215546Sopenharmony_ci } 838bf215546Sopenharmony_ci 839bf215546Sopenharmony_ci texture_view(ctx, origTexObj, texObj, target, internalformat, minlevel, 840bf215546Sopenharmony_ci numlevels, minlayer, numlayers, false); 841bf215546Sopenharmony_ci} 842