1af69d88dSmrg/* 2af69d88dSmrg * Mesa 3-D graphics library 3af69d88dSmrg * 4af69d88dSmrg * Copyright (C) 2013 LunarG, Inc. 5af69d88dSmrg * 6af69d88dSmrg * Permission is hereby granted, free of charge, to any person obtaining a 7af69d88dSmrg * copy of this software and associated documentation files (the "Software"), 8af69d88dSmrg * to deal in the Software without restriction, including without limitation 9af69d88dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10af69d88dSmrg * and/or sell copies of the Software, and to permit persons to whom the 11af69d88dSmrg * Software is furnished to do so, subject to the following conditions: 12af69d88dSmrg * 13af69d88dSmrg * The above copyright notice and this permission notice shall be included 14af69d88dSmrg * in all copies or substantial portions of the Software. 15af69d88dSmrg * 16af69d88dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17af69d88dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18af69d88dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19af69d88dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20af69d88dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21af69d88dSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22af69d88dSmrg * DEALINGS IN THE SOFTWARE. 23af69d88dSmrg * 24af69d88dSmrg * Authors: 25af69d88dSmrg * Courtney Goeltzenleuchter <courtney@lunarg.com> 26af69d88dSmrg */ 27af69d88dSmrg 28af69d88dSmrg 29af69d88dSmrg/** 30af69d88dSmrg * \file textureview.c 31af69d88dSmrg * GL_ARB_texture_view functions 32af69d88dSmrg */ 33af69d88dSmrg 34af69d88dSmrg#include "glheader.h" 35af69d88dSmrg#include "context.h" 36af69d88dSmrg#include "enums.h" 377ec681f3Smrg 38af69d88dSmrg#include "macros.h" 39af69d88dSmrg#include "teximage.h" 40af69d88dSmrg#include "texobj.h" 41af69d88dSmrg#include "mipmap.h" 42af69d88dSmrg#include "texstorage.h" 43af69d88dSmrg#include "textureview.h" 44af69d88dSmrg#include "stdbool.h" 45af69d88dSmrg#include "mtypes.h" 46af69d88dSmrg 47af69d88dSmrg/* Table 3.X.2 (Compatible internal formats for TextureView) 48af69d88dSmrg --------------------------------------------------------------------------- 49af69d88dSmrg | Class | Internal formats | 50af69d88dSmrg --------------------------------------------------------------------------- 51af69d88dSmrg | VIEW_CLASS_128_BITS | RGBA32F, RGBA32UI, RGBA32I | 52af69d88dSmrg --------------------------------------------------------------------------- 53af69d88dSmrg | VIEW_CLASS_96_BITS | RGB32F, RGB32UI, RGB32I | 54af69d88dSmrg --------------------------------------------------------------------------- 55af69d88dSmrg | VIEW_CLASS_64_BITS | RGBA16F, RG32F, RGBA16UI, RG32UI, RGBA16I, | 56af69d88dSmrg | | RG32I, RGBA16, RGBA16_SNORM | 57af69d88dSmrg --------------------------------------------------------------------------- 58af69d88dSmrg | VIEW_CLASS_48_BITS | RGB16, RGB16_SNORM, RGB16F, RGB16UI, RGB16I | 59af69d88dSmrg --------------------------------------------------------------------------- 60af69d88dSmrg | VIEW_CLASS_32_BITS | RG16F, R11F_G11F_B10F, R32F, | 61af69d88dSmrg | | RGB10_A2UI, RGBA8UI, RG16UI, R32UI, | 62af69d88dSmrg | | RGBA8I, RG16I, R32I, RGB10_A2, RGBA8, RG16, | 63af69d88dSmrg | | RGBA8_SNORM, RG16_SNORM, SRGB8_ALPHA8, RGB9_E5 | 64af69d88dSmrg --------------------------------------------------------------------------- 65af69d88dSmrg | VIEW_CLASS_24_BITS | RGB8, RGB8_SNORM, SRGB8, RGB8UI, RGB8I | 66af69d88dSmrg --------------------------------------------------------------------------- 67af69d88dSmrg | VIEW_CLASS_16_BITS | R16F, RG8UI, R16UI, RG8I, R16I, RG8, R16, | 68af69d88dSmrg | | RG8_SNORM, R16_SNORM | 69af69d88dSmrg --------------------------------------------------------------------------- 70af69d88dSmrg | VIEW_CLASS_8_BITS | R8UI, R8I, R8, R8_SNORM | 71af69d88dSmrg --------------------------------------------------------------------------- 72af69d88dSmrg | VIEW_CLASS_RGTC1_RED | COMPRESSED_RED_RGTC1, | 73af69d88dSmrg | | COMPRESSED_SIGNED_RED_RGTC1 | 74af69d88dSmrg --------------------------------------------------------------------------- 75af69d88dSmrg | VIEW_CLASS_RGTC2_RG | COMPRESSED_RG_RGTC2, | 76af69d88dSmrg | | COMPRESSED_SIGNED_RG_RGTC2 | 77af69d88dSmrg --------------------------------------------------------------------------- 78af69d88dSmrg | VIEW_CLASS_BPTC_UNORM | COMPRESSED_RGBA_BPTC_UNORM, | 79af69d88dSmrg | | COMPRESSED_SRGB_ALPHA_BPTC_UNORM | 80af69d88dSmrg --------------------------------------------------------------------------- 81af69d88dSmrg | VIEW_CLASS_BPTC_FLOAT | COMPRESSED_RGB_BPTC_SIGNED_FLOAT, | 82af69d88dSmrg | | COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT | 83af69d88dSmrg --------------------------------------------------------------------------- 84af69d88dSmrg */ 8501e04c3fSmrg 8601e04c3fSmrg#define VIEW_CLASS_GLES(x) (GL_VIEW_CLASS_BPTC_FLOAT + 1 + x) 8701e04c3fSmrg#define VIEW_CLASS_EAC_R11 VIEW_CLASS_GLES(0) 8801e04c3fSmrg#define VIEW_CLASS_EAC_RG11 VIEW_CLASS_GLES(1) 8901e04c3fSmrg#define VIEW_CLASS_ETC2_RGB VIEW_CLASS_GLES(2) 9001e04c3fSmrg#define VIEW_CLASS_ETC2_RGBA VIEW_CLASS_GLES(3) 9101e04c3fSmrg#define VIEW_CLASS_ETC2_EAC_RGBA VIEW_CLASS_GLES(4) 9201e04c3fSmrg#define VIEW_CLASS_ASTC_4x4_RGBA VIEW_CLASS_GLES(5) 9301e04c3fSmrg#define VIEW_CLASS_ASTC_5x4_RGBA VIEW_CLASS_GLES(6) 9401e04c3fSmrg#define VIEW_CLASS_ASTC_5x5_RGBA VIEW_CLASS_GLES(7) 9501e04c3fSmrg#define VIEW_CLASS_ASTC_6x5_RGBA VIEW_CLASS_GLES(8) 9601e04c3fSmrg#define VIEW_CLASS_ASTC_6x6_RGBA VIEW_CLASS_GLES(9) 9701e04c3fSmrg#define VIEW_CLASS_ASTC_8x5_RGBA VIEW_CLASS_GLES(10) 9801e04c3fSmrg#define VIEW_CLASS_ASTC_8x6_RGBA VIEW_CLASS_GLES(11) 9901e04c3fSmrg#define VIEW_CLASS_ASTC_8x8_RGBA VIEW_CLASS_GLES(12) 10001e04c3fSmrg#define VIEW_CLASS_ASTC_10x5_RGBA VIEW_CLASS_GLES(13) 10101e04c3fSmrg#define VIEW_CLASS_ASTC_10x6_RGBA VIEW_CLASS_GLES(14) 10201e04c3fSmrg#define VIEW_CLASS_ASTC_10x8_RGBA VIEW_CLASS_GLES(15) 10301e04c3fSmrg#define VIEW_CLASS_ASTC_10x10_RGBA VIEW_CLASS_GLES(16) 10401e04c3fSmrg#define VIEW_CLASS_ASTC_12x10_RGBA VIEW_CLASS_GLES(17) 10501e04c3fSmrg#define VIEW_CLASS_ASTC_12x12_RGBA VIEW_CLASS_GLES(18) 10601e04c3fSmrg#define VIEW_CLASS_ASTC_3x3x3_RGBA VIEW_CLASS_GLES(19) 10701e04c3fSmrg#define VIEW_CLASS_ASTC_4x3x3_RGBA VIEW_CLASS_GLES(20) 10801e04c3fSmrg#define VIEW_CLASS_ASTC_4x4x3_RGBA VIEW_CLASS_GLES(21) 10901e04c3fSmrg#define VIEW_CLASS_ASTC_4x4x4_RGBA VIEW_CLASS_GLES(22) 11001e04c3fSmrg#define VIEW_CLASS_ASTC_5x4x4_RGBA VIEW_CLASS_GLES(23) 11101e04c3fSmrg#define VIEW_CLASS_ASTC_5x5x4_RGBA VIEW_CLASS_GLES(24) 11201e04c3fSmrg#define VIEW_CLASS_ASTC_5x5x5_RGBA VIEW_CLASS_GLES(25) 11301e04c3fSmrg#define VIEW_CLASS_ASTC_6x5x5_RGBA VIEW_CLASS_GLES(26) 11401e04c3fSmrg#define VIEW_CLASS_ASTC_6x6x5_RGBA VIEW_CLASS_GLES(27) 11501e04c3fSmrg#define VIEW_CLASS_ASTC_6x6x6_RGBA VIEW_CLASS_GLES(28) 11601e04c3fSmrg 11701e04c3fSmrg 118af69d88dSmrgstruct internal_format_class_info { 119af69d88dSmrg GLenum view_class; 120af69d88dSmrg GLenum internal_format; 121af69d88dSmrg}; 122af69d88dSmrgstatic const struct internal_format_class_info compatible_internal_formats[] = { 123af69d88dSmrg {GL_VIEW_CLASS_128_BITS, GL_RGBA32F}, 124af69d88dSmrg {GL_VIEW_CLASS_128_BITS, GL_RGBA32UI}, 125af69d88dSmrg {GL_VIEW_CLASS_128_BITS, GL_RGBA32I}, 126af69d88dSmrg {GL_VIEW_CLASS_96_BITS, GL_RGB32F}, 127af69d88dSmrg {GL_VIEW_CLASS_96_BITS, GL_RGB32UI}, 128af69d88dSmrg {GL_VIEW_CLASS_96_BITS, GL_RGB32I}, 129af69d88dSmrg {GL_VIEW_CLASS_64_BITS, GL_RGBA16F}, 130af69d88dSmrg {GL_VIEW_CLASS_64_BITS, GL_RG32F}, 131af69d88dSmrg {GL_VIEW_CLASS_64_BITS, GL_RGBA16UI}, 132af69d88dSmrg {GL_VIEW_CLASS_64_BITS, GL_RG32UI}, 133af69d88dSmrg {GL_VIEW_CLASS_64_BITS, GL_RGBA16I}, 134af69d88dSmrg {GL_VIEW_CLASS_64_BITS, GL_RG32I}, 135af69d88dSmrg {GL_VIEW_CLASS_64_BITS, GL_RGBA16}, 136af69d88dSmrg {GL_VIEW_CLASS_64_BITS, GL_RGBA16_SNORM}, 137af69d88dSmrg {GL_VIEW_CLASS_48_BITS, GL_RGB16}, 138af69d88dSmrg {GL_VIEW_CLASS_48_BITS, GL_RGB16_SNORM}, 139af69d88dSmrg {GL_VIEW_CLASS_48_BITS, GL_RGB16F}, 140af69d88dSmrg {GL_VIEW_CLASS_48_BITS, GL_RGB16UI}, 141af69d88dSmrg {GL_VIEW_CLASS_48_BITS, GL_RGB16I}, 142af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_RG16F}, 143af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_R11F_G11F_B10F}, 144af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_R32F}, 145af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_RGB10_A2UI}, 146af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_RGBA8UI}, 147af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_RG16UI}, 148af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_R32UI}, 149af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_RGBA8I}, 150af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_RG16I}, 151af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_R32I}, 152af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_RGB10_A2}, 153af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_RGBA8}, 154af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_RG16}, 155af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_RGBA8_SNORM}, 156af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_RG16_SNORM}, 157af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_SRGB8_ALPHA8}, 158af69d88dSmrg {GL_VIEW_CLASS_32_BITS, GL_RGB9_E5}, 159af69d88dSmrg {GL_VIEW_CLASS_24_BITS, GL_RGB8}, 160af69d88dSmrg {GL_VIEW_CLASS_24_BITS, GL_RGB8_SNORM}, 161af69d88dSmrg {GL_VIEW_CLASS_24_BITS, GL_SRGB8}, 162af69d88dSmrg {GL_VIEW_CLASS_24_BITS, GL_RGB8UI}, 163af69d88dSmrg {GL_VIEW_CLASS_24_BITS, GL_RGB8I}, 164af69d88dSmrg {GL_VIEW_CLASS_16_BITS, GL_R16F}, 165af69d88dSmrg {GL_VIEW_CLASS_16_BITS, GL_RG8UI}, 166af69d88dSmrg {GL_VIEW_CLASS_16_BITS, GL_R16UI}, 167af69d88dSmrg {GL_VIEW_CLASS_16_BITS, GL_RG8I}, 168af69d88dSmrg {GL_VIEW_CLASS_16_BITS, GL_R16I}, 169af69d88dSmrg {GL_VIEW_CLASS_16_BITS, GL_RG8}, 170af69d88dSmrg {GL_VIEW_CLASS_16_BITS, GL_R16}, 171af69d88dSmrg {GL_VIEW_CLASS_16_BITS, GL_RG8_SNORM}, 1727ec681f3Smrg {GL_VIEW_CLASS_16_BITS, GL_SRG8_EXT}, 173af69d88dSmrg {GL_VIEW_CLASS_16_BITS, GL_R16_SNORM}, 174af69d88dSmrg {GL_VIEW_CLASS_8_BITS, GL_R8UI}, 175af69d88dSmrg {GL_VIEW_CLASS_8_BITS, GL_R8I}, 176af69d88dSmrg {GL_VIEW_CLASS_8_BITS, GL_R8}, 177af69d88dSmrg {GL_VIEW_CLASS_8_BITS, GL_R8_SNORM}, 178b9abf16eSmaya {GL_VIEW_CLASS_8_BITS, GL_SR8_EXT}, 179af69d88dSmrg {GL_VIEW_CLASS_RGTC1_RED, GL_COMPRESSED_RED_RGTC1}, 180af69d88dSmrg {GL_VIEW_CLASS_RGTC1_RED, GL_COMPRESSED_SIGNED_RED_RGTC1}, 181af69d88dSmrg {GL_VIEW_CLASS_RGTC2_RG, GL_COMPRESSED_RG_RGTC2}, 182af69d88dSmrg {GL_VIEW_CLASS_RGTC2_RG, GL_COMPRESSED_SIGNED_RG_RGTC2}, 183af69d88dSmrg {GL_VIEW_CLASS_BPTC_UNORM, GL_COMPRESSED_RGBA_BPTC_UNORM_ARB}, 184af69d88dSmrg {GL_VIEW_CLASS_BPTC_UNORM, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB}, 185af69d88dSmrg {GL_VIEW_CLASS_BPTC_FLOAT, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB}, 186af69d88dSmrg {GL_VIEW_CLASS_BPTC_FLOAT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB}, 187af69d88dSmrg}; 188af69d88dSmrg 189af69d88dSmrgstatic const struct internal_format_class_info s3tc_compatible_internal_formats[] = { 190af69d88dSmrg {GL_VIEW_CLASS_S3TC_DXT1_RGB, GL_COMPRESSED_RGB_S3TC_DXT1_EXT}, 191af69d88dSmrg {GL_VIEW_CLASS_S3TC_DXT1_RGB, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT}, 192af69d88dSmrg {GL_VIEW_CLASS_S3TC_DXT1_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT}, 193af69d88dSmrg {GL_VIEW_CLASS_S3TC_DXT1_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT}, 194af69d88dSmrg {GL_VIEW_CLASS_S3TC_DXT3_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT}, 195af69d88dSmrg {GL_VIEW_CLASS_S3TC_DXT3_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT}, 196af69d88dSmrg {GL_VIEW_CLASS_S3TC_DXT5_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT}, 197af69d88dSmrg {GL_VIEW_CLASS_S3TC_DXT5_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}, 198af69d88dSmrg}; 199af69d88dSmrg 20001e04c3fSmrgstatic const struct internal_format_class_info gles_etc2_compatible_internal_formats[] = { 20101e04c3fSmrg {VIEW_CLASS_EAC_R11, GL_COMPRESSED_R11_EAC}, 20201e04c3fSmrg {VIEW_CLASS_EAC_R11, GL_COMPRESSED_SIGNED_R11_EAC}, 20301e04c3fSmrg {VIEW_CLASS_EAC_RG11, GL_COMPRESSED_RG11_EAC}, 20401e04c3fSmrg {VIEW_CLASS_EAC_RG11, GL_COMPRESSED_SIGNED_RG11_EAC}, 20501e04c3fSmrg {VIEW_CLASS_ETC2_RGB, GL_COMPRESSED_RGB8_ETC2}, 20601e04c3fSmrg {VIEW_CLASS_ETC2_RGB, GL_COMPRESSED_SRGB8_ETC2}, 20701e04c3fSmrg {VIEW_CLASS_ETC2_RGBA, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2}, 20801e04c3fSmrg {VIEW_CLASS_ETC2_RGBA, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2}, 20901e04c3fSmrg {VIEW_CLASS_ETC2_EAC_RGBA, GL_COMPRESSED_RGBA8_ETC2_EAC}, 21001e04c3fSmrg {VIEW_CLASS_ETC2_EAC_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC}, 21101e04c3fSmrg}; 21201e04c3fSmrg 21301e04c3fSmrgstatic const struct internal_format_class_info gles_astc_compatible_internal_formats[] = { 21401e04c3fSmrg#define ASTC_FMT(size) \ 21501e04c3fSmrg {VIEW_CLASS_ASTC_##size##_RGBA, GL_COMPRESSED_RGBA_ASTC_##size##_KHR}, \ 21601e04c3fSmrg {VIEW_CLASS_ASTC_##size##_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_##size##_KHR} 21701e04c3fSmrg 21801e04c3fSmrg ASTC_FMT(4x4), 21901e04c3fSmrg ASTC_FMT(5x4), 22001e04c3fSmrg ASTC_FMT(5x5), 22101e04c3fSmrg ASTC_FMT(6x5), 22201e04c3fSmrg ASTC_FMT(6x6), 22301e04c3fSmrg ASTC_FMT(8x5), 22401e04c3fSmrg ASTC_FMT(8x6), 22501e04c3fSmrg ASTC_FMT(8x8), 22601e04c3fSmrg ASTC_FMT(10x5), 22701e04c3fSmrg ASTC_FMT(10x6), 22801e04c3fSmrg ASTC_FMT(10x8), 22901e04c3fSmrg ASTC_FMT(10x10), 23001e04c3fSmrg ASTC_FMT(12x10), 23101e04c3fSmrg ASTC_FMT(12x12), 23201e04c3fSmrg#undef ASTC_FMT 23301e04c3fSmrg}; 23401e04c3fSmrg 23501e04c3fSmrgstatic const struct internal_format_class_info gles_astc_3d_compatible_internal_formats[] = { 23601e04c3fSmrg#define ASTC_FMT(size) \ 23701e04c3fSmrg {VIEW_CLASS_ASTC_##size##_RGBA, GL_COMPRESSED_RGBA_ASTC_##size##_OES}, \ 23801e04c3fSmrg {VIEW_CLASS_ASTC_##size##_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_##size##_OES} 23901e04c3fSmrg 24001e04c3fSmrg ASTC_FMT(3x3x3), 24101e04c3fSmrg ASTC_FMT(4x3x3), 24201e04c3fSmrg ASTC_FMT(4x4x3), 24301e04c3fSmrg ASTC_FMT(4x4x4), 24401e04c3fSmrg ASTC_FMT(5x4x4), 24501e04c3fSmrg ASTC_FMT(5x5x4), 24601e04c3fSmrg ASTC_FMT(5x5x5), 24701e04c3fSmrg ASTC_FMT(6x5x5), 24801e04c3fSmrg ASTC_FMT(6x6x5), 24901e04c3fSmrg ASTC_FMT(6x6x6), 25001e04c3fSmrg#undef ASTC_FMT 25101e04c3fSmrg}; 25201e04c3fSmrg 25301e04c3fSmrgGLenum 25401e04c3fSmrg_mesa_texture_view_lookup_view_class(const struct gl_context *ctx, GLenum internalformat) 255af69d88dSmrg{ 256af69d88dSmrg GLuint i; 257af69d88dSmrg 258af69d88dSmrg for (i = 0; i < ARRAY_SIZE(compatible_internal_formats); i++) { 259af69d88dSmrg if (compatible_internal_formats[i].internal_format == internalformat) 260af69d88dSmrg return compatible_internal_formats[i].view_class; 261af69d88dSmrg } 262af69d88dSmrg 26301e04c3fSmrg if (ctx->Extensions.EXT_texture_compression_s3tc && 26401e04c3fSmrg ctx->Extensions.EXT_texture_sRGB) { 265af69d88dSmrg for (i = 0; i < ARRAY_SIZE(s3tc_compatible_internal_formats); i++) { 26601e04c3fSmrg if (s3tc_compatible_internal_formats[i].internal_format 26701e04c3fSmrg == internalformat) 268af69d88dSmrg return s3tc_compatible_internal_formats[i].view_class; 269af69d88dSmrg } 270af69d88dSmrg } 27101e04c3fSmrg 27201e04c3fSmrg if (_mesa_is_gles3(ctx)) { 27301e04c3fSmrg for (i = 0; i < ARRAY_SIZE(gles_etc2_compatible_internal_formats); i++) { 27401e04c3fSmrg if (gles_etc2_compatible_internal_formats[i].internal_format 27501e04c3fSmrg == internalformat) 27601e04c3fSmrg return gles_etc2_compatible_internal_formats[i].view_class; 27701e04c3fSmrg } 27801e04c3fSmrg 27901e04c3fSmrg if (ctx->Extensions.KHR_texture_compression_astc_ldr) { 28001e04c3fSmrg for (i = 0; i < ARRAY_SIZE(gles_astc_compatible_internal_formats); i++) { 28101e04c3fSmrg if (gles_astc_compatible_internal_formats[i].internal_format 28201e04c3fSmrg == internalformat) 28301e04c3fSmrg return gles_astc_compatible_internal_formats[i].view_class; 28401e04c3fSmrg } 28501e04c3fSmrg } 28601e04c3fSmrg 28701e04c3fSmrg if (ctx->Extensions.OES_texture_compression_astc) { 28801e04c3fSmrg for (i = 0; i < ARRAY_SIZE(gles_astc_3d_compatible_internal_formats); i++) { 28901e04c3fSmrg if (gles_astc_3d_compatible_internal_formats[i].internal_format 29001e04c3fSmrg == internalformat) 29101e04c3fSmrg return gles_astc_3d_compatible_internal_formats[i].view_class; 29201e04c3fSmrg } 29301e04c3fSmrg } 29401e04c3fSmrg } 295af69d88dSmrg return GL_FALSE; 296af69d88dSmrg} 297af69d88dSmrg 298af69d88dSmrg/** 299af69d88dSmrg * Initialize new texture's gl_texture_image structures. Will not call driver 300af69d88dSmrg * to allocate new space, simply record relevant layer, face, format, etc. 301af69d88dSmrg * \return GL_FALSE if any error, GL_TRUE otherwise. 302af69d88dSmrg */ 303af69d88dSmrgstatic GLboolean 304af69d88dSmrginitialize_texture_fields(struct gl_context *ctx, 305af69d88dSmrg GLenum target, 306af69d88dSmrg struct gl_texture_object *texObj, 307af69d88dSmrg GLint levels, 308af69d88dSmrg GLsizei width, GLsizei height, GLsizei depth, 30901e04c3fSmrg GLenum internalFormat, mesa_format texFormat, 31001e04c3fSmrg GLuint numSamples, GLboolean fixedSampleLocations) 311af69d88dSmrg{ 312af69d88dSmrg const GLuint numFaces = _mesa_num_tex_faces(target); 313af69d88dSmrg GLint level, levelWidth = width, levelHeight = height, levelDepth = depth; 314af69d88dSmrg GLuint face; 315af69d88dSmrg 316af69d88dSmrg /* Pretend we are bound to initialize the gl_texture_image structs */ 317af69d88dSmrg texObj->Target = target; 318af69d88dSmrg 319af69d88dSmrg /* Set up all the texture object's gl_texture_images */ 320af69d88dSmrg for (level = 0; level < levels; level++) { 321af69d88dSmrg for (face = 0; face < numFaces; face++) { 322af69d88dSmrg struct gl_texture_image *texImage; 32301e04c3fSmrg const GLenum faceTarget = _mesa_cube_face_target(target, face); 324af69d88dSmrg 325af69d88dSmrg texImage = _mesa_get_tex_image(ctx, texObj, faceTarget, level); 326af69d88dSmrg 327af69d88dSmrg if (!texImage) { 328af69d88dSmrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage"); 329af69d88dSmrg return GL_FALSE; 330af69d88dSmrg } 331af69d88dSmrg 33201e04c3fSmrg _mesa_init_teximage_fields_ms(ctx, texImage, 333af69d88dSmrg levelWidth, levelHeight, levelDepth, 33401e04c3fSmrg 0, internalFormat, texFormat, 33501e04c3fSmrg numSamples, fixedSampleLocations); 336af69d88dSmrg } 337af69d88dSmrg 33801e04c3fSmrg _mesa_next_mipmap_level_size(target, 0, 33901e04c3fSmrg levelWidth, levelHeight, levelDepth, 340af69d88dSmrg &levelWidth, &levelHeight, &levelDepth); 341af69d88dSmrg } 342af69d88dSmrg 343af69d88dSmrg /* "unbind" */ 344af69d88dSmrg texObj->Target = 0; 345af69d88dSmrg 346af69d88dSmrg return GL_TRUE; 347af69d88dSmrg} 348af69d88dSmrg 349af69d88dSmrg#define RETURN_IF_SUPPORTED(t) do { \ 350af69d88dSmrg if (newTarget == GL_ ## t) \ 351af69d88dSmrg return true; \ 352af69d88dSmrg} while (0) 353af69d88dSmrg 354af69d88dSmrg/** 355af69d88dSmrg * Check for compatible target 356af69d88dSmrg * If an error is found, record it with _mesa_error() 357af69d88dSmrg * \return false if any error, true otherwise. 358af69d88dSmrg */ 359af69d88dSmrgstatic bool 360af69d88dSmrgtarget_valid(struct gl_context *ctx, GLenum origTarget, GLenum newTarget) 361af69d88dSmrg{ 362af69d88dSmrg /* 363af69d88dSmrg * From ARB_texture_view spec: 364af69d88dSmrg --------------------------------------------------------------------------------------------------------- 365af69d88dSmrg | Original target | Valid new targets | 366af69d88dSmrg --------------------------------------------------------------------------------------------------------- 367af69d88dSmrg | TEXTURE_1D | TEXTURE_1D, TEXTURE_1D_ARRAY | 368af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 369af69d88dSmrg | TEXTURE_2D | TEXTURE_2D, TEXTURE_2D_ARRAY | 370af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 371af69d88dSmrg | TEXTURE_3D | TEXTURE_3D | 372af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 373af69d88dSmrg | TEXTURE_CUBE_MAP | TEXTURE_CUBE_MAP, TEXTURE_2D, TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY | 374af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 375af69d88dSmrg | TEXTURE_RECTANGLE | TEXTURE_RECTANGLE | 376af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 377af69d88dSmrg | TEXTURE_BUFFER | <none> | 378af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 379af69d88dSmrg | TEXTURE_1D_ARRAY | TEXTURE_1D_ARRAY, TEXTURE_1D | 380af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 381af69d88dSmrg | TEXTURE_2D_ARRAY | TEXTURE_2D_ARRAY, TEXTURE_2D, TEXTURE_CUBE_MAP, TEXTURE_CUBE_MAP_ARRAY | 382af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 383af69d88dSmrg | TEXTURE_CUBE_MAP_ARRAY | TEXTURE_CUBE_MAP_ARRAY, TEXTURE_2D_ARRAY, TEXTURE_2D, TEXTURE_CUBE_MAP | 384af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 385af69d88dSmrg | TEXTURE_2D_MULTISAMPLE | TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY | 386af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 387af69d88dSmrg | TEXTURE_2D_MULTISAMPLE_ARRAY | TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY | 388af69d88dSmrg --------------------------------------------------------------------------------------------------------- 389af69d88dSmrg */ 390af69d88dSmrg 391af69d88dSmrg switch (origTarget) { 392af69d88dSmrg case GL_TEXTURE_1D: 393af69d88dSmrg case GL_TEXTURE_1D_ARRAY: 394af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_1D); 395af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_1D_ARRAY); 396af69d88dSmrg break; 397af69d88dSmrg case GL_TEXTURE_2D: 398af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_2D); 399af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_2D_ARRAY); 400af69d88dSmrg break; 401af69d88dSmrg case GL_TEXTURE_3D: 402af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_3D); 403af69d88dSmrg break; 404af69d88dSmrg case GL_TEXTURE_RECTANGLE: 405af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_RECTANGLE); 406af69d88dSmrg break; 407af69d88dSmrg case GL_TEXTURE_CUBE_MAP: 408af69d88dSmrg case GL_TEXTURE_2D_ARRAY: 409af69d88dSmrg case GL_TEXTURE_CUBE_MAP_ARRAY: 410af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_2D); 411af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_2D_ARRAY); 412af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_CUBE_MAP); 413af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_CUBE_MAP_ARRAY); 414af69d88dSmrg break; 415af69d88dSmrg case GL_TEXTURE_2D_MULTISAMPLE: 416af69d88dSmrg case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 417af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_2D_MULTISAMPLE); 418af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_2D_MULTISAMPLE_ARRAY); 419af69d88dSmrg break; 420af69d88dSmrg } 421af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 422af69d88dSmrg "glTextureView(illegal target=%s)", 42301e04c3fSmrg _mesa_enum_to_string(newTarget)); 424af69d88dSmrg return false; 425af69d88dSmrg} 426af69d88dSmrg#undef RETURN_IF_SUPPORTED 427af69d88dSmrg 428af69d88dSmrg/** 429af69d88dSmrg * Check for compatible format 430af69d88dSmrg * If an error is found, record it with _mesa_error() 431af69d88dSmrg * \return false if any error, true otherwise. 432af69d88dSmrg */ 43301e04c3fSmrgbool 43401e04c3fSmrg_mesa_texture_view_compatible_format(const struct gl_context *ctx, 435af69d88dSmrg GLenum origInternalFormat, 436af69d88dSmrg GLenum newInternalFormat) 437af69d88dSmrg{ 438af69d88dSmrg unsigned int origViewClass, newViewClass; 439af69d88dSmrg 440af69d88dSmrg /* The two textures' internal formats must be compatible according to 441af69d88dSmrg * Table 3.X.2 (Compatible internal formats for TextureView) 442af69d88dSmrg * if the internal format exists in that table the view class must match. 443af69d88dSmrg * The internal formats must be identical if not in that table, 444af69d88dSmrg * or an INVALID_OPERATION error is generated. 445af69d88dSmrg */ 446af69d88dSmrg if (origInternalFormat == newInternalFormat) 44701e04c3fSmrg return true; 448af69d88dSmrg 44901e04c3fSmrg origViewClass = _mesa_texture_view_lookup_view_class(ctx, origInternalFormat); 45001e04c3fSmrg newViewClass = _mesa_texture_view_lookup_view_class(ctx, newInternalFormat); 451af69d88dSmrg if ((origViewClass == newViewClass) && origViewClass != false) 45201e04c3fSmrg return true; 453af69d88dSmrg 45401e04c3fSmrg return false; 455af69d88dSmrg} 45601e04c3fSmrg 457af69d88dSmrg/** 458af69d88dSmrg * Helper function for TexStorage and teximagemultisample to set immutable 459af69d88dSmrg * texture state needed by ARB_texture_view. 460af69d88dSmrg */ 461af69d88dSmrgvoid 462af69d88dSmrg_mesa_set_texture_view_state(struct gl_context *ctx, 463af69d88dSmrg struct gl_texture_object *texObj, 464af69d88dSmrg GLenum target, GLuint levels) 465af69d88dSmrg{ 466af69d88dSmrg struct gl_texture_image *texImage; 467af69d88dSmrg 468af69d88dSmrg /* Get a reference to what will become this View's base level */ 46901e04c3fSmrg texImage = _mesa_select_tex_image(texObj, target, 0); 470af69d88dSmrg 47101e04c3fSmrg /* When an immutable texture is created via glTexStorage or 47201e04c3fSmrg * glTexImageMultisample, 473af69d88dSmrg * TEXTURE_IMMUTABLE_FORMAT becomes TRUE. 474af69d88dSmrg * TEXTURE_IMMUTABLE_LEVELS and TEXTURE_VIEW_NUM_LEVELS become levels. 475af69d88dSmrg * If the texture target is TEXTURE_1D_ARRAY then 476af69d88dSmrg * TEXTURE_VIEW_NUM_LAYERS becomes height. 477af69d88dSmrg * If the texture target is TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY, 47801e04c3fSmrg * or TEXTURE_2D_MULTISAMPLE_ARRAY then TEXTURE_VIEW_NUM_LAYERS becomes 47901e04c3fSmrg * depth. 480af69d88dSmrg * If the texture target is TEXTURE_CUBE_MAP, then 481af69d88dSmrg * TEXTURE_VIEW_NUM_LAYERS becomes 6. 482af69d88dSmrg * For any other texture target, TEXTURE_VIEW_NUM_LAYERS becomes 1. 48301e04c3fSmrg * 484af69d88dSmrg * ARB_texture_multisample: Multisample textures do 485af69d88dSmrg * not have multiple image levels. 486af69d88dSmrg */ 487af69d88dSmrg 488af69d88dSmrg texObj->Immutable = GL_TRUE; 4897ec681f3Smrg texObj->External = GL_FALSE; 4907ec681f3Smrg texObj->Attrib.ImmutableLevels = levels; 4917ec681f3Smrg texObj->Attrib.MinLevel = 0; 4927ec681f3Smrg texObj->Attrib.NumLevels = levels; 4937ec681f3Smrg texObj->Attrib.MinLayer = 0; 4947ec681f3Smrg texObj->Attrib.NumLayers = 1; 495af69d88dSmrg switch (target) { 496af69d88dSmrg case GL_TEXTURE_1D_ARRAY: 4977ec681f3Smrg texObj->Attrib.NumLayers = texImage->Height; 498af69d88dSmrg break; 499af69d88dSmrg 500af69d88dSmrg case GL_TEXTURE_2D_MULTISAMPLE: 5017ec681f3Smrg texObj->Attrib.NumLevels = 1; 5027ec681f3Smrg texObj->Attrib.ImmutableLevels = 1; 503af69d88dSmrg break; 504af69d88dSmrg 505af69d88dSmrg case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 5067ec681f3Smrg texObj->Attrib.NumLevels = 1; 5077ec681f3Smrg texObj->Attrib.ImmutableLevels = 1; 5087ec681f3Smrg FALLTHROUGH; 5097ec681f3Smrg /* fallthrough to set NumLayers */ 510af69d88dSmrg 511af69d88dSmrg case GL_TEXTURE_2D_ARRAY: 512af69d88dSmrg case GL_TEXTURE_CUBE_MAP_ARRAY: 5137ec681f3Smrg texObj->Attrib.NumLayers = texImage->Depth; 514af69d88dSmrg break; 515af69d88dSmrg 516af69d88dSmrg case GL_TEXTURE_CUBE_MAP: 5177ec681f3Smrg texObj->Attrib.NumLayers = 6; 518af69d88dSmrg break; 519af69d88dSmrg } 520af69d88dSmrg} 521af69d88dSmrg 522af69d88dSmrg/** 523af69d88dSmrg * glTextureView (ARB_texture_view) 524af69d88dSmrg * If an error is found, record it with _mesa_error() 525af69d88dSmrg * \return none. 526af69d88dSmrg */ 52701e04c3fSmrgstatic ALWAYS_INLINE void 52801e04c3fSmrgtexture_view(struct gl_context *ctx, struct gl_texture_object *origTexObj, 52901e04c3fSmrg struct gl_texture_object *texObj, GLenum target, 53001e04c3fSmrg GLenum internalformat, GLuint minlevel, GLuint numlevels, 53101e04c3fSmrg GLuint minlayer, GLuint numlayers, bool no_error) 532af69d88dSmrg{ 533af69d88dSmrg struct gl_texture_image *origTexImage; 534af69d88dSmrg GLuint newViewNumLevels, newViewNumLayers; 535af69d88dSmrg GLsizei width, height, depth; 536af69d88dSmrg mesa_format texFormat; 537af69d88dSmrg GLboolean sizeOK, dimensionsOK; 538af69d88dSmrg GLenum faceTarget; 539af69d88dSmrg 540af69d88dSmrg texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, 541af69d88dSmrg internalformat, GL_NONE, GL_NONE); 542af69d88dSmrg if (texFormat == MESA_FORMAT_NONE) return; 543af69d88dSmrg 5447ec681f3Smrg newViewNumLevels = MIN2(numlevels, origTexObj->Attrib.NumLevels - minlevel); 5457ec681f3Smrg newViewNumLayers = MIN2(numlayers, origTexObj->Attrib.NumLayers - minlayer); 546af69d88dSmrg 54701e04c3fSmrg faceTarget = _mesa_cube_face_target(origTexObj->Target, minlayer); 548af69d88dSmrg 549af69d88dSmrg /* Get a reference to what will become this View's base level */ 55001e04c3fSmrg origTexImage = _mesa_select_tex_image(origTexObj, faceTarget, minlevel); 551af69d88dSmrg width = origTexImage->Width; 552af69d88dSmrg height = origTexImage->Height; 553af69d88dSmrg depth = origTexImage->Depth; 554af69d88dSmrg 555af69d88dSmrg /* Adjust width, height, depth to be appropriate for new target */ 556af69d88dSmrg switch (target) { 557af69d88dSmrg case GL_TEXTURE_1D: 55801e04c3fSmrg height = 1; 55901e04c3fSmrg break; 56001e04c3fSmrg 561af69d88dSmrg case GL_TEXTURE_3D: 562af69d88dSmrg break; 563af69d88dSmrg 564af69d88dSmrg case GL_TEXTURE_1D_ARRAY: 565af69d88dSmrg height = (GLsizei) newViewNumLayers; 566af69d88dSmrg break; 567af69d88dSmrg 568af69d88dSmrg case GL_TEXTURE_2D: 569af69d88dSmrg case GL_TEXTURE_2D_MULTISAMPLE: 570af69d88dSmrg case GL_TEXTURE_RECTANGLE: 571af69d88dSmrg depth = 1; 572af69d88dSmrg break; 573af69d88dSmrg case GL_TEXTURE_CUBE_MAP: 57401e04c3fSmrg /* If the new texture's target is TEXTURE_CUBE_MAP, the clamped 57501e04c3fSmrg * <numlayers> must be equal to 6. 576af69d88dSmrg */ 57701e04c3fSmrg if (!no_error && newViewNumLayers != 6) { 57801e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, 57901e04c3fSmrg "glTextureView(clamped numlayers %d != 6)", 580af69d88dSmrg newViewNumLayers); 581af69d88dSmrg return; 582af69d88dSmrg } 58301e04c3fSmrg depth = 1; 584af69d88dSmrg break; 585af69d88dSmrg 58601e04c3fSmrg case GL_TEXTURE_2D_ARRAY: 58701e04c3fSmrg case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 58801e04c3fSmrg depth = newViewNumLayers; 58901e04c3fSmrg break; 590af69d88dSmrg case GL_TEXTURE_CUBE_MAP_ARRAY: 591af69d88dSmrg /* If the new texture's target is TEXTURE_CUBE_MAP_ARRAY, 592af69d88dSmrg * then <numlayers> counts layer-faces rather than layers, 593af69d88dSmrg * and the clamped <numlayers> must be a multiple of 6. 594af69d88dSmrg * Otherwise, the error INVALID_VALUE is generated. 595af69d88dSmrg */ 59601e04c3fSmrg if (!no_error && (newViewNumLayers % 6) != 0) { 597af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, 59801e04c3fSmrg "glTextureView(clamped numlayers %d is not" 59901e04c3fSmrg " a multiple of 6)", 600af69d88dSmrg newViewNumLayers); 601af69d88dSmrg return; 602af69d88dSmrg } 60301e04c3fSmrg depth = newViewNumLayers; 604af69d88dSmrg break; 605af69d88dSmrg } 606af69d88dSmrg 60701e04c3fSmrg if (!no_error) { 60801e04c3fSmrg /* If the dimensions of the original texture are larger than the maximum 60901e04c3fSmrg * supported dimensions of the new target, the error INVALID_OPERATION is 61001e04c3fSmrg * generated. For example, if the original texture has a TEXTURE_2D_ARRAY 61101e04c3fSmrg * target and its width is greater than MAX_CUBE_MAP_TEXTURE_SIZE, an 61201e04c3fSmrg * error will be generated if TextureView is called to create a 61301e04c3fSmrg * TEXTURE_CUBE_MAP view. 61401e04c3fSmrg */ 61501e04c3fSmrg dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0, 61601e04c3fSmrg width, height, depth, 0); 61701e04c3fSmrg if (!dimensionsOK) { 61801e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 61901e04c3fSmrg "glTextureView(invalid width or height or depth)"); 62001e04c3fSmrg return; 62101e04c3fSmrg } 62201e04c3fSmrg 62301e04c3fSmrg sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 1, 0, texFormat, 62401e04c3fSmrg origTexImage->NumSamples, 62501e04c3fSmrg width, height, depth); 62601e04c3fSmrg if (!sizeOK) { 62701e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 62801e04c3fSmrg "glTextureView(invalid texture size)"); 62901e04c3fSmrg return; 63001e04c3fSmrg } 63101e04c3fSmrg 63201e04c3fSmrg /* If <target> is TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_RECTANGLE, 63301e04c3fSmrg * or TEXTURE_2D_MULTISAMPLE and <numlayers> does not equal 1, the error 63401e04c3fSmrg * INVALID_VALUE is generated. 63501e04c3fSmrg */ 63601e04c3fSmrg switch (target) { 63701e04c3fSmrg case GL_TEXTURE_1D: 63801e04c3fSmrg case GL_TEXTURE_2D: 63901e04c3fSmrg case GL_TEXTURE_3D: 64001e04c3fSmrg case GL_TEXTURE_RECTANGLE: 64101e04c3fSmrg case GL_TEXTURE_2D_MULTISAMPLE: 64201e04c3fSmrg if (numlayers != 1) { 64301e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(numlayers %d != 1)", 64401e04c3fSmrg numlayers); 64501e04c3fSmrg return; 64601e04c3fSmrg } 64701e04c3fSmrg break; 64801e04c3fSmrg case GL_TEXTURE_CUBE_MAP: 64901e04c3fSmrg break; 65001e04c3fSmrg case GL_TEXTURE_CUBE_MAP_ARRAY: 65101e04c3fSmrg break; 65201e04c3fSmrg } 65301e04c3fSmrg 65401e04c3fSmrg /* If the new texture's target is TEXTURE_CUBE_MAP or 65501e04c3fSmrg * TEXTURE_CUBE_MAP_ARRAY, the width and height of the original texture's 65601e04c3fSmrg * levels must be equal otherwise the error INVALID_OPERATION is 65701e04c3fSmrg * generated. 65801e04c3fSmrg */ 65901e04c3fSmrg if ((target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) 66001e04c3fSmrg && (origTexImage->Width != origTexImage->Height)) { 66101e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 66201e04c3fSmrg "glTextureView(origtexture width (%d) != height (%d))", 66301e04c3fSmrg origTexImage->Width, origTexImage->Height); 66401e04c3fSmrg return; 66501e04c3fSmrg } 666af69d88dSmrg } 667af69d88dSmrg 668af69d88dSmrg /* When the original texture's target is TEXTURE_CUBE_MAP, the layer 669af69d88dSmrg * parameters are interpreted in the same order as if it were a 670af69d88dSmrg * TEXTURE_CUBE_MAP_ARRAY with 6 layer-faces. 671af69d88dSmrg */ 672af69d88dSmrg 673af69d88dSmrg /* If the internal format does not exactly match the internal format of the 674af69d88dSmrg * original texture, the contents of the memory are reinterpreted in the 675af69d88dSmrg * same manner as for image bindings described in 676af69d88dSmrg * section 3.9.20 (Texture Image Loads and Stores). 677af69d88dSmrg */ 678af69d88dSmrg 679af69d88dSmrg /* TEXTURE_BASE_LEVEL and TEXTURE_MAX_LEVEL are interpreted 680af69d88dSmrg * relative to the view and not relative to the original data store. 681af69d88dSmrg */ 682af69d88dSmrg 683af69d88dSmrg if (!initialize_texture_fields(ctx, target, texObj, newViewNumLevels, 684af69d88dSmrg width, height, depth, 68501e04c3fSmrg internalformat, texFormat, 68601e04c3fSmrg origTexImage->NumSamples, 68701e04c3fSmrg origTexImage->FixedSampleLocations)) { 688af69d88dSmrg return; /* Already recorded error */ 689af69d88dSmrg } 690af69d88dSmrg 6917ec681f3Smrg texObj->Attrib.MinLevel = origTexObj->Attrib.MinLevel + minlevel; 6927ec681f3Smrg texObj->Attrib.MinLayer = origTexObj->Attrib.MinLayer + minlayer; 6937ec681f3Smrg texObj->Attrib.NumLevels = newViewNumLevels; 6947ec681f3Smrg texObj->Attrib.NumLayers = newViewNumLayers; 695af69d88dSmrg texObj->Immutable = GL_TRUE; 6967ec681f3Smrg texObj->External = GL_FALSE; 6977ec681f3Smrg texObj->Attrib.ImmutableLevels = origTexObj->Attrib.ImmutableLevels; 698af69d88dSmrg texObj->Target = target; 69901e04c3fSmrg texObj->TargetIndex = _mesa_tex_target_to_index(ctx, target); 70001e04c3fSmrg assert(texObj->TargetIndex < NUM_TEXTURE_TARGETS); 701af69d88dSmrg 70201e04c3fSmrg if (ctx->Driver.TextureView != NULL && 70301e04c3fSmrg !ctx->Driver.TextureView(ctx, texObj, origTexObj)) { 704af69d88dSmrg return; /* driver recorded error */ 705af69d88dSmrg } 706af69d88dSmrg} 70701e04c3fSmrg 70801e04c3fSmrgvoid GLAPIENTRY 70901e04c3fSmrg_mesa_TextureView_no_error(GLuint texture, GLenum target, GLuint origtexture, 71001e04c3fSmrg GLenum internalformat, 71101e04c3fSmrg GLuint minlevel, GLuint numlevels, 71201e04c3fSmrg GLuint minlayer, GLuint numlayers) 71301e04c3fSmrg{ 71401e04c3fSmrg struct gl_texture_object *texObj; 71501e04c3fSmrg struct gl_texture_object *origTexObj; 71601e04c3fSmrg 71701e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 71801e04c3fSmrg 71901e04c3fSmrg origTexObj = _mesa_lookup_texture(ctx, origtexture); 72001e04c3fSmrg texObj = _mesa_lookup_texture(ctx, texture); 72101e04c3fSmrg 72201e04c3fSmrg texture_view(ctx, origTexObj, texObj, target, internalformat, minlevel, 72301e04c3fSmrg numlevels, minlayer, numlayers, true); 72401e04c3fSmrg} 72501e04c3fSmrg 72601e04c3fSmrgvoid GLAPIENTRY 72701e04c3fSmrg_mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture, 72801e04c3fSmrg GLenum internalformat, 72901e04c3fSmrg GLuint minlevel, GLuint numlevels, 73001e04c3fSmrg GLuint minlayer, GLuint numlayers) 73101e04c3fSmrg{ 73201e04c3fSmrg struct gl_texture_object *texObj; 73301e04c3fSmrg struct gl_texture_object *origTexObj; 73401e04c3fSmrg GLuint newViewMinLevel, newViewMinLayer; 73501e04c3fSmrg 73601e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 73701e04c3fSmrg 73801e04c3fSmrg if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) 73901e04c3fSmrg _mesa_debug(ctx, "glTextureView %d %s %d %s %d %d %d %d\n", 74001e04c3fSmrg texture, _mesa_enum_to_string(target), origtexture, 74101e04c3fSmrg _mesa_enum_to_string(internalformat), 74201e04c3fSmrg minlevel, numlevels, minlayer, numlayers); 74301e04c3fSmrg 74401e04c3fSmrg if (origtexture == 0) { 74501e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)", 74601e04c3fSmrg origtexture); 74701e04c3fSmrg return; 74801e04c3fSmrg } 74901e04c3fSmrg 75001e04c3fSmrg /* Need original texture information to validate arguments */ 75101e04c3fSmrg origTexObj = _mesa_lookup_texture(ctx, origtexture); 75201e04c3fSmrg 75301e04c3fSmrg /* If <origtexture> is not the name of a texture, INVALID_VALUE 75401e04c3fSmrg * is generated. 75501e04c3fSmrg */ 75601e04c3fSmrg if (!origTexObj) { 75701e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)", 75801e04c3fSmrg origtexture); 75901e04c3fSmrg return; 76001e04c3fSmrg } 76101e04c3fSmrg 76201e04c3fSmrg /* If <origtexture>'s TEXTURE_IMMUTABLE_FORMAT value is not TRUE, 76301e04c3fSmrg * INVALID_OPERATION is generated. 76401e04c3fSmrg */ 76501e04c3fSmrg if (!origTexObj->Immutable) { 76601e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 76701e04c3fSmrg "glTextureView(origtexture not immutable)"); 76801e04c3fSmrg return; 76901e04c3fSmrg } 77001e04c3fSmrg 77101e04c3fSmrg /* If <texture> is 0, INVALID_VALUE is generated. */ 77201e04c3fSmrg if (texture == 0) { 77301e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(texture = 0)"); 77401e04c3fSmrg return; 77501e04c3fSmrg } 77601e04c3fSmrg 77701e04c3fSmrg /* If <texture> is not a valid name returned by GenTextures, 77801e04c3fSmrg * the error INVALID_OPERATION is generated. 77901e04c3fSmrg */ 78001e04c3fSmrg texObj = _mesa_lookup_texture(ctx, texture); 78101e04c3fSmrg if (texObj == NULL) { 78201e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 78301e04c3fSmrg "glTextureView(texture = %u non-gen name)", texture); 78401e04c3fSmrg return; 78501e04c3fSmrg } 78601e04c3fSmrg 78701e04c3fSmrg /* If <texture> has already been bound and given a target, then 78801e04c3fSmrg * the error INVALID_OPERATION is generated. 78901e04c3fSmrg */ 79001e04c3fSmrg if (texObj->Target) { 79101e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 79201e04c3fSmrg "glTextureView(texture = %u already bound)", texture); 79301e04c3fSmrg return; 79401e04c3fSmrg } 79501e04c3fSmrg 79601e04c3fSmrg /* Check for compatible target */ 79701e04c3fSmrg if (!target_valid(ctx, origTexObj->Target, target)) { 79801e04c3fSmrg return; /* error was recorded */ 79901e04c3fSmrg } 80001e04c3fSmrg 80101e04c3fSmrg /* minlevel and minlayer are relative to the view of origtexture. 80201e04c3fSmrg * If minlevel or minlayer is greater than level or layer, respectively, 80301e04c3fSmrg * return INVALID_VALUE. 80401e04c3fSmrg */ 8057ec681f3Smrg newViewMinLevel = origTexObj->Attrib.MinLevel + minlevel; 8067ec681f3Smrg newViewMinLayer = origTexObj->Attrib.MinLayer + minlayer; 8077ec681f3Smrg if (newViewMinLevel >= (origTexObj->Attrib.MinLevel + 8087ec681f3Smrg origTexObj->Attrib.NumLevels)) { 80901e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, 81001e04c3fSmrg "glTextureView(new minlevel (%d) > orig minlevel (%d)" 81101e04c3fSmrg " + orig numlevels (%d))", 8127ec681f3Smrg newViewMinLevel, origTexObj->Attrib.MinLevel, 8137ec681f3Smrg origTexObj->Attrib.NumLevels); 81401e04c3fSmrg return; 81501e04c3fSmrg } 81601e04c3fSmrg 8177ec681f3Smrg if (newViewMinLayer >= (origTexObj->Attrib.MinLayer + 8187ec681f3Smrg origTexObj->Attrib.NumLayers)) { 81901e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, 82001e04c3fSmrg "glTextureView(new minlayer (%d) > orig minlayer (%d)" 82101e04c3fSmrg " + orig numlayers (%d))", 8227ec681f3Smrg newViewMinLayer, origTexObj->Attrib.MinLayer, 8237ec681f3Smrg origTexObj->Attrib.NumLayers); 82401e04c3fSmrg return; 82501e04c3fSmrg } 82601e04c3fSmrg 82701e04c3fSmrg if (!_mesa_texture_view_compatible_format(ctx, 82801e04c3fSmrg origTexObj->Image[0][0]->InternalFormat, 82901e04c3fSmrg internalformat)) { 83001e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 83101e04c3fSmrg "glTextureView(internalformat %s not compatible with origtexture %s)", 83201e04c3fSmrg _mesa_enum_to_string(internalformat), 83301e04c3fSmrg _mesa_enum_to_string(origTexObj->Image[0][0]->InternalFormat)); 83401e04c3fSmrg return; 83501e04c3fSmrg } 83601e04c3fSmrg 83701e04c3fSmrg texture_view(ctx, origTexObj, texObj, target, internalformat, minlevel, 83801e04c3fSmrg numlevels, minlayer, numlayers, false); 83901e04c3fSmrg} 840