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