textureview.c revision b9abf16e
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" 37af69d88dSmrg#include "imports.h" 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}, 172af69d88dSmrg {GL_VIEW_CLASS_16_BITS, GL_R16_SNORM}, 173af69d88dSmrg {GL_VIEW_CLASS_8_BITS, GL_R8UI}, 174af69d88dSmrg {GL_VIEW_CLASS_8_BITS, GL_R8I}, 175af69d88dSmrg {GL_VIEW_CLASS_8_BITS, GL_R8}, 176af69d88dSmrg {GL_VIEW_CLASS_8_BITS, GL_R8_SNORM}, 177b9abf16eSmaya {GL_VIEW_CLASS_8_BITS, GL_SR8_EXT}, 178af69d88dSmrg {GL_VIEW_CLASS_RGTC1_RED, GL_COMPRESSED_RED_RGTC1}, 179af69d88dSmrg {GL_VIEW_CLASS_RGTC1_RED, GL_COMPRESSED_SIGNED_RED_RGTC1}, 180af69d88dSmrg {GL_VIEW_CLASS_RGTC2_RG, GL_COMPRESSED_RG_RGTC2}, 181af69d88dSmrg {GL_VIEW_CLASS_RGTC2_RG, GL_COMPRESSED_SIGNED_RG_RGTC2}, 182af69d88dSmrg {GL_VIEW_CLASS_BPTC_UNORM, GL_COMPRESSED_RGBA_BPTC_UNORM_ARB}, 183af69d88dSmrg {GL_VIEW_CLASS_BPTC_UNORM, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB}, 184af69d88dSmrg {GL_VIEW_CLASS_BPTC_FLOAT, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB}, 185af69d88dSmrg {GL_VIEW_CLASS_BPTC_FLOAT, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB}, 186af69d88dSmrg}; 187af69d88dSmrg 188af69d88dSmrgstatic const struct internal_format_class_info s3tc_compatible_internal_formats[] = { 189af69d88dSmrg {GL_VIEW_CLASS_S3TC_DXT1_RGB, GL_COMPRESSED_RGB_S3TC_DXT1_EXT}, 190af69d88dSmrg {GL_VIEW_CLASS_S3TC_DXT1_RGB, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT}, 191af69d88dSmrg {GL_VIEW_CLASS_S3TC_DXT1_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT}, 192af69d88dSmrg {GL_VIEW_CLASS_S3TC_DXT1_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT}, 193af69d88dSmrg {GL_VIEW_CLASS_S3TC_DXT3_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT}, 194af69d88dSmrg {GL_VIEW_CLASS_S3TC_DXT3_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT}, 195af69d88dSmrg {GL_VIEW_CLASS_S3TC_DXT5_RGBA, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT}, 196af69d88dSmrg {GL_VIEW_CLASS_S3TC_DXT5_RGBA, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT}, 197af69d88dSmrg}; 198af69d88dSmrg 19901e04c3fSmrgstatic const struct internal_format_class_info gles_etc2_compatible_internal_formats[] = { 20001e04c3fSmrg {VIEW_CLASS_EAC_R11, GL_COMPRESSED_R11_EAC}, 20101e04c3fSmrg {VIEW_CLASS_EAC_R11, GL_COMPRESSED_SIGNED_R11_EAC}, 20201e04c3fSmrg {VIEW_CLASS_EAC_RG11, GL_COMPRESSED_RG11_EAC}, 20301e04c3fSmrg {VIEW_CLASS_EAC_RG11, GL_COMPRESSED_SIGNED_RG11_EAC}, 20401e04c3fSmrg {VIEW_CLASS_ETC2_RGB, GL_COMPRESSED_RGB8_ETC2}, 20501e04c3fSmrg {VIEW_CLASS_ETC2_RGB, GL_COMPRESSED_SRGB8_ETC2}, 20601e04c3fSmrg {VIEW_CLASS_ETC2_RGBA, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2}, 20701e04c3fSmrg {VIEW_CLASS_ETC2_RGBA, GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2}, 20801e04c3fSmrg {VIEW_CLASS_ETC2_EAC_RGBA, GL_COMPRESSED_RGBA8_ETC2_EAC}, 20901e04c3fSmrg {VIEW_CLASS_ETC2_EAC_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC}, 21001e04c3fSmrg}; 21101e04c3fSmrg 21201e04c3fSmrgstatic const struct internal_format_class_info gles_astc_compatible_internal_formats[] = { 21301e04c3fSmrg#define ASTC_FMT(size) \ 21401e04c3fSmrg {VIEW_CLASS_ASTC_##size##_RGBA, GL_COMPRESSED_RGBA_ASTC_##size##_KHR}, \ 21501e04c3fSmrg {VIEW_CLASS_ASTC_##size##_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_##size##_KHR} 21601e04c3fSmrg 21701e04c3fSmrg ASTC_FMT(4x4), 21801e04c3fSmrg ASTC_FMT(5x4), 21901e04c3fSmrg ASTC_FMT(5x5), 22001e04c3fSmrg ASTC_FMT(6x5), 22101e04c3fSmrg ASTC_FMT(6x6), 22201e04c3fSmrg ASTC_FMT(8x5), 22301e04c3fSmrg ASTC_FMT(8x6), 22401e04c3fSmrg ASTC_FMT(8x8), 22501e04c3fSmrg ASTC_FMT(10x5), 22601e04c3fSmrg ASTC_FMT(10x6), 22701e04c3fSmrg ASTC_FMT(10x8), 22801e04c3fSmrg ASTC_FMT(10x10), 22901e04c3fSmrg ASTC_FMT(12x10), 23001e04c3fSmrg ASTC_FMT(12x12), 23101e04c3fSmrg#undef ASTC_FMT 23201e04c3fSmrg}; 23301e04c3fSmrg 23401e04c3fSmrgstatic const struct internal_format_class_info gles_astc_3d_compatible_internal_formats[] = { 23501e04c3fSmrg#define ASTC_FMT(size) \ 23601e04c3fSmrg {VIEW_CLASS_ASTC_##size##_RGBA, GL_COMPRESSED_RGBA_ASTC_##size##_OES}, \ 23701e04c3fSmrg {VIEW_CLASS_ASTC_##size##_RGBA, GL_COMPRESSED_SRGB8_ALPHA8_ASTC_##size##_OES} 23801e04c3fSmrg 23901e04c3fSmrg ASTC_FMT(3x3x3), 24001e04c3fSmrg ASTC_FMT(4x3x3), 24101e04c3fSmrg ASTC_FMT(4x4x3), 24201e04c3fSmrg ASTC_FMT(4x4x4), 24301e04c3fSmrg ASTC_FMT(5x4x4), 24401e04c3fSmrg ASTC_FMT(5x5x4), 24501e04c3fSmrg ASTC_FMT(5x5x5), 24601e04c3fSmrg ASTC_FMT(6x5x5), 24701e04c3fSmrg ASTC_FMT(6x6x5), 24801e04c3fSmrg ASTC_FMT(6x6x6), 24901e04c3fSmrg#undef ASTC_FMT 25001e04c3fSmrg}; 25101e04c3fSmrg 25201e04c3fSmrgGLenum 25301e04c3fSmrg_mesa_texture_view_lookup_view_class(const struct gl_context *ctx, GLenum internalformat) 254af69d88dSmrg{ 255af69d88dSmrg GLuint i; 256af69d88dSmrg 257af69d88dSmrg for (i = 0; i < ARRAY_SIZE(compatible_internal_formats); i++) { 258af69d88dSmrg if (compatible_internal_formats[i].internal_format == internalformat) 259af69d88dSmrg return compatible_internal_formats[i].view_class; 260af69d88dSmrg } 261af69d88dSmrg 26201e04c3fSmrg if (ctx->Extensions.EXT_texture_compression_s3tc && 26301e04c3fSmrg ctx->Extensions.EXT_texture_sRGB) { 264af69d88dSmrg for (i = 0; i < ARRAY_SIZE(s3tc_compatible_internal_formats); i++) { 26501e04c3fSmrg if (s3tc_compatible_internal_formats[i].internal_format 26601e04c3fSmrg == internalformat) 267af69d88dSmrg return s3tc_compatible_internal_formats[i].view_class; 268af69d88dSmrg } 269af69d88dSmrg } 27001e04c3fSmrg 27101e04c3fSmrg if (_mesa_is_gles3(ctx)) { 27201e04c3fSmrg for (i = 0; i < ARRAY_SIZE(gles_etc2_compatible_internal_formats); i++) { 27301e04c3fSmrg if (gles_etc2_compatible_internal_formats[i].internal_format 27401e04c3fSmrg == internalformat) 27501e04c3fSmrg return gles_etc2_compatible_internal_formats[i].view_class; 27601e04c3fSmrg } 27701e04c3fSmrg 27801e04c3fSmrg if (ctx->Extensions.KHR_texture_compression_astc_ldr) { 27901e04c3fSmrg for (i = 0; i < ARRAY_SIZE(gles_astc_compatible_internal_formats); i++) { 28001e04c3fSmrg if (gles_astc_compatible_internal_formats[i].internal_format 28101e04c3fSmrg == internalformat) 28201e04c3fSmrg return gles_astc_compatible_internal_formats[i].view_class; 28301e04c3fSmrg } 28401e04c3fSmrg } 28501e04c3fSmrg 28601e04c3fSmrg if (ctx->Extensions.OES_texture_compression_astc) { 28701e04c3fSmrg for (i = 0; i < ARRAY_SIZE(gles_astc_3d_compatible_internal_formats); i++) { 28801e04c3fSmrg if (gles_astc_3d_compatible_internal_formats[i].internal_format 28901e04c3fSmrg == internalformat) 29001e04c3fSmrg return gles_astc_3d_compatible_internal_formats[i].view_class; 29101e04c3fSmrg } 29201e04c3fSmrg } 29301e04c3fSmrg } 294af69d88dSmrg return GL_FALSE; 295af69d88dSmrg} 296af69d88dSmrg 297af69d88dSmrg/** 298af69d88dSmrg * Initialize new texture's gl_texture_image structures. Will not call driver 299af69d88dSmrg * to allocate new space, simply record relevant layer, face, format, etc. 300af69d88dSmrg * \return GL_FALSE if any error, GL_TRUE otherwise. 301af69d88dSmrg */ 302af69d88dSmrgstatic GLboolean 303af69d88dSmrginitialize_texture_fields(struct gl_context *ctx, 304af69d88dSmrg GLenum target, 305af69d88dSmrg struct gl_texture_object *texObj, 306af69d88dSmrg GLint levels, 307af69d88dSmrg GLsizei width, GLsizei height, GLsizei depth, 30801e04c3fSmrg GLenum internalFormat, mesa_format texFormat, 30901e04c3fSmrg GLuint numSamples, GLboolean fixedSampleLocations) 310af69d88dSmrg{ 311af69d88dSmrg const GLuint numFaces = _mesa_num_tex_faces(target); 312af69d88dSmrg GLint level, levelWidth = width, levelHeight = height, levelDepth = depth; 313af69d88dSmrg GLuint face; 314af69d88dSmrg 315af69d88dSmrg /* Pretend we are bound to initialize the gl_texture_image structs */ 316af69d88dSmrg texObj->Target = target; 317af69d88dSmrg 318af69d88dSmrg /* Set up all the texture object's gl_texture_images */ 319af69d88dSmrg for (level = 0; level < levels; level++) { 320af69d88dSmrg for (face = 0; face < numFaces; face++) { 321af69d88dSmrg struct gl_texture_image *texImage; 32201e04c3fSmrg const GLenum faceTarget = _mesa_cube_face_target(target, face); 323af69d88dSmrg 324af69d88dSmrg texImage = _mesa_get_tex_image(ctx, texObj, faceTarget, level); 325af69d88dSmrg 326af69d88dSmrg if (!texImage) { 327af69d88dSmrg _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexStorage"); 328af69d88dSmrg return GL_FALSE; 329af69d88dSmrg } 330af69d88dSmrg 33101e04c3fSmrg _mesa_init_teximage_fields_ms(ctx, texImage, 332af69d88dSmrg levelWidth, levelHeight, levelDepth, 33301e04c3fSmrg 0, internalFormat, texFormat, 33401e04c3fSmrg numSamples, fixedSampleLocations); 335af69d88dSmrg } 336af69d88dSmrg 33701e04c3fSmrg _mesa_next_mipmap_level_size(target, 0, 33801e04c3fSmrg levelWidth, levelHeight, levelDepth, 339af69d88dSmrg &levelWidth, &levelHeight, &levelDepth); 340af69d88dSmrg } 341af69d88dSmrg 342af69d88dSmrg /* "unbind" */ 343af69d88dSmrg texObj->Target = 0; 344af69d88dSmrg 345af69d88dSmrg return GL_TRUE; 346af69d88dSmrg} 347af69d88dSmrg 348af69d88dSmrg#define RETURN_IF_SUPPORTED(t) do { \ 349af69d88dSmrg if (newTarget == GL_ ## t) \ 350af69d88dSmrg return true; \ 351af69d88dSmrg} while (0) 352af69d88dSmrg 353af69d88dSmrg/** 354af69d88dSmrg * Check for compatible target 355af69d88dSmrg * If an error is found, record it with _mesa_error() 356af69d88dSmrg * \return false if any error, true otherwise. 357af69d88dSmrg */ 358af69d88dSmrgstatic bool 359af69d88dSmrgtarget_valid(struct gl_context *ctx, GLenum origTarget, GLenum newTarget) 360af69d88dSmrg{ 361af69d88dSmrg /* 362af69d88dSmrg * From ARB_texture_view spec: 363af69d88dSmrg --------------------------------------------------------------------------------------------------------- 364af69d88dSmrg | Original target | Valid new targets | 365af69d88dSmrg --------------------------------------------------------------------------------------------------------- 366af69d88dSmrg | TEXTURE_1D | TEXTURE_1D, TEXTURE_1D_ARRAY | 367af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 368af69d88dSmrg | TEXTURE_2D | TEXTURE_2D, TEXTURE_2D_ARRAY | 369af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 370af69d88dSmrg | TEXTURE_3D | TEXTURE_3D | 371af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 372af69d88dSmrg | TEXTURE_CUBE_MAP | TEXTURE_CUBE_MAP, TEXTURE_2D, TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY | 373af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 374af69d88dSmrg | TEXTURE_RECTANGLE | TEXTURE_RECTANGLE | 375af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 376af69d88dSmrg | TEXTURE_BUFFER | <none> | 377af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 378af69d88dSmrg | TEXTURE_1D_ARRAY | TEXTURE_1D_ARRAY, TEXTURE_1D | 379af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 380af69d88dSmrg | TEXTURE_2D_ARRAY | TEXTURE_2D_ARRAY, TEXTURE_2D, TEXTURE_CUBE_MAP, TEXTURE_CUBE_MAP_ARRAY | 381af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 382af69d88dSmrg | TEXTURE_CUBE_MAP_ARRAY | TEXTURE_CUBE_MAP_ARRAY, TEXTURE_2D_ARRAY, TEXTURE_2D, TEXTURE_CUBE_MAP | 383af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 384af69d88dSmrg | TEXTURE_2D_MULTISAMPLE | TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY | 385af69d88dSmrg | ------------------------------------------------------------------------------------------------------- | 386af69d88dSmrg | TEXTURE_2D_MULTISAMPLE_ARRAY | TEXTURE_2D_MULTISAMPLE, TEXTURE_2D_MULTISAMPLE_ARRAY | 387af69d88dSmrg --------------------------------------------------------------------------------------------------------- 388af69d88dSmrg */ 389af69d88dSmrg 390af69d88dSmrg switch (origTarget) { 391af69d88dSmrg case GL_TEXTURE_1D: 392af69d88dSmrg case GL_TEXTURE_1D_ARRAY: 393af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_1D); 394af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_1D_ARRAY); 395af69d88dSmrg break; 396af69d88dSmrg case GL_TEXTURE_2D: 397af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_2D); 398af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_2D_ARRAY); 399af69d88dSmrg break; 400af69d88dSmrg case GL_TEXTURE_3D: 401af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_3D); 402af69d88dSmrg break; 403af69d88dSmrg case GL_TEXTURE_RECTANGLE: 404af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_RECTANGLE); 405af69d88dSmrg break; 406af69d88dSmrg case GL_TEXTURE_CUBE_MAP: 407af69d88dSmrg case GL_TEXTURE_2D_ARRAY: 408af69d88dSmrg case GL_TEXTURE_CUBE_MAP_ARRAY: 409af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_2D); 410af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_2D_ARRAY); 411af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_CUBE_MAP); 412af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_CUBE_MAP_ARRAY); 413af69d88dSmrg break; 414af69d88dSmrg case GL_TEXTURE_2D_MULTISAMPLE: 415af69d88dSmrg case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 416af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_2D_MULTISAMPLE); 417af69d88dSmrg RETURN_IF_SUPPORTED(TEXTURE_2D_MULTISAMPLE_ARRAY); 418af69d88dSmrg break; 419af69d88dSmrg } 420af69d88dSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 421af69d88dSmrg "glTextureView(illegal target=%s)", 42201e04c3fSmrg _mesa_enum_to_string(newTarget)); 423af69d88dSmrg return false; 424af69d88dSmrg} 425af69d88dSmrg#undef RETURN_IF_SUPPORTED 426af69d88dSmrg 427af69d88dSmrg/** 428af69d88dSmrg * Check for compatible format 429af69d88dSmrg * If an error is found, record it with _mesa_error() 430af69d88dSmrg * \return false if any error, true otherwise. 431af69d88dSmrg */ 43201e04c3fSmrgbool 43301e04c3fSmrg_mesa_texture_view_compatible_format(const struct gl_context *ctx, 434af69d88dSmrg GLenum origInternalFormat, 435af69d88dSmrg GLenum newInternalFormat) 436af69d88dSmrg{ 437af69d88dSmrg unsigned int origViewClass, newViewClass; 438af69d88dSmrg 439af69d88dSmrg /* The two textures' internal formats must be compatible according to 440af69d88dSmrg * Table 3.X.2 (Compatible internal formats for TextureView) 441af69d88dSmrg * if the internal format exists in that table the view class must match. 442af69d88dSmrg * The internal formats must be identical if not in that table, 443af69d88dSmrg * or an INVALID_OPERATION error is generated. 444af69d88dSmrg */ 445af69d88dSmrg if (origInternalFormat == newInternalFormat) 44601e04c3fSmrg return true; 447af69d88dSmrg 44801e04c3fSmrg origViewClass = _mesa_texture_view_lookup_view_class(ctx, origInternalFormat); 44901e04c3fSmrg newViewClass = _mesa_texture_view_lookup_view_class(ctx, newInternalFormat); 450af69d88dSmrg if ((origViewClass == newViewClass) && origViewClass != false) 45101e04c3fSmrg return true; 452af69d88dSmrg 45301e04c3fSmrg return false; 454af69d88dSmrg} 45501e04c3fSmrg 456af69d88dSmrg/** 457af69d88dSmrg * Helper function for TexStorage and teximagemultisample to set immutable 458af69d88dSmrg * texture state needed by ARB_texture_view. 459af69d88dSmrg */ 460af69d88dSmrgvoid 461af69d88dSmrg_mesa_set_texture_view_state(struct gl_context *ctx, 462af69d88dSmrg struct gl_texture_object *texObj, 463af69d88dSmrg GLenum target, GLuint levels) 464af69d88dSmrg{ 465af69d88dSmrg struct gl_texture_image *texImage; 466af69d88dSmrg 467af69d88dSmrg /* Get a reference to what will become this View's base level */ 46801e04c3fSmrg texImage = _mesa_select_tex_image(texObj, target, 0); 469af69d88dSmrg 47001e04c3fSmrg /* When an immutable texture is created via glTexStorage or 47101e04c3fSmrg * glTexImageMultisample, 472af69d88dSmrg * TEXTURE_IMMUTABLE_FORMAT becomes TRUE. 473af69d88dSmrg * TEXTURE_IMMUTABLE_LEVELS and TEXTURE_VIEW_NUM_LEVELS become levels. 474af69d88dSmrg * If the texture target is TEXTURE_1D_ARRAY then 475af69d88dSmrg * TEXTURE_VIEW_NUM_LAYERS becomes height. 476af69d88dSmrg * If the texture target is TEXTURE_2D_ARRAY, TEXTURE_CUBE_MAP_ARRAY, 47701e04c3fSmrg * or TEXTURE_2D_MULTISAMPLE_ARRAY then TEXTURE_VIEW_NUM_LAYERS becomes 47801e04c3fSmrg * depth. 479af69d88dSmrg * If the texture target is TEXTURE_CUBE_MAP, then 480af69d88dSmrg * TEXTURE_VIEW_NUM_LAYERS becomes 6. 481af69d88dSmrg * For any other texture target, TEXTURE_VIEW_NUM_LAYERS becomes 1. 48201e04c3fSmrg * 483af69d88dSmrg * ARB_texture_multisample: Multisample textures do 484af69d88dSmrg * not have multiple image levels. 485af69d88dSmrg */ 486af69d88dSmrg 487af69d88dSmrg texObj->Immutable = GL_TRUE; 488af69d88dSmrg texObj->ImmutableLevels = levels; 489af69d88dSmrg texObj->MinLevel = 0; 490af69d88dSmrg texObj->NumLevels = levels; 491af69d88dSmrg texObj->MinLayer = 0; 492af69d88dSmrg texObj->NumLayers = 1; 493af69d88dSmrg switch (target) { 494af69d88dSmrg case GL_TEXTURE_1D_ARRAY: 495af69d88dSmrg texObj->NumLayers = texImage->Height; 496af69d88dSmrg break; 497af69d88dSmrg 498af69d88dSmrg case GL_TEXTURE_2D_MULTISAMPLE: 499af69d88dSmrg texObj->NumLevels = 1; 500af69d88dSmrg texObj->ImmutableLevels = 1; 501af69d88dSmrg break; 502af69d88dSmrg 503af69d88dSmrg case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 504af69d88dSmrg texObj->NumLevels = 1; 505af69d88dSmrg texObj->ImmutableLevels = 1; 506af69d88dSmrg /* fall through to set NumLayers */ 507af69d88dSmrg 508af69d88dSmrg case GL_TEXTURE_2D_ARRAY: 509af69d88dSmrg case GL_TEXTURE_CUBE_MAP_ARRAY: 510af69d88dSmrg texObj->NumLayers = texImage->Depth; 511af69d88dSmrg break; 512af69d88dSmrg 513af69d88dSmrg case GL_TEXTURE_CUBE_MAP: 514af69d88dSmrg texObj->NumLayers = 6; 515af69d88dSmrg break; 516af69d88dSmrg } 517af69d88dSmrg} 518af69d88dSmrg 519af69d88dSmrg/** 520af69d88dSmrg * glTextureView (ARB_texture_view) 521af69d88dSmrg * If an error is found, record it with _mesa_error() 522af69d88dSmrg * \return none. 523af69d88dSmrg */ 52401e04c3fSmrgstatic ALWAYS_INLINE void 52501e04c3fSmrgtexture_view(struct gl_context *ctx, struct gl_texture_object *origTexObj, 52601e04c3fSmrg struct gl_texture_object *texObj, GLenum target, 52701e04c3fSmrg GLenum internalformat, GLuint minlevel, GLuint numlevels, 52801e04c3fSmrg GLuint minlayer, GLuint numlayers, bool no_error) 529af69d88dSmrg{ 530af69d88dSmrg struct gl_texture_image *origTexImage; 531af69d88dSmrg GLuint newViewNumLevels, newViewNumLayers; 532af69d88dSmrg GLsizei width, height, depth; 533af69d88dSmrg mesa_format texFormat; 534af69d88dSmrg GLboolean sizeOK, dimensionsOK; 535af69d88dSmrg GLenum faceTarget; 536af69d88dSmrg 537af69d88dSmrg texFormat = _mesa_choose_texture_format(ctx, texObj, target, 0, 538af69d88dSmrg internalformat, GL_NONE, GL_NONE); 539af69d88dSmrg if (texFormat == MESA_FORMAT_NONE) return; 540af69d88dSmrg 541af69d88dSmrg newViewNumLevels = MIN2(numlevels, origTexObj->NumLevels - minlevel); 542af69d88dSmrg newViewNumLayers = MIN2(numlayers, origTexObj->NumLayers - minlayer); 543af69d88dSmrg 54401e04c3fSmrg faceTarget = _mesa_cube_face_target(origTexObj->Target, minlayer); 545af69d88dSmrg 546af69d88dSmrg /* Get a reference to what will become this View's base level */ 54701e04c3fSmrg origTexImage = _mesa_select_tex_image(origTexObj, faceTarget, minlevel); 548af69d88dSmrg width = origTexImage->Width; 549af69d88dSmrg height = origTexImage->Height; 550af69d88dSmrg depth = origTexImage->Depth; 551af69d88dSmrg 552af69d88dSmrg /* Adjust width, height, depth to be appropriate for new target */ 553af69d88dSmrg switch (target) { 554af69d88dSmrg case GL_TEXTURE_1D: 55501e04c3fSmrg height = 1; 55601e04c3fSmrg break; 55701e04c3fSmrg 558af69d88dSmrg case GL_TEXTURE_3D: 559af69d88dSmrg break; 560af69d88dSmrg 561af69d88dSmrg case GL_TEXTURE_1D_ARRAY: 562af69d88dSmrg height = (GLsizei) newViewNumLayers; 563af69d88dSmrg break; 564af69d88dSmrg 565af69d88dSmrg case GL_TEXTURE_2D: 566af69d88dSmrg case GL_TEXTURE_2D_MULTISAMPLE: 567af69d88dSmrg case GL_TEXTURE_RECTANGLE: 568af69d88dSmrg depth = 1; 569af69d88dSmrg break; 570af69d88dSmrg case GL_TEXTURE_CUBE_MAP: 57101e04c3fSmrg /* If the new texture's target is TEXTURE_CUBE_MAP, the clamped 57201e04c3fSmrg * <numlayers> must be equal to 6. 573af69d88dSmrg */ 57401e04c3fSmrg if (!no_error && newViewNumLayers != 6) { 57501e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, 57601e04c3fSmrg "glTextureView(clamped numlayers %d != 6)", 577af69d88dSmrg newViewNumLayers); 578af69d88dSmrg return; 579af69d88dSmrg } 58001e04c3fSmrg depth = 1; 581af69d88dSmrg break; 582af69d88dSmrg 58301e04c3fSmrg case GL_TEXTURE_2D_ARRAY: 58401e04c3fSmrg case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: 58501e04c3fSmrg depth = newViewNumLayers; 58601e04c3fSmrg break; 587af69d88dSmrg case GL_TEXTURE_CUBE_MAP_ARRAY: 588af69d88dSmrg /* If the new texture's target is TEXTURE_CUBE_MAP_ARRAY, 589af69d88dSmrg * then <numlayers> counts layer-faces rather than layers, 590af69d88dSmrg * and the clamped <numlayers> must be a multiple of 6. 591af69d88dSmrg * Otherwise, the error INVALID_VALUE is generated. 592af69d88dSmrg */ 59301e04c3fSmrg if (!no_error && (newViewNumLayers % 6) != 0) { 594af69d88dSmrg _mesa_error(ctx, GL_INVALID_VALUE, 59501e04c3fSmrg "glTextureView(clamped numlayers %d is not" 59601e04c3fSmrg " a multiple of 6)", 597af69d88dSmrg newViewNumLayers); 598af69d88dSmrg return; 599af69d88dSmrg } 60001e04c3fSmrg depth = newViewNumLayers; 601af69d88dSmrg break; 602af69d88dSmrg } 603af69d88dSmrg 60401e04c3fSmrg if (!no_error) { 60501e04c3fSmrg /* If the dimensions of the original texture are larger than the maximum 60601e04c3fSmrg * supported dimensions of the new target, the error INVALID_OPERATION is 60701e04c3fSmrg * generated. For example, if the original texture has a TEXTURE_2D_ARRAY 60801e04c3fSmrg * target and its width is greater than MAX_CUBE_MAP_TEXTURE_SIZE, an 60901e04c3fSmrg * error will be generated if TextureView is called to create a 61001e04c3fSmrg * TEXTURE_CUBE_MAP view. 61101e04c3fSmrg */ 61201e04c3fSmrg dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0, 61301e04c3fSmrg width, height, depth, 0); 61401e04c3fSmrg if (!dimensionsOK) { 61501e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 61601e04c3fSmrg "glTextureView(invalid width or height or depth)"); 61701e04c3fSmrg return; 61801e04c3fSmrg } 61901e04c3fSmrg 62001e04c3fSmrg sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 1, 0, texFormat, 62101e04c3fSmrg origTexImage->NumSamples, 62201e04c3fSmrg width, height, depth); 62301e04c3fSmrg if (!sizeOK) { 62401e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 62501e04c3fSmrg "glTextureView(invalid texture size)"); 62601e04c3fSmrg return; 62701e04c3fSmrg } 62801e04c3fSmrg 62901e04c3fSmrg /* If <target> is TEXTURE_1D, TEXTURE_2D, TEXTURE_3D, TEXTURE_RECTANGLE, 63001e04c3fSmrg * or TEXTURE_2D_MULTISAMPLE and <numlayers> does not equal 1, the error 63101e04c3fSmrg * INVALID_VALUE is generated. 63201e04c3fSmrg */ 63301e04c3fSmrg switch (target) { 63401e04c3fSmrg case GL_TEXTURE_1D: 63501e04c3fSmrg case GL_TEXTURE_2D: 63601e04c3fSmrg case GL_TEXTURE_3D: 63701e04c3fSmrg case GL_TEXTURE_RECTANGLE: 63801e04c3fSmrg case GL_TEXTURE_2D_MULTISAMPLE: 63901e04c3fSmrg if (numlayers != 1) { 64001e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(numlayers %d != 1)", 64101e04c3fSmrg numlayers); 64201e04c3fSmrg return; 64301e04c3fSmrg } 64401e04c3fSmrg break; 64501e04c3fSmrg case GL_TEXTURE_CUBE_MAP: 64601e04c3fSmrg break; 64701e04c3fSmrg case GL_TEXTURE_CUBE_MAP_ARRAY: 64801e04c3fSmrg break; 64901e04c3fSmrg } 65001e04c3fSmrg 65101e04c3fSmrg /* If the new texture's target is TEXTURE_CUBE_MAP or 65201e04c3fSmrg * TEXTURE_CUBE_MAP_ARRAY, the width and height of the original texture's 65301e04c3fSmrg * levels must be equal otherwise the error INVALID_OPERATION is 65401e04c3fSmrg * generated. 65501e04c3fSmrg */ 65601e04c3fSmrg if ((target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) 65701e04c3fSmrg && (origTexImage->Width != origTexImage->Height)) { 65801e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 65901e04c3fSmrg "glTextureView(origtexture width (%d) != height (%d))", 66001e04c3fSmrg origTexImage->Width, origTexImage->Height); 66101e04c3fSmrg return; 66201e04c3fSmrg } 663af69d88dSmrg } 664af69d88dSmrg 665af69d88dSmrg /* When the original texture's target is TEXTURE_CUBE_MAP, the layer 666af69d88dSmrg * parameters are interpreted in the same order as if it were a 667af69d88dSmrg * TEXTURE_CUBE_MAP_ARRAY with 6 layer-faces. 668af69d88dSmrg */ 669af69d88dSmrg 670af69d88dSmrg /* If the internal format does not exactly match the internal format of the 671af69d88dSmrg * original texture, the contents of the memory are reinterpreted in the 672af69d88dSmrg * same manner as for image bindings described in 673af69d88dSmrg * section 3.9.20 (Texture Image Loads and Stores). 674af69d88dSmrg */ 675af69d88dSmrg 676af69d88dSmrg /* TEXTURE_BASE_LEVEL and TEXTURE_MAX_LEVEL are interpreted 677af69d88dSmrg * relative to the view and not relative to the original data store. 678af69d88dSmrg */ 679af69d88dSmrg 680af69d88dSmrg if (!initialize_texture_fields(ctx, target, texObj, newViewNumLevels, 681af69d88dSmrg width, height, depth, 68201e04c3fSmrg internalformat, texFormat, 68301e04c3fSmrg origTexImage->NumSamples, 68401e04c3fSmrg origTexImage->FixedSampleLocations)) { 685af69d88dSmrg return; /* Already recorded error */ 686af69d88dSmrg } 687af69d88dSmrg 68801e04c3fSmrg texObj->MinLevel = origTexObj->MinLevel + minlevel; 68901e04c3fSmrg texObj->MinLayer = origTexObj->MinLayer + minlayer; 690af69d88dSmrg texObj->NumLevels = newViewNumLevels; 691af69d88dSmrg texObj->NumLayers = newViewNumLayers; 692af69d88dSmrg texObj->Immutable = GL_TRUE; 693af69d88dSmrg texObj->ImmutableLevels = origTexObj->ImmutableLevels; 694af69d88dSmrg texObj->Target = target; 69501e04c3fSmrg texObj->TargetIndex = _mesa_tex_target_to_index(ctx, target); 69601e04c3fSmrg assert(texObj->TargetIndex < NUM_TEXTURE_TARGETS); 697af69d88dSmrg 69801e04c3fSmrg if (ctx->Driver.TextureView != NULL && 69901e04c3fSmrg !ctx->Driver.TextureView(ctx, texObj, origTexObj)) { 700af69d88dSmrg return; /* driver recorded error */ 701af69d88dSmrg } 702af69d88dSmrg} 70301e04c3fSmrg 70401e04c3fSmrgvoid GLAPIENTRY 70501e04c3fSmrg_mesa_TextureView_no_error(GLuint texture, GLenum target, GLuint origtexture, 70601e04c3fSmrg GLenum internalformat, 70701e04c3fSmrg GLuint minlevel, GLuint numlevels, 70801e04c3fSmrg GLuint minlayer, GLuint numlayers) 70901e04c3fSmrg{ 71001e04c3fSmrg struct gl_texture_object *texObj; 71101e04c3fSmrg struct gl_texture_object *origTexObj; 71201e04c3fSmrg 71301e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 71401e04c3fSmrg 71501e04c3fSmrg origTexObj = _mesa_lookup_texture(ctx, origtexture); 71601e04c3fSmrg texObj = _mesa_lookup_texture(ctx, texture); 71701e04c3fSmrg 71801e04c3fSmrg texture_view(ctx, origTexObj, texObj, target, internalformat, minlevel, 71901e04c3fSmrg numlevels, minlayer, numlayers, true); 72001e04c3fSmrg} 72101e04c3fSmrg 72201e04c3fSmrgvoid GLAPIENTRY 72301e04c3fSmrg_mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture, 72401e04c3fSmrg GLenum internalformat, 72501e04c3fSmrg GLuint minlevel, GLuint numlevels, 72601e04c3fSmrg GLuint minlayer, GLuint numlayers) 72701e04c3fSmrg{ 72801e04c3fSmrg struct gl_texture_object *texObj; 72901e04c3fSmrg struct gl_texture_object *origTexObj; 73001e04c3fSmrg GLuint newViewMinLevel, newViewMinLayer; 73101e04c3fSmrg 73201e04c3fSmrg GET_CURRENT_CONTEXT(ctx); 73301e04c3fSmrg 73401e04c3fSmrg if (MESA_VERBOSE & (VERBOSE_API | VERBOSE_TEXTURE)) 73501e04c3fSmrg _mesa_debug(ctx, "glTextureView %d %s %d %s %d %d %d %d\n", 73601e04c3fSmrg texture, _mesa_enum_to_string(target), origtexture, 73701e04c3fSmrg _mesa_enum_to_string(internalformat), 73801e04c3fSmrg minlevel, numlevels, minlayer, numlayers); 73901e04c3fSmrg 74001e04c3fSmrg if (origtexture == 0) { 74101e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)", 74201e04c3fSmrg origtexture); 74301e04c3fSmrg return; 74401e04c3fSmrg } 74501e04c3fSmrg 74601e04c3fSmrg /* Need original texture information to validate arguments */ 74701e04c3fSmrg origTexObj = _mesa_lookup_texture(ctx, origtexture); 74801e04c3fSmrg 74901e04c3fSmrg /* If <origtexture> is not the name of a texture, INVALID_VALUE 75001e04c3fSmrg * is generated. 75101e04c3fSmrg */ 75201e04c3fSmrg if (!origTexObj) { 75301e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(origtexture = %u)", 75401e04c3fSmrg origtexture); 75501e04c3fSmrg return; 75601e04c3fSmrg } 75701e04c3fSmrg 75801e04c3fSmrg /* If <origtexture>'s TEXTURE_IMMUTABLE_FORMAT value is not TRUE, 75901e04c3fSmrg * INVALID_OPERATION is generated. 76001e04c3fSmrg */ 76101e04c3fSmrg if (!origTexObj->Immutable) { 76201e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 76301e04c3fSmrg "glTextureView(origtexture not immutable)"); 76401e04c3fSmrg return; 76501e04c3fSmrg } 76601e04c3fSmrg 76701e04c3fSmrg /* If <texture> is 0, INVALID_VALUE is generated. */ 76801e04c3fSmrg if (texture == 0) { 76901e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, "glTextureView(texture = 0)"); 77001e04c3fSmrg return; 77101e04c3fSmrg } 77201e04c3fSmrg 77301e04c3fSmrg /* If <texture> is not a valid name returned by GenTextures, 77401e04c3fSmrg * the error INVALID_OPERATION is generated. 77501e04c3fSmrg */ 77601e04c3fSmrg texObj = _mesa_lookup_texture(ctx, texture); 77701e04c3fSmrg if (texObj == NULL) { 77801e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 77901e04c3fSmrg "glTextureView(texture = %u non-gen name)", texture); 78001e04c3fSmrg return; 78101e04c3fSmrg } 78201e04c3fSmrg 78301e04c3fSmrg /* If <texture> has already been bound and given a target, then 78401e04c3fSmrg * the error INVALID_OPERATION is generated. 78501e04c3fSmrg */ 78601e04c3fSmrg if (texObj->Target) { 78701e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 78801e04c3fSmrg "glTextureView(texture = %u already bound)", texture); 78901e04c3fSmrg return; 79001e04c3fSmrg } 79101e04c3fSmrg 79201e04c3fSmrg /* Check for compatible target */ 79301e04c3fSmrg if (!target_valid(ctx, origTexObj->Target, target)) { 79401e04c3fSmrg return; /* error was recorded */ 79501e04c3fSmrg } 79601e04c3fSmrg 79701e04c3fSmrg /* minlevel and minlayer are relative to the view of origtexture. 79801e04c3fSmrg * If minlevel or minlayer is greater than level or layer, respectively, 79901e04c3fSmrg * return INVALID_VALUE. 80001e04c3fSmrg */ 80101e04c3fSmrg newViewMinLevel = origTexObj->MinLevel + minlevel; 80201e04c3fSmrg newViewMinLayer = origTexObj->MinLayer + minlayer; 80301e04c3fSmrg if (newViewMinLevel >= (origTexObj->MinLevel + origTexObj->NumLevels)) { 80401e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, 80501e04c3fSmrg "glTextureView(new minlevel (%d) > orig minlevel (%d)" 80601e04c3fSmrg " + orig numlevels (%d))", 80701e04c3fSmrg newViewMinLevel, origTexObj->MinLevel, origTexObj->NumLevels); 80801e04c3fSmrg return; 80901e04c3fSmrg } 81001e04c3fSmrg 81101e04c3fSmrg if (newViewMinLayer >= (origTexObj->MinLayer + origTexObj->NumLayers)) { 81201e04c3fSmrg _mesa_error(ctx, GL_INVALID_VALUE, 81301e04c3fSmrg "glTextureView(new minlayer (%d) > orig minlayer (%d)" 81401e04c3fSmrg " + orig numlayers (%d))", 81501e04c3fSmrg newViewMinLayer, origTexObj->MinLayer, origTexObj->NumLayers); 81601e04c3fSmrg return; 81701e04c3fSmrg } 81801e04c3fSmrg 81901e04c3fSmrg if (!_mesa_texture_view_compatible_format(ctx, 82001e04c3fSmrg origTexObj->Image[0][0]->InternalFormat, 82101e04c3fSmrg internalformat)) { 82201e04c3fSmrg _mesa_error(ctx, GL_INVALID_OPERATION, 82301e04c3fSmrg "glTextureView(internalformat %s not compatible with origtexture %s)", 82401e04c3fSmrg _mesa_enum_to_string(internalformat), 82501e04c3fSmrg _mesa_enum_to_string(origTexObj->Image[0][0]->InternalFormat)); 82601e04c3fSmrg return; 82701e04c3fSmrg } 82801e04c3fSmrg 82901e04c3fSmrg texture_view(ctx, origTexObj, texObj, target, internalformat, minlevel, 83001e04c3fSmrg numlevels, minlayer, numlayers, false); 83101e04c3fSmrg} 832