xref: /aosp_15_r20/external/mesa3d/src/mesa/state_tracker/st_cb_texture.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /**************************************************************************
2  *
3  * Copyright 2007 VMware, Inc.
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27 
28 #include <stdio.h>
29 #include "main/bufferobj.h"
30 #include "main/context.h"
31 #include "main/enums.h"
32 #include "main/errors.h"
33 #include "main/fbobject.h"
34 #include "main/formats.h"
35 #include "main/format_utils.h"
36 #include "main/framebuffer.h"
37 #include "main/glformats.h"
38 #include "main/image.h"
39 #include "main/formatquery.h"
40 
41 #include "main/macros.h"
42 #include "main/mipmap.h"
43 #include "main/pack.h"
44 #include "main/pbo.h"
45 #include "main/pixeltransfer.h"
46 #include "main/texcompress.h"
47 #include "main/texcompress_astc.h"
48 #include "main/texcompress_bptc.h"
49 #include "main/texcompress_etc.h"
50 #include "main/texcompress_rgtc.h"
51 #include "main/texcompress_s3tc.h"
52 #include "main/texgetimage.h"
53 #include "main/teximage.h"
54 #include "main/texobj.h"
55 #include "main/texstore.h"
56 
57 #include "state_tracker/st_debug.h"
58 #include "state_tracker/st_context.h"
59 #include "state_tracker/st_cb_bitmap.h"
60 #include "state_tracker/st_cb_drawpixels.h"
61 #include "state_tracker/st_cb_flush.h"
62 #include "state_tracker/st_cb_texture.h"
63 #include "state_tracker/st_format.h"
64 #include "state_tracker/st_pbo.h"
65 #include "state_tracker/st_texture.h"
66 #include "state_tracker/st_gen_mipmap.h"
67 #include "state_tracker/st_atom.h"
68 #include "state_tracker/st_sampler_view.h"
69 #include "state_tracker/st_texcompress_compute.h"
70 #include "state_tracker/st_util.h"
71 
72 #include "pipe/p_context.h"
73 #include "pipe/p_defines.h"
74 #include "util/log.h"
75 #include "util/u_inlines.h"
76 #include "util/u_upload_mgr.h"
77 #include "pipe/p_shader_tokens.h"
78 #include "util/u_tile.h"
79 #include "util/format/u_format.h"
80 #include "util/u_surface.h"
81 #include "util/u_sampler.h"
82 #include "util/u_math.h"
83 #include "util/box.h"
84 #include "util/u_memory.h"
85 #include "cso_cache/cso_context.h"
86 
87 #define DBG if (0) printf
88 
89 
90 enum pipe_texture_target
gl_target_to_pipe(GLenum target)91 gl_target_to_pipe(GLenum target)
92 {
93    switch (target) {
94    case GL_TEXTURE_1D:
95    case GL_PROXY_TEXTURE_1D:
96       return PIPE_TEXTURE_1D;
97    case GL_TEXTURE_2D:
98    case GL_PROXY_TEXTURE_2D:
99    case GL_TEXTURE_EXTERNAL_OES:
100    case GL_TEXTURE_2D_MULTISAMPLE:
101    case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
102       return PIPE_TEXTURE_2D;
103    case GL_TEXTURE_RECTANGLE_NV:
104    case GL_PROXY_TEXTURE_RECTANGLE_NV:
105       return PIPE_TEXTURE_RECT;
106    case GL_TEXTURE_3D:
107    case GL_PROXY_TEXTURE_3D:
108       return PIPE_TEXTURE_3D;
109    case GL_TEXTURE_CUBE_MAP_ARB:
110    case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
111    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
112    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
113    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
114    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
115    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
116    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
117       return PIPE_TEXTURE_CUBE;
118    case GL_TEXTURE_1D_ARRAY_EXT:
119    case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
120       return PIPE_TEXTURE_1D_ARRAY;
121    case GL_TEXTURE_2D_ARRAY_EXT:
122    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
123    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
124    case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
125       return PIPE_TEXTURE_2D_ARRAY;
126    case GL_TEXTURE_BUFFER:
127       return PIPE_BUFFER;
128    case GL_TEXTURE_CUBE_MAP_ARRAY:
129    case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
130       return PIPE_TEXTURE_CUBE_ARRAY;
131    default:
132       assert(0);
133       return 0;
134    }
135 }
136 
137 GLint
st_from_pipe_compression_rate(uint32_t rate)138 st_from_pipe_compression_rate(uint32_t rate)
139 {
140    switch (rate) {
141    case PIPE_COMPRESSION_FIXED_RATE_NONE:
142       return GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT;
143    case PIPE_COMPRESSION_FIXED_RATE_DEFAULT:
144       return GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT;
145    case 1: return GL_SURFACE_COMPRESSION_FIXED_RATE_1BPC_EXT;
146    case 2: return GL_SURFACE_COMPRESSION_FIXED_RATE_2BPC_EXT;
147    case 3: return GL_SURFACE_COMPRESSION_FIXED_RATE_3BPC_EXT;
148    case 4: return GL_SURFACE_COMPRESSION_FIXED_RATE_4BPC_EXT;
149    case 5: return GL_SURFACE_COMPRESSION_FIXED_RATE_5BPC_EXT;
150    case 6: return GL_SURFACE_COMPRESSION_FIXED_RATE_6BPC_EXT;
151    case 7: return GL_SURFACE_COMPRESSION_FIXED_RATE_7BPC_EXT;
152    case 8: return GL_SURFACE_COMPRESSION_FIXED_RATE_8BPC_EXT;
153    case 9: return GL_SURFACE_COMPRESSION_FIXED_RATE_9BPC_EXT;
154    case 10: return GL_SURFACE_COMPRESSION_FIXED_RATE_10BPC_EXT;
155    case 11: return GL_SURFACE_COMPRESSION_FIXED_RATE_11BPC_EXT;
156    case 12: return GL_SURFACE_COMPRESSION_FIXED_RATE_12BPC_EXT;
157    default:
158       unreachable("Unexpected value in st_from_pipe_compression_rate");
159    }
160 }
161 
162 static uint32_t
st_gl_compression_rate_to_pipe(GLint rate)163 st_gl_compression_rate_to_pipe(GLint rate)
164 {
165    switch (rate) {
166    case GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT:
167       return PIPE_COMPRESSION_FIXED_RATE_NONE;
168    case GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT:
169       return PIPE_COMPRESSION_FIXED_RATE_DEFAULT;
170    case GL_SURFACE_COMPRESSION_FIXED_RATE_1BPC_EXT: return 1;
171    case GL_SURFACE_COMPRESSION_FIXED_RATE_2BPC_EXT: return 2;
172    case GL_SURFACE_COMPRESSION_FIXED_RATE_3BPC_EXT: return 3;
173    case GL_SURFACE_COMPRESSION_FIXED_RATE_4BPC_EXT: return 4;
174    case GL_SURFACE_COMPRESSION_FIXED_RATE_5BPC_EXT: return 5;
175    case GL_SURFACE_COMPRESSION_FIXED_RATE_6BPC_EXT: return 6;
176    case GL_SURFACE_COMPRESSION_FIXED_RATE_7BPC_EXT: return 7;
177    case GL_SURFACE_COMPRESSION_FIXED_RATE_8BPC_EXT: return 8;
178    case GL_SURFACE_COMPRESSION_FIXED_RATE_9BPC_EXT: return 9;
179    case GL_SURFACE_COMPRESSION_FIXED_RATE_10BPC_EXT: return 10;
180    case GL_SURFACE_COMPRESSION_FIXED_RATE_11BPC_EXT: return 11;
181    case GL_SURFACE_COMPRESSION_FIXED_RATE_12BPC_EXT: return 12;
182    default:
183       unreachable("Unexpected value in st_gl_compression_rate_to_pipe()");
184    }
185 }
186 
187 enum pipe_format
st_pbo_get_src_format(struct pipe_screen * screen,enum pipe_format src_format,struct pipe_resource * src)188 st_pbo_get_src_format(struct pipe_screen *screen, enum pipe_format src_format, struct pipe_resource *src)
189 {
190    /* Convert the source format to what is expected by GetTexImage
191     * and see if it's supported.
192     *
193     * This only applies to glGetTexImage:
194     * - Luminance must be returned as (L,0,0,1).
195     * - Luminance alpha must be returned as (L,0,0,A).
196     * - Intensity must be returned as (I,0,0,1)
197     */
198    src_format = util_format_linear(src_format);
199    src_format = util_format_luminance_to_red(src_format);
200    src_format = util_format_intensity_to_red(src_format);
201 
202    if (!src_format ||
203        !screen->is_format_supported(screen, src_format, src->target,
204                                     src->nr_samples, src->nr_storage_samples,
205                                     PIPE_BIND_SAMPLER_VIEW)) {
206       return PIPE_FORMAT_NONE;
207    }
208    return src_format;
209 }
210 
211 static struct pipe_resource *
create_dst_texture(struct gl_context * ctx,enum pipe_format dst_format,enum pipe_texture_target pipe_target,GLsizei width,GLsizei height,GLint depth,GLenum gl_target,unsigned bind)212 create_dst_texture(struct gl_context *ctx,
213                    enum pipe_format dst_format, enum pipe_texture_target pipe_target,
214                    GLsizei width, GLsizei height, GLint depth,
215                    GLenum gl_target, unsigned bind)
216 {
217    struct st_context *st = st_context(ctx);
218    struct pipe_screen *screen = st->screen;
219    struct pipe_resource dst_templ;
220 
221    if (pipe_target == PIPE_TEXTURE_CUBE || pipe_target == PIPE_TEXTURE_CUBE_ARRAY) {
222       width = MAX2(width, height);
223       height = MAX2(width, height);
224    }
225 
226    /* create the destination texture of size (width X height X depth) */
227    memset(&dst_templ, 0, sizeof(dst_templ));
228    dst_templ.target = pipe_target;
229    dst_templ.format = dst_format;
230    dst_templ.bind = bind;
231    dst_templ.usage = PIPE_USAGE_STAGING;
232 
233    st_gl_texture_dims_to_pipe_dims(gl_target, width, height, depth,
234                                    &dst_templ.width0, &dst_templ.height0,
235                                    &dst_templ.depth0, &dst_templ.array_size);
236 
237    return screen->resource_create(screen, &dst_templ);
238 }
239 
240 static bool
copy_to_staging_dest(struct gl_context * ctx,struct pipe_resource * dst,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLint depth,GLenum format,GLenum type,void * pixels,struct gl_texture_image * texImage)241 copy_to_staging_dest(struct gl_context * ctx, struct pipe_resource *dst,
242                  GLint xoffset, GLint yoffset, GLint zoffset,
243                  GLsizei width, GLsizei height, GLint depth,
244                  GLenum format, GLenum type, void * pixels,
245                  struct gl_texture_image *texImage)
246 {
247    struct st_context *st = st_context(ctx);
248    struct pipe_context *pipe = st->pipe;
249    struct gl_texture_object *stObj = texImage->TexObject;
250    ASSERTED struct pipe_resource *src = stObj->pt;
251    enum pipe_format dst_format = dst->format;
252    mesa_format mesa_format;
253    GLenum gl_target = texImage->TexObject->Target;
254    unsigned dims;
255    struct pipe_transfer *tex_xfer;
256    uint8_t *map = NULL;
257    bool done = false;
258 
259    pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels);
260 
261    map = pipe_texture_map_3d(pipe, dst, 0, PIPE_MAP_READ,
262                               0, 0, 0, width, height, depth, &tex_xfer);
263    if (!map) {
264       goto end;
265    }
266 
267    mesa_format = st_pipe_format_to_mesa_format(dst_format);
268    dims = _mesa_get_texture_dimensions(gl_target);
269 
270    /* copy/pack data into user buffer */
271    if (_mesa_format_matches_format_and_type(mesa_format, format, type,
272                                             ctx->Pack.SwapBytes, NULL)) {
273       /* memcpy */
274       const uint bytesPerRow = width * util_format_get_blocksize(dst_format);
275       GLuint row, slice;
276 
277       for (slice = 0; slice < depth; slice++) {
278          uint8_t *slice_map = map;
279 
280          for (row = 0; row < height; row++) {
281             void *dest = _mesa_image_address(dims, &ctx->Pack, pixels,
282                                              width, height, format, type,
283                                              slice, row, 0);
284 
285             memcpy(dest, slice_map, bytesPerRow);
286 
287             slice_map += tex_xfer->stride;
288          }
289 
290          map += tex_xfer->layer_stride;
291       }
292    }
293    else {
294       /* format translation via floats */
295       GLuint slice;
296       GLfloat *rgba;
297       uint32_t dstMesaFormat;
298       int dstStride, srcStride;
299 
300       assert(util_format_is_compressed(src->format));
301 
302       rgba = malloc(width * height * 4 * sizeof(GLfloat));
303       if (!rgba) {
304          goto end;
305       }
306 
307       if (ST_DEBUG & DEBUG_FALLBACK)
308          debug_printf("%s: fallback format translation\n", __func__);
309 
310       dstMesaFormat = _mesa_format_from_format_and_type(format, type);
311       dstStride = _mesa_image_row_stride(&ctx->Pack, width, format, type);
312       srcStride = 4 * width * sizeof(GLfloat);
313       for (slice = 0; slice < depth; slice++) {
314          void *dest = _mesa_image_address(dims, &ctx->Pack, pixels,
315                                           width, height, format, type,
316                                           slice, 0, 0);
317 
318          /* get float[4] rgba row from surface */
319          pipe_get_tile_rgba(tex_xfer, map, 0, 0, width, height, dst_format,
320                             rgba);
321 
322          _mesa_format_convert(dest, dstMesaFormat, dstStride,
323                               rgba, RGBA32_FLOAT, srcStride,
324                               width, height, NULL);
325 
326          /* Handle byte swapping if required */
327          if (ctx->Pack.SwapBytes) {
328             _mesa_swap_bytes_2d_image(format, type, &ctx->Pack,
329                                       width, height, dest, dest);
330          }
331 
332          map += tex_xfer->layer_stride;
333       }
334 
335       free(rgba);
336    }
337    done = true;
338 
339 end:
340    if (map)
341       pipe_texture_unmap(pipe, tex_xfer);
342 
343    _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
344    return done;
345 }
346 
347 enum pipe_format
st_pbo_get_dst_format(struct gl_context * ctx,enum pipe_texture_target target,enum pipe_format src_format,bool is_compressed,GLenum format,GLenum type,unsigned bind)348 st_pbo_get_dst_format(struct gl_context *ctx, enum pipe_texture_target target,
349                       enum pipe_format src_format, bool is_compressed,
350                       GLenum format, GLenum type, unsigned bind)
351 {
352    struct st_context *st = st_context(ctx);
353    struct pipe_screen *screen = st->screen;
354    /* Choose the destination format by finding the best match
355     * for the format+type combo. */
356    enum pipe_format dst_format = st_choose_matching_format(st, bind, format, type,
357                                                            ctx->Pack.SwapBytes);
358 
359    if (dst_format == PIPE_FORMAT_NONE) {
360       GLenum dst_glformat;
361 
362       /* Fall back to _mesa_GetTexImage_sw except for compressed formats,
363        * where decompression with a blit is always preferred. */
364       if (!is_compressed) {
365          return PIPE_FORMAT_NONE;
366       }
367 
368       /* Set the appropriate format for the decompressed texture.
369        * Luminance and sRGB formats shouldn't appear here.*/
370       switch (src_format) {
371       case PIPE_FORMAT_DXT1_RGB:
372       case PIPE_FORMAT_DXT1_RGBA:
373       case PIPE_FORMAT_DXT3_RGBA:
374       case PIPE_FORMAT_DXT5_RGBA:
375       case PIPE_FORMAT_RGTC1_UNORM:
376       case PIPE_FORMAT_RGTC2_UNORM:
377       case PIPE_FORMAT_ETC1_RGB8:
378       case PIPE_FORMAT_ETC2_RGB8:
379       case PIPE_FORMAT_ETC2_RGB8A1:
380       case PIPE_FORMAT_ETC2_RGBA8:
381       case PIPE_FORMAT_ASTC_4x4:
382       case PIPE_FORMAT_ASTC_5x4:
383       case PIPE_FORMAT_ASTC_5x5:
384       case PIPE_FORMAT_ASTC_6x5:
385       case PIPE_FORMAT_ASTC_6x6:
386       case PIPE_FORMAT_ASTC_8x5:
387       case PIPE_FORMAT_ASTC_8x6:
388       case PIPE_FORMAT_ASTC_8x8:
389       case PIPE_FORMAT_ASTC_10x5:
390       case PIPE_FORMAT_ASTC_10x6:
391       case PIPE_FORMAT_ASTC_10x8:
392       case PIPE_FORMAT_ASTC_10x10:
393       case PIPE_FORMAT_ASTC_12x10:
394       case PIPE_FORMAT_ASTC_12x12:
395       case PIPE_FORMAT_BPTC_RGBA_UNORM:
396       case PIPE_FORMAT_FXT1_RGB:
397       case PIPE_FORMAT_FXT1_RGBA:
398          dst_glformat = GL_RGBA8;
399          break;
400       case PIPE_FORMAT_RGTC1_SNORM:
401       case PIPE_FORMAT_RGTC2_SNORM:
402          if (!ctx->Extensions.EXT_texture_snorm)
403             return PIPE_FORMAT_NONE;
404          dst_glformat = GL_RGBA8_SNORM;
405          break;
406       case PIPE_FORMAT_BPTC_RGB_FLOAT:
407       case PIPE_FORMAT_BPTC_RGB_UFLOAT:
408          if (!ctx->Extensions.ARB_texture_float)
409             return PIPE_FORMAT_NONE;
410          dst_glformat = GL_RGBA32F;
411          break;
412       case PIPE_FORMAT_ETC2_R11_UNORM:
413          if (bind && !screen->is_format_supported(screen, PIPE_FORMAT_R16_UNORM,
414                                                   target, 0, 0, bind))
415             return PIPE_FORMAT_NONE;
416          dst_glformat = GL_R16;
417          break;
418       case PIPE_FORMAT_ETC2_R11_SNORM:
419          if (bind && !screen->is_format_supported(screen, PIPE_FORMAT_R16_SNORM,
420                                                   target, 0, 0, bind))
421             return PIPE_FORMAT_NONE;
422          dst_glformat = GL_R16_SNORM;
423          break;
424       case PIPE_FORMAT_ETC2_RG11_UNORM:
425          if (bind && !screen->is_format_supported(screen, PIPE_FORMAT_R16G16_UNORM,
426                                                   target, 0, 0, bind))
427             return PIPE_FORMAT_NONE;
428          dst_glformat = GL_RG16;
429          break;
430       case PIPE_FORMAT_ETC2_RG11_SNORM:
431          if (bind && !screen->is_format_supported(screen, PIPE_FORMAT_R16G16_SNORM,
432                                                   target, 0, 0, bind))
433             return PIPE_FORMAT_NONE;
434          dst_glformat = GL_RG16_SNORM;
435          break;
436       default:
437          assert(0);
438          return PIPE_FORMAT_NONE;
439       }
440 
441       dst_format = st_choose_format(st, dst_glformat, format, type,
442                                     target, 0, 0, bind,
443                                     false, false);
444    }
445    return dst_format;
446 }
447 
448 void
st_FreeTextureImageBuffer(struct gl_context * ctx,struct gl_texture_image * texImage)449 st_FreeTextureImageBuffer(struct gl_context *ctx,
450                           struct gl_texture_image *texImage)
451 {
452    struct st_context *st = st_context(ctx);
453    struct gl_texture_object *stObj = texImage->TexObject;
454    struct gl_texture_image *stImage = texImage;
455 
456    DBG("%s\n", __func__);
457 
458    if (stImage->pt) {
459       pipe_resource_reference(&stImage->pt, NULL);
460    }
461 
462    free(stImage->transfer);
463    stImage->transfer = NULL;
464    stImage->num_transfers = 0;
465 
466    if (stImage->compressed_data &&
467        pipe_reference(&stImage->compressed_data->reference, NULL)) {
468       free(stImage->compressed_data->ptr);
469       FREE(stImage->compressed_data);
470       stImage->compressed_data = NULL;
471    }
472 
473    /* if the texture image is being deallocated, the structure of the
474     * texture is changing so we'll likely need a new sampler view.
475     */
476    st_texture_release_all_sampler_views(st, stObj);
477 }
478 
479 bool
st_astc_format_fallback(const struct st_context * st,mesa_format format)480 st_astc_format_fallback(const struct st_context *st, mesa_format format)
481 {
482    if (!_mesa_is_format_astc_2d(format))
483       return false;
484 
485    if (st->astc_void_extents_need_denorm_flush && !util_format_is_srgb(format))
486       return true;
487 
488    if (format == MESA_FORMAT_RGBA_ASTC_5x5 ||
489        format == MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5)
490       return !st->has_astc_5x5_ldr;
491 
492    return !st->has_astc_2d_ldr;
493 }
494 
495 bool
st_compressed_format_fallback(struct st_context * st,mesa_format format)496 st_compressed_format_fallback(struct st_context *st, mesa_format format)
497 {
498    switch (_mesa_get_format_layout(format)) {
499    case MESA_FORMAT_LAYOUT_ETC1:
500       return !st->has_etc1;
501    case MESA_FORMAT_LAYOUT_ETC2:
502       return !st->has_etc2;
503    case MESA_FORMAT_LAYOUT_S3TC:
504       return !st->has_s3tc;
505    case MESA_FORMAT_LAYOUT_RGTC:
506       return !st->has_rgtc;
507    case MESA_FORMAT_LAYOUT_LATC:
508       return !st->has_latc;
509    case MESA_FORMAT_LAYOUT_BPTC:
510       return !st->has_bptc;
511    case MESA_FORMAT_LAYOUT_ASTC:
512       return st_astc_format_fallback(st, format);
513    default:
514       return false;
515    }
516 }
517 
518 
519 static void
compressed_tex_fallback_allocate(struct st_context * st,struct gl_texture_image * texImage)520 compressed_tex_fallback_allocate(struct st_context *st,
521                                  struct gl_texture_image *texImage)
522 {
523    if (!st_compressed_format_fallback(st, texImage->TexFormat))
524       return;
525 
526    if (texImage->compressed_data &&
527        pipe_reference(&texImage->compressed_data->reference, NULL)) {
528       free(texImage->compressed_data->ptr);
529       FREE(texImage->compressed_data);
530    }
531 
532    unsigned data_size = _mesa_format_image_size(texImage->TexFormat,
533                                                 texImage->Width2,
534                                                 texImage->Height2,
535                                                 texImage->Depth2);
536 
537    texImage->compressed_data = CALLOC_STRUCT(st_compressed_data);
538    texImage->compressed_data->ptr =
539       malloc(data_size * _mesa_num_tex_faces(texImage->TexObject->Target));
540    pipe_reference_init(&texImage->compressed_data->reference, 1);
541 }
542 
543 
544 void
st_MapTextureImage(struct gl_context * ctx,struct gl_texture_image * texImage,GLuint slice,GLuint x,GLuint y,GLuint w,GLuint h,GLbitfield mode,GLubyte ** mapOut,GLint * rowStrideOut)545 st_MapTextureImage(struct gl_context *ctx,
546                    struct gl_texture_image *texImage,
547                    GLuint slice, GLuint x, GLuint y, GLuint w, GLuint h,
548                    GLbitfield mode,
549                    GLubyte **mapOut, GLint *rowStrideOut)
550 {
551    struct st_context *st = st_context(ctx);
552 
553    /* Check for unexpected flags */
554    assert((mode & ~(GL_MAP_READ_BIT |
555                     GL_MAP_WRITE_BIT |
556                     GL_MAP_INVALIDATE_RANGE_BIT)) == 0);
557 
558    const enum pipe_map_flags transfer_flags =
559       _mesa_access_flags_to_transfer_flags(mode, false);
560 
561    if (st_compressed_format_fallback(st, texImage->TexFormat)) {
562       /* Some compressed formats don't have to be supported by drivers,
563        * and st/mesa transparently handles decompression on upload (Unmap),
564        * so that drivers don't see the compressed formats.
565        *
566        * We store the compressed data (it's needed for glGetCompressedTexImage
567        * and image copies in OES_copy_image).
568        */
569       unsigned z = slice + texImage->Face +
570                    texImage->TexObject->Attrib.MinLayer;
571 
572       /* Enlarge the transfer array if it's not large enough. */
573       st_texture_image_insert_transfer(texImage, z, NULL);
574 
575       struct st_texture_image_transfer *itransfer = &texImage->transfer[z];
576 
577       assert(itransfer->box.depth == 0);
578       if (transfer_flags & PIPE_MAP_WRITE)
579          u_box_2d_zslice(x, y, z, w, h, &itransfer->box);
580 
581       unsigned blk_w, blk_h;
582       _mesa_get_format_block_size(texImage->TexFormat, &blk_w, &blk_h);
583 
584       unsigned y_blocks = DIV_ROUND_UP(texImage->Height2, blk_h);
585       unsigned stride = *rowStrideOut = itransfer->temp_stride =
586          _mesa_format_row_stride(texImage->TexFormat, texImage->Width2);
587       unsigned block_size = _mesa_get_format_bytes(texImage->TexFormat);
588 
589       assert(texImage->compressed_data);
590       *mapOut = itransfer->temp_data =
591          texImage->compressed_data->ptr +
592          (z * y_blocks + (y / blk_h)) * stride +
593          (x / blk_w) * block_size;
594    } else {
595       struct pipe_transfer *transfer;
596       *mapOut = st_texture_image_map(st, texImage, transfer_flags,
597                                      x, y, slice, w, h, 1, &transfer);
598       *rowStrideOut = *mapOut ? transfer->stride : 0;
599    }
600 }
601 
602 static void
log_unmap_time_delta(const struct pipe_box * box,const struct gl_texture_image * texImage,const char * pathname,int64_t start_us)603 log_unmap_time_delta(const struct pipe_box *box,
604                      const struct gl_texture_image *texImage,
605                      const char *pathname, int64_t start_us)
606 {
607    assert(start_us >= 0);
608    mesa_logi("unmap %dx%d pixels of %s data for %s tex, %s path: "
609              "%"PRIi64" us\n", box->width, box->height,
610              util_format_short_name(texImage->TexFormat),
611              util_format_short_name(texImage->pt->format),
612              pathname, os_time_get() - start_us);
613 }
614 
615 /**
616  * Upload ASTC data but flush denorms in any void extent blocks.
617  */
618 static void
upload_astc_slice_with_flushed_void_extents(uint8_t * dst,unsigned dst_stride,const uint8_t * src,unsigned src_stride,unsigned src_width,unsigned src_height,mesa_format format)619 upload_astc_slice_with_flushed_void_extents(uint8_t *dst,
620                                             unsigned dst_stride,
621                                             const uint8_t *src,
622                                             unsigned src_stride,
623                                             unsigned src_width,
624                                            unsigned src_height,
625                                            mesa_format format)
626 {
627    unsigned blk_w, blk_h;
628    _mesa_get_format_block_size(format, &blk_w, &blk_h);
629 
630    unsigned x_blocks = (src_width + blk_w - 1) / blk_w;
631    unsigned y_blocks = (src_height + blk_h - 1) / blk_h;
632 
633    for (int y = 0; y < y_blocks; y++) {
634       /* An ASTC block is stored in little endian mode. The byte that
635        * contains bits 0..7 is stored at the lower address in memory.
636        */
637       struct astc_block {
638          uint16_t header;
639          uint16_t dontcare0;
640          uint16_t dontcare1;
641          uint16_t dontcare2;
642          uint16_t R;
643          uint16_t G;
644          uint16_t B;
645          uint16_t A;
646       } *blocks = (struct astc_block *) src;
647 
648       /* Iterate over every copied block in the row */
649       for (int x = 0; x < x_blocks; x++) {
650          /* Check if the header matches that of an LDR void-extent block */
651          if ((blocks[x].header & 0xfff) == 0xDFC) {
652             struct astc_block flushed_block = {
653                .header = blocks[x].header,
654                .dontcare0 = blocks[x].dontcare0,
655                .dontcare1 = blocks[x].dontcare1,
656                .dontcare2 = blocks[x].dontcare2,
657                .R = blocks[x].R < 4 ? 0 : blocks[x].R,
658                .G = blocks[x].G < 4 ? 0 : blocks[x].G,
659                .B = blocks[x].B < 4 ? 0 : blocks[x].B,
660                .A = blocks[x].A < 4 ? 0 : blocks[x].A,
661             };
662             memcpy(&dst[x * 16], &flushed_block, 16);
663          } else {
664             memcpy(&dst[x * 16], &blocks[x], 16);
665          }
666       }
667 
668       dst += dst_stride;
669       src += src_stride;
670    }
671 }
672 
673 void
st_UnmapTextureImage(struct gl_context * ctx,struct gl_texture_image * texImage,GLuint slice)674 st_UnmapTextureImage(struct gl_context *ctx,
675                      struct gl_texture_image *texImage,
676                      GLuint slice)
677 {
678    struct st_context *st = st_context(ctx);
679 
680    if (st_compressed_format_fallback(st, texImage->TexFormat)) {
681       /* Decompress the compressed image on upload if the driver doesn't
682        * support the compressed format. */
683       unsigned z = slice + texImage->Face;
684       struct st_texture_image_transfer *itransfer = &texImage->transfer[z];
685 
686       if (itransfer->box.depth != 0) {
687          assert(itransfer->box.depth == 1);
688 
689          /* Toggle logging for the different unmap paths. */
690          const bool log_unmap_time = false;
691          const int64_t unmap_start_us = log_unmap_time ? os_time_get() : 0;
692 
693          if (_mesa_is_format_astc_2d(texImage->TexFormat) &&
694              !_mesa_is_format_astc_2d(texImage->pt->format) &&
695              util_format_is_compressed(texImage->pt->format)) {
696 
697             /* DXT5 is the only supported transcode target from ASTC. */
698             assert(texImage->pt->format == PIPE_FORMAT_DXT5_RGBA ||
699                    texImage->pt->format == PIPE_FORMAT_DXT5_SRGBA);
700 
701             /* Try a compute-based transcode. */
702             if (itransfer->box.x == 0 &&
703                 itransfer->box.y == 0 &&
704                 itransfer->box.width == texImage->Width &&
705                 itransfer->box.height == texImage->Height &&
706                 _mesa_has_compute_shaders(ctx) &&
707                 st_compute_transcode_astc_to_dxt5(st,
708                    itransfer->temp_data,
709                    itransfer->temp_stride,
710                    texImage->TexFormat,
711                    texImage->pt,
712                    st_texture_image_resource_level(texImage),
713                    itransfer->box.z)) {
714 
715                if (log_unmap_time) {
716                   log_unmap_time_delta(&itransfer->box, texImage, "GPU",
717                                        unmap_start_us);
718                }
719 
720                /* Mark the unmap as complete. */
721                assert(itransfer->transfer == NULL);
722                memset(itransfer, 0, sizeof(struct st_texture_image_transfer));
723 
724                return;
725             }
726          }
727 
728          struct pipe_transfer *transfer;
729          GLubyte *map = st_texture_image_map(st, texImage,
730                                              PIPE_MAP_WRITE |
731                                              PIPE_MAP_DISCARD_RANGE,
732                                              itransfer->box.x,
733                                              itransfer->box.y, slice,
734                                              itransfer->box.width,
735                                              itransfer->box.height, 1,
736                                              &transfer);
737 
738          if (!map) {
739             _mesa_error(ctx, GL_OUT_OF_MEMORY, "compressed fallback map");
740             return;
741          }
742 
743          assert(z == transfer->box.z);
744 
745          if (_mesa_is_format_astc_2d(texImage->pt->format)) {
746             assert(st->astc_void_extents_need_denorm_flush);
747             upload_astc_slice_with_flushed_void_extents(map, transfer->stride,
748                                                         itransfer->temp_data,
749                                                         itransfer->temp_stride,
750                                                         transfer->box.width,
751                                                         transfer->box.height,
752                                                         texImage->pt->format);
753          } else if (util_format_is_compressed(texImage->pt->format)) {
754             /* Transcode into a different compressed format. */
755             unsigned size =
756                _mesa_format_image_size(PIPE_FORMAT_R8G8B8A8_UNORM,
757                                        transfer->box.width,
758                                        transfer->box.height, 1);
759             void *tmp = malloc(size);
760 
761             /* Decompress to tmp. */
762             if (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8) {
763                _mesa_etc1_unpack_rgba8888(tmp, transfer->box.width * 4,
764                                           itransfer->temp_data,
765                                           itransfer->temp_stride,
766                                           transfer->box.width,
767                                           transfer->box.height);
768             } else if (_mesa_is_format_etc2(texImage->TexFormat)) {
769                bool bgra = texImage->pt->format == PIPE_FORMAT_B8G8R8A8_SRGB;
770 
771                _mesa_unpack_etc2_format(tmp, transfer->box.width * 4,
772                                         itransfer->temp_data,
773                                         itransfer->temp_stride,
774                                         transfer->box.width,
775                                         transfer->box.height,
776                                         texImage->TexFormat,
777                                         bgra);
778             } else if (_mesa_is_format_astc_2d(texImage->TexFormat)) {
779                _mesa_unpack_astc_2d_ldr(tmp, transfer->box.width * 4,
780                                         itransfer->temp_data,
781                                         itransfer->temp_stride,
782                                         transfer->box.width,
783                                         transfer->box.height,
784                                         texImage->TexFormat);
785             } else {
786                unreachable("unexpected format for a compressed format fallback");
787             }
788 
789             /* Compress it to the target format. */
790             struct gl_pixelstore_attrib pack = {0};
791             pack.Alignment = 4;
792 
793             _mesa_texstore(ctx, 2, GL_RGBA, texImage->pt->format,
794                            transfer->stride, &map,
795                            transfer->box.width,
796                            transfer->box.height, 1, GL_RGBA,
797                            GL_UNSIGNED_BYTE, tmp, &pack);
798             free(tmp);
799          } else {
800             /* Decompress into an uncompressed format. */
801             if (texImage->TexFormat == MESA_FORMAT_ETC1_RGB8) {
802                _mesa_etc1_unpack_rgba8888(map, transfer->stride,
803                                           itransfer->temp_data,
804                                           itransfer->temp_stride,
805                                           transfer->box.width,
806                                           transfer->box.height);
807             } else if (_mesa_is_format_etc2(texImage->TexFormat)) {
808                bool bgra = texImage->pt->format == PIPE_FORMAT_B8G8R8A8_SRGB;
809 
810                _mesa_unpack_etc2_format(map, transfer->stride,
811                                         itransfer->temp_data,
812                                         itransfer->temp_stride,
813                                         transfer->box.width, transfer->box.height,
814                                         texImage->TexFormat,
815                                         bgra);
816             } else if (_mesa_is_format_astc_2d(texImage->TexFormat)) {
817                _mesa_unpack_astc_2d_ldr(map, transfer->stride,
818                                         itransfer->temp_data,
819                                         itransfer->temp_stride,
820                                         transfer->box.width, transfer->box.height,
821                                         texImage->TexFormat);
822             } else if (_mesa_is_format_s3tc(texImage->TexFormat)) {
823                _mesa_unpack_s3tc(map, transfer->stride,
824                                  itransfer->temp_data,
825                                  itransfer->temp_stride,
826                                  transfer->box.width, transfer->box.height,
827                                  texImage->TexFormat);
828             } else if (_mesa_is_format_rgtc(texImage->TexFormat) ||
829                        _mesa_is_format_latc(texImage->TexFormat)) {
830                _mesa_unpack_rgtc(map, transfer->stride,
831                                  itransfer->temp_data,
832                                  itransfer->temp_stride,
833                                  transfer->box.width, transfer->box.height,
834                                  texImage->TexFormat);
835             } else if (_mesa_is_format_bptc(texImage->TexFormat)) {
836                _mesa_unpack_bptc(map, transfer->stride,
837                                  itransfer->temp_data,
838                                  itransfer->temp_stride,
839                                  transfer->box.width, transfer->box.height,
840                                  texImage->TexFormat);
841             } else {
842                unreachable("unexpected format for a compressed format fallback");
843             }
844          }
845 
846          st_texture_image_unmap(st, texImage, slice);
847 
848          if (log_unmap_time) {
849             log_unmap_time_delta(&itransfer->box, texImage, "CPU",
850                                  unmap_start_us);
851          }
852 
853          memset(&itransfer->box, 0, sizeof(struct pipe_box));
854       }
855 
856       itransfer->temp_data = NULL;
857       itransfer->temp_stride = 0;
858    } else {
859       st_texture_image_unmap(st, texImage, slice);
860    }
861 }
862 
863 
864 /**
865  * Return default texture resource binding bitmask for the given format.
866  */
867 static GLuint
default_bindings(struct st_context * st,enum pipe_format format)868 default_bindings(struct st_context *st, enum pipe_format format)
869 {
870    struct pipe_screen *screen = st->screen;
871    const unsigned target = PIPE_TEXTURE_2D;
872    unsigned bindings;
873 
874    if (util_format_is_depth_or_stencil(format))
875       bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_DEPTH_STENCIL;
876    else
877       bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
878 
879    if (screen->is_format_supported(screen, format, target, 0, 0, bindings))
880       return bindings;
881    else {
882       /* Try non-sRGB. */
883       format = util_format_linear(format);
884 
885       if (screen->is_format_supported(screen, format, target, 0, 0, bindings))
886          return bindings;
887       else
888          return PIPE_BIND_SAMPLER_VIEW;
889    }
890 }
891 
892 
893 /**
894  * Given the size of a mipmap image, try to compute the size of the level=0
895  * mipmap image.
896  *
897  * Note that this isn't always accurate for odd-sized, non-POW textures.
898  * For example, if level=1 and width=40 then the level=0 width may be 80 or 81.
899  *
900  * \return GL_TRUE for success, GL_FALSE for failure
901  */
902 static GLboolean
guess_base_level_size(GLenum target,GLuint width,GLuint height,GLuint depth,GLuint level,GLuint * width0,GLuint * height0,GLuint * depth0)903 guess_base_level_size(GLenum target,
904                       GLuint width, GLuint height, GLuint depth, GLuint level,
905                       GLuint *width0, GLuint *height0, GLuint *depth0)
906 {
907    assert(width >= 1);
908    assert(height >= 1);
909    assert(depth >= 1);
910 
911    if (level > 0) {
912       /* Guess the size of the base level.
913        * Depending on the image's size, we can't always make a guess here.
914        */
915       switch (target) {
916       case GL_TEXTURE_1D:
917       case GL_TEXTURE_1D_ARRAY:
918          width <<= level;
919          break;
920 
921       case GL_TEXTURE_2D:
922       case GL_TEXTURE_2D_ARRAY:
923          /* We can't make a good guess here, because the base level dimensions
924           * can be non-square.
925           */
926          if (width == 1 || height == 1) {
927             return GL_FALSE;
928          }
929          width <<= level;
930          height <<= level;
931          break;
932 
933       case GL_TEXTURE_CUBE_MAP:
934       case GL_TEXTURE_CUBE_MAP_ARRAY:
935          width <<= level;
936          height <<= level;
937          break;
938 
939       case GL_TEXTURE_3D:
940          /* We can't make a good guess here, because the base level dimensions
941           * can be non-cube.
942           */
943          if (width == 1 || height == 1 || depth == 1) {
944             return GL_FALSE;
945          }
946          width <<= level;
947          height <<= level;
948          depth <<= level;
949          break;
950 
951       case GL_TEXTURE_RECTANGLE:
952          break;
953 
954       default:
955          assert(0);
956       }
957    }
958 
959    *width0 = width;
960    *height0 = height;
961    *depth0 = depth;
962 
963    return GL_TRUE;
964 }
965 
966 
967 /**
968  * Try to determine whether we should allocate memory for a full texture
969  * mipmap.  The problem is when we get a glTexImage(level=0) call, we
970  * can't immediately know if other mipmap levels are coming next.  Here
971  * we try to guess whether to allocate memory for a mipmap or just the
972  * 0th level.
973  *
974  * If we guess incorrectly here we'll later reallocate the right amount of
975  * memory either in st_AllocTextureImageBuffer() or st_finalize_texture().
976  *
977  * \param stObj  the texture object we're going to allocate memory for.
978  * \param stImage  describes the incoming image which we need to store.
979  */
980 static bool
allocate_full_mipmap(const struct gl_texture_object * stObj,const struct gl_texture_image * stImage)981 allocate_full_mipmap(const struct gl_texture_object *stObj,
982                      const struct gl_texture_image *stImage)
983 {
984    switch (stObj->Target) {
985    case GL_TEXTURE_RECTANGLE_NV:
986    case GL_TEXTURE_BUFFER:
987    case GL_TEXTURE_EXTERNAL_OES:
988    case GL_TEXTURE_2D_MULTISAMPLE:
989    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
990       /* these texture types cannot be mipmapped */
991       return false;
992    }
993 
994    if (stImage->Level > 0 || stObj->Attrib.GenerateMipmap)
995       return true;
996 
997    /* If the application has explicitly called glTextureParameter to set
998     * GL_TEXTURE_MAX_LEVEL, such that (max - base) > 0, then they're trying
999     * to communicate that they will have multiple miplevels.
1000     *
1001     * Core Mesa will initialize MaxLevel to value much larger than
1002     * MAX_TEXTURE_LEVELS, so we check that to see if it's been set at all.
1003     */
1004    if (stObj->Attrib.MaxLevel < MAX_TEXTURE_LEVELS &&
1005        stObj->Attrib.MaxLevel - stObj->Attrib.BaseLevel > 0)
1006       return true;
1007 
1008    if (stImage->_BaseFormat == GL_DEPTH_COMPONENT ||
1009        stImage->_BaseFormat == GL_DEPTH_STENCIL_EXT)
1010       /* depth/stencil textures are seldom mipmapped */
1011       return false;
1012 
1013    if (stObj->Attrib.BaseLevel == 0 && stObj->Attrib.MaxLevel == 0)
1014       return false;
1015 
1016    if (stObj->Sampler.Attrib.MinFilter == GL_NEAREST ||
1017        stObj->Sampler.Attrib.MinFilter == GL_LINEAR)
1018       /* not a mipmap minification filter */
1019       return false;
1020 
1021    /* If the following sequence of GL calls is used:
1022     *   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, ...
1023     *   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1024     *
1025     * we would needlessly allocate a mipmapped texture, because the initial
1026     * MinFilter is GL_NEAREST_MIPMAP_LINEAR. Catch this case and don't
1027     * allocate a mipmapped texture by default. This may cause texture
1028     * reallocation later, but GL_NEAREST_MIPMAP_LINEAR is pretty rare.
1029     */
1030    if (stObj->Sampler.Attrib.MinFilter == GL_NEAREST_MIPMAP_LINEAR)
1031       return false;
1032 
1033    if (stObj->Target == GL_TEXTURE_3D)
1034       /* 3D textures are seldom mipmapped */
1035       return false;
1036 
1037    return true;
1038 }
1039 
1040 
1041 /**
1042  * Try to allocate a pipe_resource object for the given gl_texture_object.
1043  *
1044  * We use the given st_texture_image as a clue to determine the size of the
1045  * mipmap image at level=0.
1046  *
1047  * \return GL_TRUE for success, GL_FALSE if out of memory.
1048  */
1049 static GLboolean
guess_and_alloc_texture(struct st_context * st,struct gl_texture_object * stObj,const struct gl_texture_image * stImage)1050 guess_and_alloc_texture(struct st_context *st,
1051                         struct gl_texture_object *stObj,
1052                         const struct gl_texture_image *stImage)
1053 {
1054    const struct gl_texture_image *firstImage;
1055    GLuint lastLevel, width, height, depth;
1056    GLuint bindings;
1057    unsigned ptWidth;
1058    uint16_t ptHeight, ptDepth, ptLayers;
1059    enum pipe_format fmt;
1060    bool guessed_box = false;
1061 
1062    DBG("%s\n", __func__);
1063 
1064    assert(!stObj->pt);
1065 
1066    /* If a base level image with compatible size exists, use that as our guess.
1067     */
1068    firstImage = _mesa_base_tex_image(stObj);
1069    if (firstImage &&
1070        firstImage->Width2 > 0 &&
1071        firstImage->Height2 > 0 &&
1072        firstImage->Depth2 > 0 &&
1073        guess_base_level_size(stObj->Target,
1074                              firstImage->Width2,
1075                              firstImage->Height2,
1076                              firstImage->Depth2,
1077                              firstImage->Level,
1078                              &width, &height, &depth)) {
1079       if (stImage->Width2 == u_minify(width, stImage->Level) &&
1080           stImage->Height2 == u_minify(height, stImage->Level) &&
1081           stImage->Depth2 == u_minify(depth, stImage->Level))
1082          guessed_box = true;
1083    }
1084 
1085    if (!guessed_box)
1086       guessed_box = guess_base_level_size(stObj->Target,
1087                                           stImage->Width2,
1088                                           stImage->Height2,
1089                                           stImage->Depth2,
1090                                           stImage->Level,
1091                                           &width, &height, &depth);
1092 
1093    if (!guessed_box) {
1094       /* we can't determine the image size at level=0 */
1095       /* this is not an out of memory error */
1096       return GL_TRUE;
1097    }
1098 
1099    /* At this point, (width x height x depth) is the expected size of
1100     * the level=0 mipmap image.
1101     */
1102 
1103    /* Guess a reasonable value for lastLevel.  With OpenGL we have no
1104     * idea how many mipmap levels will be in a texture until we start
1105     * to render with it.  Make an educated guess here but be prepared
1106     * to re-allocating a texture buffer with space for more (or fewer)
1107     * mipmap levels later.
1108     */
1109    if (allocate_full_mipmap(stObj, stImage)) {
1110       /* alloc space for a full mipmap */
1111       lastLevel = _mesa_get_tex_max_num_levels(stObj->Target,
1112                                                width, height, depth) - 1;
1113    }
1114    else {
1115       /* only alloc space for a single mipmap level */
1116       lastLevel = 0;
1117    }
1118 
1119    fmt = st_mesa_format_to_pipe_format(st, stImage->TexFormat);
1120 
1121    bindings = default_bindings(st, fmt);
1122 
1123    st_gl_texture_dims_to_pipe_dims(stObj->Target,
1124                                    width, height, depth,
1125                                    &ptWidth, &ptHeight, &ptDepth, &ptLayers);
1126 
1127    enum pipe_texture_target target = gl_target_to_pipe(stObj->Target);
1128    unsigned nr_samples = 0;
1129    if (stObj->TargetIndex == TEXTURE_2D_MULTISAMPLE_INDEX ||
1130        stObj->TargetIndex == TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX) {
1131       int samples[16];
1132       st_QueryInternalFormat(st->ctx, 0, stImage->InternalFormat, GL_SAMPLES, samples);
1133       nr_samples = samples[0];
1134    }
1135    stObj->pt = st_texture_create(st,
1136                                  target,
1137                                  fmt,
1138                                  lastLevel,
1139                                  ptWidth,
1140                                  ptHeight,
1141                                  ptDepth,
1142                                  ptLayers, nr_samples,
1143                                  bindings,
1144                                  false,
1145                                  PIPE_COMPRESSION_FIXED_RATE_NONE);
1146 
1147    stObj->lastLevel = lastLevel;
1148 
1149    DBG("%s returning %d\n", __func__, (stObj->pt != NULL));
1150 
1151    return stObj->pt != NULL;
1152 }
1153 
1154 
1155 /**
1156  * If the texture object/buffer already has space for the indicated image,
1157  * we're done.  Otherwise, allocate memory for the new texture image.
1158  */
1159 GLboolean
st_AllocTextureImageBuffer(struct gl_context * ctx,struct gl_texture_image * texImage)1160 st_AllocTextureImageBuffer(struct gl_context *ctx,
1161                            struct gl_texture_image *texImage)
1162 {
1163    struct st_context *st = st_context(ctx);
1164    struct gl_texture_image *stImage = texImage;
1165    struct gl_texture_object *stObj = texImage->TexObject;
1166    GLuint width = texImage->Width;
1167    GLuint height = texImage->Height;
1168    GLuint depth = texImage->Depth;
1169 
1170    DBG("%s\n", __func__);
1171 
1172    assert(!stImage->pt); /* xxx this might be wrong */
1173 
1174    stObj->needs_validation = true;
1175 
1176    compressed_tex_fallback_allocate(st, stImage);
1177    const bool allowAllocateToStObj = !stObj->pt ||
1178                                      stObj->pt->last_level == 0 ||
1179                                      texImage->Level == 0;
1180 
1181    if (allowAllocateToStObj) {
1182       /* Look if the parent texture object has space for this image */
1183       if (stObj->pt &&
1184           st_texture_match_image(st, stObj->pt, texImage)) {
1185          /* this image will fit in the existing texture object's memory */
1186          pipe_resource_reference(&stImage->pt, stObj->pt);
1187          assert(stImage->pt);
1188          return GL_TRUE;
1189       }
1190 
1191       /* The parent texture object does not have space for this image */
1192 
1193       pipe_resource_reference(&stObj->pt, NULL);
1194       st_texture_release_all_sampler_views(st, stObj);
1195 
1196       if (!guess_and_alloc_texture(st, stObj, stImage)) {
1197          /* Probably out of memory.
1198          * Try flushing any pending rendering, then retry.
1199          */
1200          st_finish(st);
1201          if (!guess_and_alloc_texture(st, stObj, stImage)) {
1202             _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage(internalformat=%s)",
1203                         _mesa_enum_to_string(stImage->InternalFormat));
1204             return GL_FALSE;
1205          }
1206       }
1207    }
1208 
1209    if (stObj->pt &&
1210        st_texture_match_image(st, stObj->pt, texImage)) {
1211       /* The image will live in the object's mipmap memory */
1212       pipe_resource_reference(&stImage->pt, stObj->pt);
1213       assert(stImage->pt);
1214       return GL_TRUE;
1215    }
1216    else {
1217       /* Create a new, temporary texture/resource/buffer to hold this
1218        * one texture image.  Note that when we later access this image
1219        * (either for mapping or copying) we'll want to always specify
1220        * mipmap level=0, even if the image represents some other mipmap
1221        * level.
1222        */
1223       enum pipe_format format =
1224          st_mesa_format_to_pipe_format(st, texImage->TexFormat);
1225       GLuint bindings = default_bindings(st, format);
1226       unsigned ptWidth;
1227       uint16_t ptHeight, ptDepth, ptLayers;
1228 
1229       st_gl_texture_dims_to_pipe_dims(stObj->Target,
1230                                       width, height, depth,
1231                                       &ptWidth, &ptHeight, &ptDepth, &ptLayers);
1232 
1233       stImage->pt = st_texture_create(st,
1234                                       gl_target_to_pipe(stObj->Target),
1235                                       format,
1236                                       0, /* lastLevel */
1237                                       ptWidth,
1238                                       ptHeight,
1239                                       ptDepth,
1240                                       ptLayers, 0,
1241                                       bindings,
1242                                       false,
1243                                       PIPE_COMPRESSION_FIXED_RATE_NONE);
1244       return stImage->pt != NULL;
1245    }
1246 }
1247 
1248 
1249 /**
1250  * Preparation prior to glTexImage.  Basically check the 'surface_based'
1251  * field and switch to a "normal" tex image if necessary.
1252  */
1253 static void
prep_teximage(struct gl_context * ctx,struct gl_texture_image * texImage,GLenum format,GLenum type)1254 prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage,
1255               GLenum format, GLenum type)
1256 {
1257    struct gl_texture_object *texObj = texImage->TexObject;
1258 
1259    /* switch to "normal" */
1260    if (texObj->surface_based) {
1261       const GLenum target = texObj->Target;
1262       const GLuint level = texImage->Level;
1263       mesa_format texFormat;
1264 
1265       assert(!texImage->pt);
1266       _mesa_clear_texture_object(ctx, texObj, texImage);
1267       texObj->layer_override = -1;
1268       texObj->level_override = -1;
1269       pipe_resource_reference(&texObj->pt, NULL);
1270 
1271       /* oops, need to init this image again */
1272       texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
1273                                               texImage->InternalFormat, format,
1274                                               type);
1275 
1276       _mesa_init_teximage_fields(ctx, texImage,
1277                                  texImage->Width, texImage->Height,
1278                                  texImage->Depth, texImage->Border,
1279                                  texImage->InternalFormat, texFormat);
1280 
1281       texObj->surface_based = GL_FALSE;
1282       _mesa_update_texture_object_swizzle(ctx, texObj);
1283    }
1284 }
1285 
1286 
1287 /**
1288  * Return a writemask for the gallium blit. The parameters can be base
1289  * formats or "format" from glDrawPixels/glTexImage/glGetTexImage.
1290  */
1291 unsigned
st_get_blit_mask(GLenum srcFormat,GLenum dstFormat)1292 st_get_blit_mask(GLenum srcFormat, GLenum dstFormat)
1293 {
1294    switch (dstFormat) {
1295    case GL_DEPTH_STENCIL:
1296       switch (srcFormat) {
1297       case GL_DEPTH_STENCIL:
1298          return PIPE_MASK_ZS;
1299       case GL_DEPTH_COMPONENT:
1300          return PIPE_MASK_Z;
1301       case GL_STENCIL_INDEX:
1302          return PIPE_MASK_S;
1303       default:
1304          assert(0);
1305          return 0;
1306       }
1307 
1308    case GL_DEPTH_COMPONENT:
1309       switch (srcFormat) {
1310       case GL_DEPTH_STENCIL:
1311       case GL_DEPTH_COMPONENT:
1312          return PIPE_MASK_Z;
1313       default:
1314          assert(0);
1315          return 0;
1316       }
1317 
1318    case GL_STENCIL_INDEX:
1319       switch (srcFormat) {
1320       case GL_DEPTH_STENCIL:
1321       case GL_STENCIL_INDEX:
1322          return PIPE_MASK_S;
1323       default:
1324          assert(0);
1325          return 0;
1326       }
1327 
1328    default:
1329       return PIPE_MASK_RGBA;
1330    }
1331 }
1332 
1333 /**
1334  * Converts format to a format with the same components, types
1335  * and sizes, but with the components in RGBA order.
1336  */
1337 static enum pipe_format
unswizzle_format(enum pipe_format format)1338 unswizzle_format(enum pipe_format format)
1339 {
1340    switch (format)
1341    {
1342    case PIPE_FORMAT_B8G8R8A8_UNORM:
1343    case PIPE_FORMAT_A8R8G8B8_UNORM:
1344    case PIPE_FORMAT_A8B8G8R8_UNORM:
1345       return PIPE_FORMAT_R8G8B8A8_UNORM;
1346 
1347    case PIPE_FORMAT_B10G10R10A2_UNORM:
1348       return PIPE_FORMAT_R10G10B10A2_UNORM;
1349 
1350    case PIPE_FORMAT_B10G10R10A2_SNORM:
1351       return PIPE_FORMAT_R10G10B10A2_SNORM;
1352 
1353    case PIPE_FORMAT_B10G10R10A2_UINT:
1354       return PIPE_FORMAT_R10G10B10A2_UINT;
1355 
1356    default:
1357       return format;
1358    }
1359 }
1360 
1361 
1362 /**
1363  * Converts PIPE_FORMAT_A* to PIPE_FORMAT_R*.
1364  */
1365 static enum pipe_format
alpha_to_red(enum pipe_format format)1366 alpha_to_red(enum pipe_format format)
1367 {
1368    switch (format)
1369    {
1370    case PIPE_FORMAT_A8_UNORM:
1371       return PIPE_FORMAT_R8_UNORM;
1372    case PIPE_FORMAT_A8_SNORM:
1373       return PIPE_FORMAT_R8_SNORM;
1374    case PIPE_FORMAT_A8_UINT:
1375       return PIPE_FORMAT_R8_UINT;
1376    case PIPE_FORMAT_A8_SINT:
1377       return PIPE_FORMAT_R8_SINT;
1378 
1379    case PIPE_FORMAT_A16_UNORM:
1380       return PIPE_FORMAT_R16_UNORM;
1381    case PIPE_FORMAT_A16_SNORM:
1382       return PIPE_FORMAT_R16_SNORM;
1383    case PIPE_FORMAT_A16_UINT:
1384       return PIPE_FORMAT_R16_UINT;
1385    case PIPE_FORMAT_A16_SINT:
1386       return PIPE_FORMAT_R16_SINT;
1387    case PIPE_FORMAT_A16_FLOAT:
1388       return PIPE_FORMAT_R16_FLOAT;
1389 
1390    case PIPE_FORMAT_A32_UINT:
1391       return PIPE_FORMAT_R32_UINT;
1392    case PIPE_FORMAT_A32_SINT:
1393       return PIPE_FORMAT_R32_SINT;
1394    case PIPE_FORMAT_A32_FLOAT:
1395       return PIPE_FORMAT_R32_FLOAT;
1396 
1397    default:
1398       return format;
1399    }
1400 }
1401 
1402 
1403 /**
1404  * Converts PIPE_FORMAT_R*A* to PIPE_FORMAT_R*G*.
1405  */
1406 static enum pipe_format
red_alpha_to_red_green(enum pipe_format format)1407 red_alpha_to_red_green(enum pipe_format format)
1408 {
1409    switch (format)
1410    {
1411    case PIPE_FORMAT_R8A8_UNORM:
1412       return PIPE_FORMAT_R8G8_UNORM;
1413    case PIPE_FORMAT_R8A8_SNORM:
1414       return PIPE_FORMAT_R8G8_SNORM;
1415    case PIPE_FORMAT_R8A8_UINT:
1416       return PIPE_FORMAT_R8G8_UINT;
1417    case PIPE_FORMAT_R8A8_SINT:
1418       return PIPE_FORMAT_R8G8_SINT;
1419 
1420    case PIPE_FORMAT_R16A16_UNORM:
1421       return PIPE_FORMAT_R16G16_UNORM;
1422    case PIPE_FORMAT_R16A16_SNORM:
1423       return PIPE_FORMAT_R16G16_SNORM;
1424    case PIPE_FORMAT_R16A16_UINT:
1425       return PIPE_FORMAT_R16G16_UINT;
1426    case PIPE_FORMAT_R16A16_SINT:
1427       return PIPE_FORMAT_R16G16_SINT;
1428    case PIPE_FORMAT_R16A16_FLOAT:
1429       return PIPE_FORMAT_R16G16_FLOAT;
1430 
1431    case PIPE_FORMAT_R32A32_UINT:
1432       return PIPE_FORMAT_R32G32_UINT;
1433    case PIPE_FORMAT_R32A32_SINT:
1434       return PIPE_FORMAT_R32G32_SINT;
1435    case PIPE_FORMAT_R32A32_FLOAT:
1436       return PIPE_FORMAT_R32G32_FLOAT;
1437 
1438    default:
1439        return format;
1440    }
1441 }
1442 
1443 
1444 /**
1445  * Converts PIPE_FORMAT_L*A* to PIPE_FORMAT_R*G*.
1446  */
1447 static enum pipe_format
luminance_alpha_to_red_green(enum pipe_format format)1448 luminance_alpha_to_red_green(enum pipe_format format)
1449 {
1450    switch (format)
1451    {
1452    case PIPE_FORMAT_L8A8_UNORM:
1453       return PIPE_FORMAT_R8G8_UNORM;
1454    case PIPE_FORMAT_L8A8_SNORM:
1455       return PIPE_FORMAT_R8G8_SNORM;
1456    case PIPE_FORMAT_L8A8_UINT:
1457       return PIPE_FORMAT_R8G8_UINT;
1458    case PIPE_FORMAT_L8A8_SINT:
1459       return PIPE_FORMAT_R8G8_SINT;
1460 
1461    case PIPE_FORMAT_L16A16_UNORM:
1462       return PIPE_FORMAT_R16G16_UNORM;
1463    case PIPE_FORMAT_L16A16_SNORM:
1464       return PIPE_FORMAT_R16G16_SNORM;
1465    case PIPE_FORMAT_L16A16_UINT:
1466       return PIPE_FORMAT_R16G16_UINT;
1467    case PIPE_FORMAT_L16A16_SINT:
1468       return PIPE_FORMAT_R16G16_SINT;
1469    case PIPE_FORMAT_L16A16_FLOAT:
1470       return PIPE_FORMAT_R16G16_FLOAT;
1471 
1472    case PIPE_FORMAT_L32A32_UINT:
1473       return PIPE_FORMAT_R32G32_UINT;
1474    case PIPE_FORMAT_L32A32_SINT:
1475       return PIPE_FORMAT_R32G32_SINT;
1476    case PIPE_FORMAT_L32A32_FLOAT:
1477       return PIPE_FORMAT_R32G32_FLOAT;
1478 
1479    default:
1480        return format;
1481    }
1482 }
1483 
1484 
1485 /**
1486  * Returns true if format is a PIPE_FORMAT_A* format, and false otherwise.
1487  */
1488 static bool
format_is_alpha(enum pipe_format format)1489 format_is_alpha(enum pipe_format format)
1490 {
1491    const struct util_format_description *desc = util_format_description(format);
1492 
1493    if (desc->nr_channels == 1 &&
1494        desc->swizzle[0] == PIPE_SWIZZLE_0 &&
1495        desc->swizzle[1] == PIPE_SWIZZLE_0 &&
1496        desc->swizzle[2] == PIPE_SWIZZLE_0 &&
1497        desc->swizzle[3] == PIPE_SWIZZLE_X)
1498       return true;
1499 
1500    return false;
1501 }
1502 
1503 
1504 /**
1505  * Returns true if format is a PIPE_FORMAT_R* format, and false otherwise.
1506  */
1507 static bool
format_is_red(enum pipe_format format)1508 format_is_red(enum pipe_format format)
1509 {
1510    const struct util_format_description *desc = util_format_description(format);
1511 
1512    if (desc->nr_channels == 1 &&
1513        desc->swizzle[0] == PIPE_SWIZZLE_X &&
1514        desc->swizzle[1] == PIPE_SWIZZLE_0 &&
1515        desc->swizzle[2] == PIPE_SWIZZLE_0 &&
1516        desc->swizzle[3] == PIPE_SWIZZLE_1)
1517       return true;
1518 
1519    return false;
1520 }
1521 
1522 
1523 /**
1524  * Returns true if format is a PIPE_FORMAT_L* format, and false otherwise.
1525  */
1526 static bool
format_is_luminance(enum pipe_format format)1527 format_is_luminance(enum pipe_format format)
1528 {
1529    const struct util_format_description *desc = util_format_description(format);
1530 
1531    if (desc->nr_channels == 1 &&
1532        desc->swizzle[0] == PIPE_SWIZZLE_X &&
1533        desc->swizzle[1] == PIPE_SWIZZLE_X &&
1534        desc->swizzle[2] == PIPE_SWIZZLE_X &&
1535        desc->swizzle[3] == PIPE_SWIZZLE_1)
1536       return true;
1537 
1538    return false;
1539 }
1540 
1541 /**
1542  * Returns true if format is a PIPE_FORMAT_R*A* format, and false otherwise.
1543  */
1544 static bool
format_is_red_alpha(enum pipe_format format)1545 format_is_red_alpha(enum pipe_format format)
1546 {
1547    const struct util_format_description *desc = util_format_description(format);
1548 
1549    if (desc->nr_channels == 2 &&
1550        desc->swizzle[0] == PIPE_SWIZZLE_X &&
1551        desc->swizzle[1] == PIPE_SWIZZLE_0 &&
1552        desc->swizzle[2] == PIPE_SWIZZLE_0 &&
1553        desc->swizzle[3] == PIPE_SWIZZLE_Y)
1554       return true;
1555 
1556    return false;
1557 }
1558 
1559 
1560 static bool
format_is_swizzled_rgba(enum pipe_format format)1561 format_is_swizzled_rgba(enum pipe_format format)
1562 {
1563     const struct util_format_description *desc = util_format_description(format);
1564 
1565     if ((desc->swizzle[0] == TGSI_SWIZZLE_X || desc->swizzle[0] == PIPE_SWIZZLE_0) &&
1566         (desc->swizzle[1] == TGSI_SWIZZLE_Y || desc->swizzle[1] == PIPE_SWIZZLE_0) &&
1567         (desc->swizzle[2] == TGSI_SWIZZLE_Z || desc->swizzle[2] == PIPE_SWIZZLE_0) &&
1568         (desc->swizzle[3] == TGSI_SWIZZLE_W || desc->swizzle[3] == PIPE_SWIZZLE_1))
1569        return false;
1570 
1571     return true;
1572 }
1573 
1574 
1575 struct format_table
1576 {
1577    unsigned char swizzle[4];
1578    enum pipe_format format;
1579 };
1580 
1581 static const struct format_table table_8888_unorm[] = {
1582    { { 0, 1, 2, 3 }, PIPE_FORMAT_R8G8B8A8_UNORM },
1583    { { 2, 1, 0, 3 }, PIPE_FORMAT_B8G8R8A8_UNORM },
1584    { { 3, 0, 1, 2 }, PIPE_FORMAT_A8R8G8B8_UNORM },
1585    { { 3, 2, 1, 0 }, PIPE_FORMAT_A8B8G8R8_UNORM }
1586 };
1587 
1588 static const struct format_table table_1010102_unorm[] = {
1589    { { 0, 1, 2, 3 }, PIPE_FORMAT_R10G10B10A2_UNORM },
1590    { { 2, 1, 0, 3 }, PIPE_FORMAT_B10G10R10A2_UNORM }
1591 };
1592 
1593 static const struct format_table table_1010102_snorm[] = {
1594    { { 0, 1, 2, 3 }, PIPE_FORMAT_R10G10B10A2_SNORM },
1595    { { 2, 1, 0, 3 }, PIPE_FORMAT_B10G10R10A2_SNORM }
1596 };
1597 
1598 static const struct format_table table_1010102_uint[] = {
1599    { { 0, 1, 2, 3 }, PIPE_FORMAT_R10G10B10A2_UINT },
1600    { { 2, 1, 0, 3 }, PIPE_FORMAT_B10G10R10A2_UINT }
1601 };
1602 
1603 static enum pipe_format
swizzle_format(enum pipe_format format,const int * const swizzle)1604 swizzle_format(enum pipe_format format, const int * const swizzle)
1605 {
1606    unsigned i;
1607 
1608    switch (format) {
1609    case PIPE_FORMAT_R8G8B8A8_UNORM:
1610    case PIPE_FORMAT_B8G8R8A8_UNORM:
1611    case PIPE_FORMAT_A8R8G8B8_UNORM:
1612    case PIPE_FORMAT_A8B8G8R8_UNORM:
1613       for (i = 0; i < ARRAY_SIZE(table_8888_unorm); i++) {
1614          if (swizzle[0] == table_8888_unorm[i].swizzle[0] &&
1615              swizzle[1] == table_8888_unorm[i].swizzle[1] &&
1616              swizzle[2] == table_8888_unorm[i].swizzle[2] &&
1617              swizzle[3] == table_8888_unorm[i].swizzle[3])
1618             return table_8888_unorm[i].format;
1619       }
1620       break;
1621 
1622    case PIPE_FORMAT_R10G10B10A2_UNORM:
1623    case PIPE_FORMAT_B10G10R10A2_UNORM:
1624       for (i = 0; i < ARRAY_SIZE(table_1010102_unorm); i++) {
1625          if (swizzle[0] == table_1010102_unorm[i].swizzle[0] &&
1626              swizzle[1] == table_1010102_unorm[i].swizzle[1] &&
1627              swizzle[2] == table_1010102_unorm[i].swizzle[2] &&
1628              swizzle[3] == table_1010102_unorm[i].swizzle[3])
1629             return table_1010102_unorm[i].format;
1630       }
1631       break;
1632 
1633    case PIPE_FORMAT_R10G10B10A2_SNORM:
1634    case PIPE_FORMAT_B10G10R10A2_SNORM:
1635       for (i = 0; i < ARRAY_SIZE(table_1010102_snorm); i++) {
1636          if (swizzle[0] == table_1010102_snorm[i].swizzle[0] &&
1637              swizzle[1] == table_1010102_snorm[i].swizzle[1] &&
1638              swizzle[2] == table_1010102_snorm[i].swizzle[2] &&
1639              swizzle[3] == table_1010102_snorm[i].swizzle[3])
1640             return table_1010102_snorm[i].format;
1641       }
1642       break;
1643 
1644    case PIPE_FORMAT_R10G10B10A2_UINT:
1645    case PIPE_FORMAT_B10G10R10A2_UINT:
1646       for (i = 0; i < ARRAY_SIZE(table_1010102_uint); i++) {
1647          if (swizzle[0] == table_1010102_uint[i].swizzle[0] &&
1648              swizzle[1] == table_1010102_uint[i].swizzle[1] &&
1649              swizzle[2] == table_1010102_uint[i].swizzle[2] &&
1650              swizzle[3] == table_1010102_uint[i].swizzle[3])
1651             return table_1010102_uint[i].format;
1652       }
1653       break;
1654 
1655    default:
1656       break;
1657    }
1658 
1659    return PIPE_FORMAT_NONE;
1660 }
1661 
1662 static bool
reinterpret_formats(enum pipe_format * src_format,enum pipe_format * dst_format)1663 reinterpret_formats(enum pipe_format *src_format, enum pipe_format *dst_format)
1664 {
1665    enum pipe_format src = *src_format;
1666    enum pipe_format dst = *dst_format;
1667 
1668    /* Note: dst_format has already been transformed from luminance/intensity
1669     *       to red when this function is called.  The source format will never
1670     *       be an intensity format, because GL_INTENSITY is not a legal value
1671     *       for the format parameter in glTex(Sub)Image(). */
1672 
1673    if (format_is_alpha(src)) {
1674       if (!format_is_alpha(dst))
1675          return false;
1676 
1677       src = alpha_to_red(src);
1678       dst = alpha_to_red(dst);
1679    } else if (format_is_luminance(src)) {
1680       if (!format_is_red(dst) && !format_is_red_alpha(dst))
1681          return false;
1682 
1683       src = util_format_luminance_to_red(src);
1684    } else if (util_format_is_luminance_alpha(src)) {
1685       src = luminance_alpha_to_red_green(src);
1686 
1687       if (format_is_red_alpha(dst)) {
1688          dst = red_alpha_to_red_green(dst);
1689       } else if (!format_is_red(dst))
1690          return false;
1691    } else if (format_is_swizzled_rgba(src)) {
1692       const struct util_format_description *src_desc = util_format_description(src);
1693       const struct util_format_description *dst_desc = util_format_description(dst);
1694       int swizzle[4];
1695       unsigned i;
1696 
1697       /* Make sure the format is an RGBA and not an RGBX format */
1698       if (src_desc->nr_channels != 4 || src_desc->swizzle[3] == PIPE_SWIZZLE_1)
1699          return false;
1700 
1701       if (dst_desc->nr_channels != 4 || dst_desc->swizzle[3] == PIPE_SWIZZLE_1)
1702          return false;
1703 
1704       for (i = 0; i < 4; i++)
1705          swizzle[i] = dst_desc->swizzle[src_desc->swizzle[i]];
1706 
1707       dst = swizzle_format(dst, swizzle);
1708       if (dst == PIPE_FORMAT_NONE)
1709          return false;
1710 
1711       src = unswizzle_format(src);
1712    }
1713 
1714    *src_format = src;
1715    *dst_format = dst;
1716    return true;
1717 }
1718 
1719 static bool
try_pbo_upload_common(struct gl_context * ctx,struct pipe_surface * surface,const struct st_pbo_addresses * addr,enum pipe_format src_format)1720 try_pbo_upload_common(struct gl_context *ctx,
1721                       struct pipe_surface *surface,
1722                       const struct st_pbo_addresses *addr,
1723                       enum pipe_format src_format)
1724 {
1725    struct st_context *st = st_context(ctx);
1726    struct cso_context *cso = st->cso_context;
1727    struct pipe_context *pipe = st->pipe;
1728    bool success = false;
1729    void *fs;
1730 
1731    fs = st_pbo_get_upload_fs(st, src_format, surface->format, addr->depth != 1);
1732    if (!fs)
1733       return false;
1734 
1735    cso_save_state(cso, (CSO_BIT_VERTEX_ELEMENTS |
1736                         CSO_BIT_FRAMEBUFFER |
1737                         CSO_BIT_VIEWPORT |
1738                         CSO_BIT_BLEND |
1739                         CSO_BIT_DEPTH_STENCIL_ALPHA |
1740                         CSO_BIT_RASTERIZER |
1741                         CSO_BIT_STREAM_OUTPUTS |
1742                         (st->active_queries ? CSO_BIT_PAUSE_QUERIES : 0) |
1743                         CSO_BIT_SAMPLE_MASK |
1744                         CSO_BIT_MIN_SAMPLES |
1745                         CSO_BIT_RENDER_CONDITION |
1746                         CSO_BITS_ALL_SHADERS));
1747 
1748    cso_set_sample_mask(cso, ~0);
1749    cso_set_min_samples(cso, 1);
1750    cso_set_render_condition(cso, NULL, false, 0);
1751 
1752    /* Set up the sampler_view */
1753    {
1754       struct pipe_sampler_view templ;
1755       struct pipe_sampler_view *sampler_view;
1756 
1757       memset(&templ, 0, sizeof(templ));
1758       templ.target = PIPE_BUFFER;
1759       templ.format = src_format;
1760       templ.u.buf.offset = addr->first_element * addr->bytes_per_pixel;
1761       templ.u.buf.size = (addr->last_element - addr->first_element + 1) *
1762                          addr->bytes_per_pixel;
1763       templ.swizzle_r = PIPE_SWIZZLE_X;
1764       templ.swizzle_g = PIPE_SWIZZLE_Y;
1765       templ.swizzle_b = PIPE_SWIZZLE_Z;
1766       templ.swizzle_a = PIPE_SWIZZLE_W;
1767 
1768       sampler_view = pipe->create_sampler_view(pipe, addr->buffer, &templ);
1769       if (sampler_view == NULL)
1770          goto fail;
1771 
1772       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0,
1773                               false, &sampler_view);
1774       st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] =
1775          MAX2(st->state.num_sampler_views[PIPE_SHADER_FRAGMENT], 1);
1776 
1777       pipe_sampler_view_reference(&sampler_view, NULL);
1778    }
1779 
1780    /* Framebuffer_state */
1781    {
1782       struct pipe_framebuffer_state fb;
1783       memset(&fb, 0, sizeof(fb));
1784       fb.width = surface->width;
1785       fb.height = surface->height;
1786       fb.nr_cbufs = 1;
1787       fb.cbufs[0] = surface;
1788 
1789       cso_set_framebuffer(cso, &fb);
1790    }
1791 
1792    cso_set_viewport_dims(cso, surface->width, surface->height, false);
1793 
1794    /* Blend state */
1795    cso_set_blend(cso, &st->pbo.upload_blend);
1796 
1797    /* Depth/stencil/alpha state */
1798    {
1799       struct pipe_depth_stencil_alpha_state dsa;
1800       memset(&dsa, 0, sizeof(dsa));
1801       cso_set_depth_stencil_alpha(cso, &dsa);
1802    }
1803 
1804    /* Set up the fragment shader */
1805    cso_set_fragment_shader_handle(cso, fs);
1806 
1807    success = st_pbo_draw(st, addr, surface->width, surface->height);
1808 
1809 fail:
1810    /* Unbind all because st/mesa won't do it if the current shader doesn't
1811     * use them.
1812     */
1813    cso_restore_state(cso, CSO_UNBIND_FS_SAMPLERVIEWS);
1814    st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] = 0;
1815 
1816    ctx->Array.NewVertexElements = true;
1817    ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS |
1818                           ST_NEW_FS_CONSTANTS |
1819                           ST_NEW_FS_SAMPLER_VIEWS;
1820 
1821    return success;
1822 }
1823 
1824 
1825 static bool
try_pbo_upload(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLenum format,GLenum type,enum pipe_format dst_format,GLint xoffset,GLint yoffset,GLint zoffset,GLint width,GLint height,GLint depth,const void * pixels,const struct gl_pixelstore_attrib * unpack)1826 try_pbo_upload(struct gl_context *ctx, GLuint dims,
1827                struct gl_texture_image *texImage,
1828                GLenum format, GLenum type,
1829                enum pipe_format dst_format,
1830                GLint xoffset, GLint yoffset, GLint zoffset,
1831                GLint width, GLint height, GLint depth,
1832                const void *pixels,
1833                const struct gl_pixelstore_attrib *unpack)
1834 {
1835    struct st_context *st = st_context(ctx);
1836    struct gl_texture_image *stImage = texImage;
1837    struct gl_texture_object *stObj = texImage->TexObject;
1838    struct pipe_resource *texture = stImage->pt;
1839    struct pipe_context *pipe = st->pipe;
1840    struct pipe_screen *screen = st->screen;
1841    struct pipe_surface *surface = NULL;
1842    struct st_pbo_addresses addr;
1843    enum pipe_format src_format;
1844    const struct util_format_description *desc;
1845    GLenum gl_target = texImage->TexObject->Target;
1846    bool success;
1847 
1848    if (!st->pbo.upload_enabled)
1849       return false;
1850 
1851    /* From now on, we need the gallium representation of dimensions. */
1852    if (gl_target == GL_TEXTURE_1D_ARRAY) {
1853       depth = height;
1854       height = 1;
1855       zoffset = yoffset;
1856       yoffset = 0;
1857    }
1858 
1859    if (depth != 1 && !st->pbo.layers)
1860       return false;
1861 
1862    /* Choose the source format. Initially, we do so without checking driver
1863     * support at all because of the remapping we later perform and because
1864     * at least the Radeon driver actually supports some formats for texture
1865     * buffers which it doesn't support for regular textures. */
1866    src_format = st_choose_matching_format(st, 0, format, type,
1867                                           unpack->SwapBytes);
1868    if (!src_format) {
1869       return false;
1870    }
1871 
1872    src_format = util_format_linear(src_format);
1873    desc = util_format_description(src_format);
1874 
1875    if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
1876       return false;
1877 
1878    if (desc->colorspace != UTIL_FORMAT_COLORSPACE_RGB)
1879       return false;
1880 
1881    if (st->pbo.rgba_only) {
1882       enum pipe_format orig_dst_format = dst_format;
1883 
1884       if (!reinterpret_formats(&src_format, &dst_format)) {
1885          return false;
1886       }
1887 
1888       if (dst_format != orig_dst_format &&
1889           !screen->is_format_supported(screen, dst_format, PIPE_TEXTURE_2D, 0,
1890                                        0, PIPE_BIND_RENDER_TARGET)) {
1891          return false;
1892       }
1893    }
1894 
1895    if (!src_format ||
1896        !screen->is_format_supported(screen, src_format, PIPE_BUFFER, 0, 0,
1897                                     PIPE_BIND_SAMPLER_VIEW)) {
1898       return false;
1899    }
1900 
1901    /* Compute buffer addresses */
1902    addr.xoffset = xoffset;
1903    addr.yoffset = yoffset;
1904    addr.width = width;
1905    addr.height = height;
1906    addr.depth = depth;
1907    addr.bytes_per_pixel = desc->block.bits / 8;
1908 
1909    if (!st_pbo_addresses_pixelstore(st, gl_target, dims == 3, unpack, pixels,
1910                                     &addr))
1911       return false;
1912 
1913    /* Set up the surface */
1914    {
1915       unsigned level = stObj->pt != stImage->pt
1916          ? 0 : texImage->TexObject->Attrib.MinLevel + texImage->Level;
1917       unsigned max_layer = util_max_layer(texture, level);
1918 
1919       zoffset += texImage->Face + texImage->TexObject->Attrib.MinLayer;
1920 
1921       struct pipe_surface templ;
1922       memset(&templ, 0, sizeof(templ));
1923       templ.format = dst_format;
1924       templ.u.tex.level = level;
1925       templ.u.tex.first_layer = MIN2(zoffset, max_layer);
1926       templ.u.tex.last_layer = MIN2(zoffset + depth - 1, max_layer);
1927 
1928       surface = pipe->create_surface(pipe, texture, &templ);
1929       if (!surface)
1930          return false;
1931    }
1932 
1933    success = try_pbo_upload_common(ctx, surface, &addr, src_format);
1934 
1935    pipe_surface_reference(&surface, NULL);
1936 
1937    return success;
1938 }
1939 
1940 static bool
try_pbo_download(struct st_context * st,struct gl_texture_image * texImage,enum pipe_format src_format,enum pipe_format dst_format,GLint xoffset,GLint yoffset,GLint zoffset,GLint width,GLint height,GLint depth,const struct gl_pixelstore_attrib * pack,void * pixels)1941 try_pbo_download(struct st_context *st,
1942                    struct gl_texture_image *texImage,
1943                    enum pipe_format src_format, enum pipe_format dst_format,
1944                    GLint xoffset, GLint yoffset, GLint zoffset,
1945                    GLint width, GLint height, GLint depth,
1946                    const struct gl_pixelstore_attrib *pack, void *pixels)
1947 {
1948    struct pipe_context *pipe = st->pipe;
1949    struct pipe_screen *screen = pipe->screen;
1950    struct pipe_resource *texture = texImage->pt;
1951    struct cso_context *cso = st->cso_context;
1952    const struct util_format_description *desc;
1953    struct st_pbo_addresses addr;
1954    struct pipe_framebuffer_state fb;
1955    enum pipe_texture_target pipe_target;
1956    GLenum gl_target = texImage->TexObject->Target;
1957    GLuint dims;
1958    bool success = false;
1959 
1960    if (texture->nr_samples > 1)
1961       return false;
1962 
1963    /* GetTexImage only returns a single face for cubemaps. */
1964    if (gl_target == GL_TEXTURE_CUBE_MAP) {
1965       gl_target = GL_TEXTURE_2D;
1966    }
1967    if (gl_target == GL_TEXTURE_CUBE_MAP_ARRAY) {
1968       gl_target = GL_TEXTURE_2D_ARRAY;
1969    }
1970    pipe_target = gl_target_to_pipe(gl_target);
1971    dims = _mesa_get_texture_dimensions(gl_target);
1972 
1973    /* From now on, we need the gallium representation of dimensions. */
1974    if (gl_target == GL_TEXTURE_1D_ARRAY) {
1975       depth = height;
1976       height = 1;
1977       zoffset = yoffset;
1978       yoffset = 0;
1979    }
1980 
1981    if (depth != 1 && !st->pbo.layers)
1982       return false;
1983 
1984    if (!screen->is_format_supported(screen, dst_format, PIPE_BUFFER, 0, 0,
1985                                     PIPE_BIND_SHADER_IMAGE) ||
1986        util_format_is_compressed(src_format) ||
1987        util_format_is_compressed(dst_format))
1988       return false;
1989 
1990    desc = util_format_description(dst_format);
1991 
1992    /* Compute PBO addresses */
1993    addr.bytes_per_pixel = desc->block.bits / 8;
1994    addr.xoffset = xoffset;
1995    addr.yoffset = yoffset;
1996    addr.width = width;
1997    addr.height = height;
1998    addr.depth = depth;
1999    if (!st_pbo_addresses_pixelstore(st, gl_target, dims == 3, pack, pixels, &addr))
2000       return false;
2001 
2002    cso_save_state(cso, (CSO_BIT_VERTEX_ELEMENTS |
2003                         CSO_BIT_FRAMEBUFFER |
2004                         CSO_BIT_VIEWPORT |
2005                         CSO_BIT_BLEND |
2006                         CSO_BIT_DEPTH_STENCIL_ALPHA |
2007                         CSO_BIT_RASTERIZER |
2008                         CSO_BIT_STREAM_OUTPUTS |
2009                         (st->active_queries ? CSO_BIT_PAUSE_QUERIES : 0) |
2010                         CSO_BIT_SAMPLE_MASK |
2011                         CSO_BIT_MIN_SAMPLES |
2012                         CSO_BIT_RENDER_CONDITION |
2013                         CSO_BITS_ALL_SHADERS));
2014 
2015    cso_set_sample_mask(cso, ~0);
2016    cso_set_min_samples(cso, 1);
2017    cso_set_render_condition(cso, NULL, false, 0);
2018 
2019    /* Set up the sampler_view */
2020    {
2021       struct pipe_sampler_view templ;
2022       struct pipe_sampler_view *sampler_view;
2023       struct pipe_sampler_state sampler = {0};
2024       const struct pipe_sampler_state *samplers[1] = {&sampler};
2025       unsigned level = texImage->TexObject->Attrib.MinLevel + texImage->Level;
2026       unsigned max_layer = util_max_layer(texture, level);
2027 
2028       u_sampler_view_default_template(&templ, texture, src_format);
2029 
2030       templ.target = pipe_target;
2031       templ.u.tex.first_level = level;
2032       templ.u.tex.last_level = templ.u.tex.first_level;
2033 
2034       zoffset += texImage->Face + texImage->TexObject->Attrib.MinLayer;
2035       templ.u.tex.first_layer = MIN2(zoffset, max_layer);
2036       templ.u.tex.last_layer = MIN2(zoffset + depth - 1, max_layer);
2037 
2038       sampler_view = pipe->create_sampler_view(pipe, texture, &templ);
2039       if (sampler_view == NULL)
2040          goto fail;
2041 
2042       pipe->set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, true, &sampler_view);
2043       sampler_view = NULL;
2044 
2045       cso_set_samplers(cso, PIPE_SHADER_FRAGMENT, 1, samplers);
2046    }
2047 
2048    /* Set up destination image */
2049    {
2050       struct pipe_image_view image;
2051 
2052       memset(&image, 0, sizeof(image));
2053       image.resource = addr.buffer;
2054       image.format = dst_format;
2055       image.access = PIPE_IMAGE_ACCESS_WRITE;
2056       image.shader_access = PIPE_IMAGE_ACCESS_WRITE;
2057       image.u.buf.offset = addr.first_element * addr.bytes_per_pixel;
2058       image.u.buf.size = (addr.last_element - addr.first_element + 1) *
2059                          addr.bytes_per_pixel;
2060 
2061       pipe->set_shader_images(pipe, PIPE_SHADER_FRAGMENT, 0, 1, 0, &image);
2062    }
2063 
2064    /* Set up no-attachment framebuffer */
2065    memset(&fb, 0, sizeof(fb));
2066    fb.width = texture->width0;
2067    fb.height = texture->height0;
2068    fb.layers = addr.depth;
2069    fb.samples = 1;
2070    cso_set_framebuffer(cso, &fb);
2071 
2072    /* Any blend state would do. Set this just to prevent drivers having
2073     * blend == NULL.
2074     */
2075    cso_set_blend(cso, &st->pbo.upload_blend);
2076 
2077    cso_set_viewport_dims(cso, fb.width, fb.height, false);
2078 
2079    {
2080       struct pipe_depth_stencil_alpha_state dsa;
2081       memset(&dsa, 0, sizeof(dsa));
2082       cso_set_depth_stencil_alpha(cso, &dsa);
2083    }
2084 
2085    /* Set up the fragment shader */
2086    {
2087       void *fs = st_pbo_get_download_fs(st, pipe_target, src_format, dst_format, addr.depth != 1);
2088       if (!fs)
2089          goto fail;
2090 
2091       cso_set_fragment_shader_handle(cso, fs);
2092    }
2093 
2094    success = st_pbo_draw(st, &addr, fb.width, fb.height);
2095 
2096    /* Buffer written via shader images needs explicit synchronization. */
2097    pipe->memory_barrier(pipe, PIPE_BARRIER_IMAGE | PIPE_BARRIER_TEXTURE | PIPE_BARRIER_FRAMEBUFFER);
2098 
2099 fail:
2100    /* Unbind all because st/mesa won't do it if the current shader doesn't
2101     * use them.
2102     */
2103    cso_restore_state(cso, CSO_UNBIND_FS_SAMPLERVIEWS | CSO_UNBIND_FS_IMAGE0);
2104    st->state.num_sampler_views[PIPE_SHADER_FRAGMENT] = 0;
2105 
2106    st->ctx->Array.NewVertexElements = true;
2107    st->ctx->NewDriverState |= ST_NEW_FS_CONSTANTS |
2108                               ST_NEW_FS_IMAGES |
2109                               ST_NEW_FS_SAMPLER_VIEWS |
2110                               ST_NEW_VERTEX_ARRAYS;
2111 
2112    return success;
2113 }
2114 
2115 
2116 void
st_TexSubImage(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLint xoffset,GLint yoffset,GLint zoffset,GLint width,GLint height,GLint depth,GLenum format,GLenum type,const void * pixels,const struct gl_pixelstore_attrib * unpack)2117 st_TexSubImage(struct gl_context *ctx, GLuint dims,
2118                struct gl_texture_image *texImage,
2119                GLint xoffset, GLint yoffset, GLint zoffset,
2120                GLint width, GLint height, GLint depth,
2121                GLenum format, GLenum type, const void *pixels,
2122                const struct gl_pixelstore_attrib *unpack)
2123 {
2124    struct st_context *st = st_context(ctx);
2125    struct gl_texture_object *stObj = texImage->TexObject;
2126    struct pipe_context *pipe = st->pipe;
2127    struct pipe_screen *screen = st->screen;
2128    struct pipe_resource *dst = texImage->pt;
2129    struct pipe_resource *src = NULL;
2130    struct pipe_resource src_templ;
2131    struct pipe_transfer *transfer;
2132    struct pipe_blit_info blit;
2133    enum pipe_format src_format, dst_format;
2134    mesa_format mesa_src_format;
2135    GLenum gl_target = texImage->TexObject->Target;
2136    unsigned bind;
2137    GLubyte *map;
2138    unsigned dstz = texImage->Face + texImage->TexObject->Attrib.MinLayer;
2139    unsigned dst_level = 0;
2140    bool is_ms;
2141    bool throttled = false;
2142 
2143    st_flush_bitmap_cache(st);
2144    st_invalidate_readpix_cache(st);
2145 
2146    if (stObj->pt == texImage->pt)
2147       dst_level = texImage->TexObject->Attrib.MinLevel + texImage->Level;
2148 
2149    assert(!_mesa_is_format_etc2(texImage->TexFormat) &&
2150           !_mesa_is_format_astc_2d(texImage->TexFormat) &&
2151           texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
2152 
2153    if (!dst)
2154       goto fallback;
2155 
2156    is_ms = dst->nr_samples > 1;
2157 
2158    /* Try texture_subdata, which should be the fastest memcpy path. */
2159    if (pixels &&
2160        !unpack->BufferObj &&
2161        !is_ms &&
2162        _mesa_texstore_can_use_memcpy(ctx, texImage->_BaseFormat,
2163                                      texImage->TexFormat, format, type,
2164                                      unpack)) {
2165       struct pipe_box box;
2166       unsigned stride;
2167       intptr_t layer_stride;
2168       void *data;
2169 
2170       stride = _mesa_image_row_stride(unpack, width, format, type);
2171       layer_stride = _mesa_image_image_stride(unpack, width, height, format,
2172                                               type);
2173       data = _mesa_image_address(dims, unpack, pixels, width, height, format,
2174                                  type, 0, 0, 0);
2175 
2176       /* Convert to Gallium coordinates. */
2177       if (gl_target == GL_TEXTURE_1D_ARRAY) {
2178          zoffset = yoffset;
2179          yoffset = 0;
2180          depth = height;
2181          height = 1;
2182          layer_stride = stride;
2183       }
2184 
2185       util_throttle_memory_usage(pipe, &st->throttle,
2186                                  (uint64_t) width * height * depth *
2187                                  util_format_get_blocksize(dst->format));
2188 
2189       u_box_3d(xoffset, yoffset, zoffset + dstz, width, height, depth, &box);
2190       pipe->texture_subdata(pipe, dst, dst_level, 0,
2191                             &box, data, stride, layer_stride);
2192       return;
2193    }
2194 
2195    if (!st->prefer_blit_based_texture_transfer) {
2196       goto fallback;
2197    }
2198 
2199    /* If the base internal format and the texture format don't match,
2200     * we can't use blit-based TexSubImage. */
2201    if (texImage->_BaseFormat !=
2202        _mesa_get_format_base_format(texImage->TexFormat)) {
2203       goto fallback;
2204    }
2205 
2206    /* We need both the compressed and non-compressed textures updated,
2207     * which neither the PBO nor memcpy code-paths does */
2208    if (st_compressed_format_fallback(st, texImage->TexFormat)) {
2209       goto fallback;
2210    }
2211 
2212    /* See if the destination format is supported. */
2213    if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL)
2214       bind = PIPE_BIND_DEPTH_STENCIL;
2215    else
2216       bind = PIPE_BIND_RENDER_TARGET;
2217 
2218    /* For luminance and intensity, only the red channel is stored
2219     * in the destination. */
2220    dst_format = util_format_linear(dst->format);
2221    dst_format = util_format_luminance_to_red(dst_format);
2222    dst_format = util_format_intensity_to_red(dst_format);
2223 
2224    if (!dst_format ||
2225        !screen->is_format_supported(screen, dst_format, dst->target,
2226                                     dst->nr_samples, dst->nr_storage_samples,
2227                                     bind)) {
2228       goto fallback;
2229    }
2230 
2231    if (unpack->BufferObj) {
2232       if (try_pbo_upload(ctx, dims, texImage, format, type, dst_format,
2233                          xoffset, yoffset, zoffset,
2234                          width, height, depth, pixels, unpack))
2235          return;
2236    }
2237 
2238    /* See if the texture format already matches the format and type,
2239     * in which case the memcpy-based fast path will likely be used and
2240     * we don't have to blit. */
2241    if (_mesa_format_matches_format_and_type(texImage->TexFormat, format,
2242                                             type, unpack->SwapBytes, NULL) && !is_ms) {
2243       goto fallback;
2244    }
2245 
2246    /* Choose the source format. */
2247    src_format = st_choose_matching_format(st, PIPE_BIND_SAMPLER_VIEW,
2248                                           format, type, unpack->SwapBytes);
2249    if (!src_format) {
2250       goto fallback;
2251    }
2252 
2253    mesa_src_format = st_pipe_format_to_mesa_format(src_format);
2254 
2255    /* There is no reason to do this if we cannot use memcpy for the temporary
2256     * source texture at least. This also takes transfer ops into account,
2257     * etc. */
2258    if (!_mesa_texstore_can_use_memcpy(ctx,
2259                              _mesa_get_format_base_format(mesa_src_format),
2260                              mesa_src_format, format, type, unpack) && !is_ms) {
2261       goto fallback;
2262    }
2263 
2264    /* TexSubImage only sets a single cubemap face. */
2265    if (gl_target == GL_TEXTURE_CUBE_MAP) {
2266       gl_target = GL_TEXTURE_2D;
2267    }
2268    /* TexSubImage can specify subsets of cube map array faces
2269     * so we need to upload via 2D array instead */
2270    if (gl_target == GL_TEXTURE_CUBE_MAP_ARRAY) {
2271       gl_target = GL_TEXTURE_2D_ARRAY;
2272    }
2273 
2274    /* Initialize the source texture description. */
2275    memset(&src_templ, 0, sizeof(src_templ));
2276    src_templ.target = gl_target_to_pipe(gl_target);
2277    src_templ.format = src_format;
2278    src_templ.bind = PIPE_BIND_SAMPLER_VIEW;
2279    src_templ.usage = PIPE_USAGE_STAGING;
2280 
2281    st_gl_texture_dims_to_pipe_dims(gl_target, width, height, depth,
2282                                    &src_templ.width0, &src_templ.height0,
2283                                    &src_templ.depth0, &src_templ.array_size);
2284 
2285    /* Check for NPOT texture support. */
2286    if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES) &&
2287        (!util_is_power_of_two_or_zero(src_templ.width0) ||
2288         !util_is_power_of_two_or_zero(src_templ.height0) ||
2289         !util_is_power_of_two_or_zero(src_templ.depth0))) {
2290       goto fallback;
2291    }
2292 
2293    util_throttle_memory_usage(pipe, &st->throttle,
2294                               (uint64_t) width * height * depth *
2295                               util_format_get_blocksize(src_templ.format));
2296    throttled = true;
2297 
2298    /* Create the source texture. */
2299    src = screen->resource_create(screen, &src_templ);
2300    if (!src) {
2301       goto fallback;
2302    }
2303 
2304    /* Map source pixels. */
2305    pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
2306                                         format, type, pixels, unpack,
2307                                         "glTexSubImage");
2308    if (!pixels) {
2309       /* This is a GL error. */
2310       pipe_resource_reference(&src, NULL);
2311       return;
2312    }
2313 
2314    /* From now on, we need the gallium representation of dimensions. */
2315    if (gl_target == GL_TEXTURE_1D_ARRAY) {
2316       zoffset = yoffset;
2317       yoffset = 0;
2318       depth = height;
2319       height = 1;
2320    }
2321 
2322    map = pipe_texture_map_3d(pipe, src, 0, PIPE_MAP_WRITE, 0, 0, 0,
2323                               width, height, depth, &transfer);
2324    if (!map) {
2325       _mesa_unmap_teximage_pbo(ctx, unpack);
2326       pipe_resource_reference(&src, NULL);
2327       goto fallback;
2328    }
2329 
2330    /* Upload pixels (just memcpy). */
2331    {
2332       const uint bytesPerRow = width * util_format_get_blocksize(src_format);
2333       GLuint row, slice;
2334 
2335       for (slice = 0; slice < (unsigned) depth; slice++) {
2336          if (gl_target == GL_TEXTURE_1D_ARRAY) {
2337             /* 1D array textures.
2338              * We need to convert gallium coords to GL coords.
2339              */
2340             void *src = _mesa_image_address2d(unpack, pixels,
2341                                                 width, depth, format,
2342                                                 type, slice, 0);
2343             memcpy(map, src, bytesPerRow);
2344          }
2345          else {
2346             uint8_t *slice_map = map;
2347 
2348             for (row = 0; row < (unsigned) height; row++) {
2349                void *src = _mesa_image_address(dims, unpack, pixels,
2350                                                  width, height, format,
2351                                                  type, slice, row, 0);
2352                memcpy(slice_map, src, bytesPerRow);
2353                slice_map += transfer->stride;
2354             }
2355          }
2356          map += transfer->layer_stride;
2357       }
2358    }
2359 
2360    pipe_texture_unmap(pipe, transfer);
2361    _mesa_unmap_teximage_pbo(ctx, unpack);
2362 
2363    /* Blit. */
2364    memset(&blit, 0, sizeof(blit));
2365    blit.src.resource = src;
2366    blit.src.level = 0;
2367    blit.src.format = src_format;
2368    blit.dst.resource = dst;
2369    blit.dst.level = dst_level;
2370    blit.dst.format = dst_format;
2371    blit.src.box.x = blit.src.box.y = blit.src.box.z = 0;
2372    blit.dst.box.x = xoffset;
2373    blit.dst.box.y = yoffset;
2374    blit.dst.box.z = zoffset + dstz;
2375    blit.src.box.width = blit.dst.box.width = width;
2376    blit.src.box.height = blit.dst.box.height = height;
2377    blit.src.box.depth = blit.dst.box.depth = depth;
2378    blit.mask = st_get_blit_mask(format, texImage->_BaseFormat);
2379    blit.filter = PIPE_TEX_FILTER_NEAREST;
2380    blit.scissor_enable = false;
2381 
2382    st->pipe->blit(st->pipe, &blit);
2383 
2384    pipe_resource_reference(&src, NULL);
2385    return;
2386 
2387 fallback:
2388    if (!throttled) {
2389       util_throttle_memory_usage(pipe, &st->throttle,
2390                                  (uint64_t) width * height * depth *
2391                                  _mesa_get_format_bytes(texImage->TexFormat));
2392    }
2393    _mesa_store_texsubimage(ctx, dims, texImage, xoffset, yoffset, zoffset,
2394                            width, height, depth, format, type, pixels,
2395                            unpack);
2396 }
2397 
2398 
2399 void
st_TexImage(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLenum format,GLenum type,const void * pixels,const struct gl_pixelstore_attrib * unpack)2400 st_TexImage(struct gl_context * ctx, GLuint dims,
2401             struct gl_texture_image *texImage,
2402             GLenum format, GLenum type, const void *pixels,
2403             const struct gl_pixelstore_attrib *unpack)
2404 {
2405    assert(dims == 1 || dims == 2 || dims == 3);
2406 
2407    prep_teximage(ctx, texImage, format, type);
2408 
2409    if (_mesa_is_zero_size_texture(texImage))
2410       return;
2411 
2412    /* allocate storage for texture data */
2413    if (!st_AllocTextureImageBuffer(ctx, texImage)) {
2414       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD(internalformat=%s)",
2415                   dims, _mesa_enum_to_string(texImage->InternalFormat));
2416 
2417       return;
2418    }
2419 
2420    st_TexSubImage(ctx, dims, texImage, 0, 0, 0,
2421                   texImage->Width, texImage->Height, texImage->Depth,
2422                   format, type, pixels, unpack);
2423 }
2424 
2425 static bool
st_try_pbo_compressed_texsubimage(struct gl_context * ctx,struct pipe_resource * buf,intptr_t buf_offset,const struct st_pbo_addresses * addr_tmpl,struct pipe_resource * texture,const struct pipe_surface * surface_templ)2426 st_try_pbo_compressed_texsubimage(struct gl_context *ctx,
2427                                   struct pipe_resource *buf,
2428                                   intptr_t buf_offset,
2429                                   const struct st_pbo_addresses *addr_tmpl,
2430                                   struct pipe_resource *texture,
2431                                   const struct pipe_surface *surface_templ)
2432 {
2433    struct st_context *st = st_context(ctx);
2434    struct pipe_context *pipe = st->pipe;
2435    struct st_pbo_addresses addr;
2436    struct pipe_surface *surface = NULL;
2437    bool success;
2438 
2439    addr = *addr_tmpl;
2440    if (!st_pbo_addresses_setup(st, buf, buf_offset, &addr))
2441       return false;
2442 
2443    surface = pipe->create_surface(pipe, texture, surface_templ);
2444    if (!surface)
2445       return false;
2446 
2447    success = try_pbo_upload_common(ctx, surface, &addr, surface_templ->format);
2448 
2449    pipe_surface_reference(&surface, NULL);
2450 
2451    return success;
2452 }
2453 
2454 void
st_CompressedTexSubImage(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLint x,GLint y,GLint z,GLsizei w,GLsizei h,GLsizei d,GLenum format,GLsizei imageSize,const void * data)2455 st_CompressedTexSubImage(struct gl_context *ctx, GLuint dims,
2456                          struct gl_texture_image *texImage,
2457                          GLint x, GLint y, GLint z,
2458                          GLsizei w, GLsizei h, GLsizei d,
2459                          GLenum format, GLsizei imageSize, const void *data)
2460 {
2461    struct st_context *st = st_context(ctx);
2462    struct gl_texture_image *stImage = texImage;
2463    struct gl_texture_object *stObj = texImage->TexObject;
2464    struct pipe_resource *buf;
2465    struct pipe_resource *texture = stImage->pt;
2466    struct pipe_screen *screen = st->screen;
2467    struct pipe_resource *dst = stImage->pt;
2468    struct pipe_surface templ;
2469    struct compressed_pixelstore store;
2470    struct st_pbo_addresses addr;
2471    enum pipe_format copy_format;
2472    unsigned bw, bh, level, max_layer;
2473    int layer;
2474    intptr_t buf_offset;
2475    bool success = false;
2476 
2477    /* Check basic pre-conditions for PBO upload */
2478    if (!st->prefer_blit_based_texture_transfer) {
2479       goto fallback;
2480    }
2481 
2482    if (!ctx->Unpack.BufferObj)
2483       goto fallback;
2484 
2485    if (st_compressed_format_fallback(st, texImage->TexFormat))
2486       goto fallback;
2487 
2488    if (!dst) {
2489       goto fallback;
2490    }
2491 
2492    if (!st->pbo.upload_enabled ||
2493        !screen->get_param(screen, PIPE_CAP_SURFACE_REINTERPRET_BLOCKS)) {
2494       goto fallback;
2495    }
2496 
2497    /* Choose the pipe format for the upload. */
2498    addr.bytes_per_pixel = util_format_get_blocksize(dst->format);
2499    bw = util_format_get_blockwidth(dst->format);
2500    bh = util_format_get_blockheight(dst->format);
2501 
2502    switch (addr.bytes_per_pixel) {
2503    case 8:
2504       copy_format = PIPE_FORMAT_R16G16B16A16_UINT;
2505       break;
2506    case 16:
2507       copy_format = PIPE_FORMAT_R32G32B32A32_UINT;
2508       break;
2509    default:
2510       goto fallback;
2511    }
2512 
2513    if (!screen->is_format_supported(screen, copy_format, PIPE_BUFFER, 0, 0,
2514                                     PIPE_BIND_SAMPLER_VIEW)) {
2515       goto fallback;
2516    }
2517 
2518    if (!screen->is_format_supported(screen, copy_format, dst->target,
2519                                     dst->nr_samples, dst->nr_storage_samples,
2520                                     PIPE_BIND_RENDER_TARGET)) {
2521       goto fallback;
2522    }
2523 
2524    /* Interpret the pixelstore settings. */
2525    _mesa_compute_compressed_pixelstore(dims, texImage->TexFormat, w, h, d,
2526                                        &ctx->Unpack, &store);
2527    assert(store.CopyBytesPerRow % addr.bytes_per_pixel == 0);
2528    assert(store.SkipBytes % addr.bytes_per_pixel == 0);
2529 
2530    /* Compute the offset into the buffer */
2531    buf_offset = (intptr_t)data + store.SkipBytes;
2532 
2533    if (buf_offset % addr.bytes_per_pixel) {
2534       goto fallback;
2535    }
2536 
2537    buf_offset = buf_offset / addr.bytes_per_pixel;
2538 
2539    buf = ctx->Unpack.BufferObj->buffer;
2540 
2541    addr.xoffset = x / bw;
2542    addr.yoffset = y / bh;
2543    addr.width = store.CopyBytesPerRow / addr.bytes_per_pixel;
2544    addr.height = store.CopyRowsPerSlice;
2545    addr.depth = d;
2546    addr.pixels_per_row = store.TotalBytesPerRow / addr.bytes_per_pixel;
2547    addr.image_height = store.TotalRowsPerSlice;
2548 
2549    /* Set up the surface. */
2550    level = stObj->pt != stImage->pt
2551       ? 0 : texImage->TexObject->Attrib.MinLevel + texImage->Level;
2552    max_layer = util_max_layer(texture, level);
2553    layer = z + texImage->Face + texImage->TexObject->Attrib.MinLayer;
2554 
2555    memset(&templ, 0, sizeof(templ));
2556    templ.format = copy_format;
2557    templ.u.tex.level = level;
2558    templ.u.tex.first_layer = MIN2(layer, max_layer);
2559    templ.u.tex.last_layer = MIN2(layer + d - 1, max_layer);
2560 
2561    if (st_try_pbo_compressed_texsubimage(ctx, buf, buf_offset, &addr,
2562                                          texture, &templ))
2563       return;
2564 
2565    /* Some drivers can re-interpret surfaces but only one layer at a time.
2566     * Fall back to doing a single try_pbo_upload_common per layer.
2567     */
2568    while (layer <= max_layer) {
2569       templ.u.tex.first_layer = MIN2(layer, max_layer);
2570       templ.u.tex.last_layer = templ.u.tex.first_layer;
2571       if (!st_try_pbo_compressed_texsubimage(ctx, buf, buf_offset, &addr,
2572                                              texture, &templ))
2573          goto fallback;
2574 
2575       /* By incrementing layer here, we ensure the fallback only uploads
2576        * layers we failed to upload.
2577        */
2578       buf_offset += addr.pixels_per_row * addr.image_height;
2579       layer++;
2580       addr.depth--;
2581    }
2582 
2583    if (success)
2584       return;
2585 
2586 fallback:
2587    _mesa_store_compressed_texsubimage(ctx, dims, texImage,
2588                                       x, y, z, w, h, d,
2589                                       format, imageSize, data);
2590 }
2591 
2592 
2593 void
st_CompressedTexImage(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLsizei imageSize,const void * data)2594 st_CompressedTexImage(struct gl_context *ctx, GLuint dims,
2595                       struct gl_texture_image *texImage,
2596                       GLsizei imageSize, const void *data)
2597 {
2598    prep_teximage(ctx, texImage, GL_NONE, GL_NONE);
2599 
2600    /* only 2D and 3D compressed images are supported at this time */
2601    if (dims == 1) {
2602       _mesa_problem(ctx, "Unexpected glCompressedTexImage1D call");
2603       return;
2604    }
2605 
2606    /* This is pretty simple, because unlike the general texstore path we don't
2607     * have to worry about the usual image unpacking or image transfer
2608     * operations.
2609     */
2610    assert(texImage);
2611    assert(texImage->Width > 0);
2612    assert(texImage->Height > 0);
2613    assert(texImage->Depth > 0);
2614 
2615    /* allocate storage for texture data */
2616    if (!st_AllocTextureImageBuffer(ctx, texImage)) {
2617       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage%uD", dims);
2618       return;
2619    }
2620 
2621    st_CompressedTexSubImage(ctx, dims, texImage,
2622                             0, 0, 0,
2623                             texImage->Width, texImage->Height, texImage->Depth,
2624                             texImage->TexFormat,
2625                             imageSize, data);
2626 }
2627 
2628 
2629 /**
2630  * Called via ctx->Driver.GetTexSubImage()
2631  *
2632  * This uses a blit to copy the texture to a texture format which matches
2633  * the format and type combo and then a fast read-back is done using memcpy.
2634  * We can do arbitrary X/Y/Z/W/0/1 swizzling here as long as there is
2635  * a format which matches the swizzling.
2636  *
2637  * If such a format isn't available, it falls back to _mesa_GetTexImage_sw.
2638  *
2639  * NOTE: Drivers usually do a blit to convert between tiled and linear
2640  *       texture layouts during texture uploads/downloads, so the blit
2641  *       we do here should be free in such cases.
2642  */
2643 void
st_GetTexSubImage(struct gl_context * ctx,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLint depth,GLenum format,GLenum type,void * pixels,struct gl_texture_image * texImage)2644 st_GetTexSubImage(struct gl_context * ctx,
2645                   GLint xoffset, GLint yoffset, GLint zoffset,
2646                   GLsizei width, GLsizei height, GLint depth,
2647                   GLenum format, GLenum type, void * pixels,
2648                   struct gl_texture_image *texImage)
2649 {
2650    struct st_context *st = st_context(ctx);
2651    struct pipe_screen *screen = st->screen;
2652    struct gl_texture_image *stImage = texImage;
2653    struct gl_texture_object *stObj = texImage->TexObject;
2654    struct pipe_resource *src = stObj->pt;
2655    struct pipe_resource *dst = NULL;
2656    enum pipe_format dst_format, src_format;
2657    GLenum gl_target = texImage->TexObject->Target;
2658    enum pipe_texture_target pipe_target;
2659    struct pipe_blit_info blit;
2660    unsigned bind;
2661    bool done = false;
2662 
2663    assert(!_mesa_is_format_etc2(texImage->TexFormat) &&
2664           !_mesa_is_format_astc_2d(texImage->TexFormat) &&
2665           texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
2666 
2667    st_flush_bitmap_cache(st);
2668    if (st->force_compute_based_texture_transfer)
2669       goto non_blit_transfer;
2670 
2671    /* GetTexImage only returns a single face for cubemaps. */
2672    if (gl_target == GL_TEXTURE_CUBE_MAP) {
2673       gl_target = GL_TEXTURE_2D;
2674    }
2675    pipe_target = gl_target_to_pipe(gl_target);
2676 
2677    if (!st->prefer_blit_based_texture_transfer &&
2678        !_mesa_is_format_compressed(texImage->TexFormat)) {
2679       /* Try to avoid the non_blit_transfer if we're doing texture decompression here */
2680       goto non_blit_transfer;
2681    }
2682 
2683    if (stImage->pt != stObj->pt)
2684       goto non_blit_transfer;
2685 
2686    /* Handle non-finalized textures. */
2687    if (!stImage->pt || !src) {
2688       goto cpu_transfer;
2689    }
2690 
2691    /* XXX Fallback to _mesa_GetTexImage_sw for depth-stencil formats
2692     * due to an incomplete stencil blit implementation in some drivers. */
2693    if (format == GL_DEPTH_STENCIL || format == GL_STENCIL_INDEX) {
2694       goto non_blit_transfer;
2695    }
2696 
2697    /* If the base internal format and the texture format don't match, we have
2698     * to fall back to _mesa_GetTexImage_sw. */
2699    if (texImage->_BaseFormat !=
2700        _mesa_get_format_base_format(texImage->TexFormat)) {
2701       goto non_blit_transfer;
2702    }
2703 
2704    src_format = st_pbo_get_src_format(screen, stObj->surface_based ? stObj->surface_format : src->format, src);
2705    if (src_format == PIPE_FORMAT_NONE)
2706       goto non_blit_transfer;
2707 
2708    if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL)
2709       bind = PIPE_BIND_DEPTH_STENCIL;
2710    else
2711       bind = PIPE_BIND_RENDER_TARGET;
2712 
2713    dst_format = st_pbo_get_dst_format(ctx, pipe_target, src_format, util_format_is_compressed(src->format),
2714                                format, type, bind);
2715    if (dst_format == PIPE_FORMAT_NONE)
2716       goto non_blit_transfer;
2717 
2718    if (st->pbo.download_enabled && ctx->Pack.BufferObj) {
2719       if (try_pbo_download(st, texImage,
2720                            src_format, dst_format,
2721                            xoffset, yoffset, zoffset,
2722                            width, height, depth,
2723                            &ctx->Pack, pixels))
2724          return;
2725    }
2726 
2727    /* See if the texture format already matches the format and type,
2728     * in which case the memcpy-based fast path will be used. */
2729    if (_mesa_format_matches_format_and_type(texImage->TexFormat, format,
2730                                             type, ctx->Pack.SwapBytes, NULL))
2731       goto non_blit_transfer;
2732 
2733    dst = create_dst_texture(ctx, dst_format, pipe_target, width, height, depth, gl_target, bind);
2734    if (!dst)
2735       goto non_blit_transfer;
2736 
2737    /* From now on, we need the gallium representation of dimensions. */
2738    if (gl_target == GL_TEXTURE_1D_ARRAY) {
2739       zoffset = yoffset;
2740       yoffset = 0;
2741       depth = height;
2742       height = 1;
2743    }
2744 
2745    assert(texImage->Face == 0 ||
2746           texImage->TexObject->Attrib.MinLayer == 0 ||
2747           zoffset == 0);
2748 
2749    memset(&blit, 0, sizeof(blit));
2750    blit.src.resource = src;
2751    blit.src.level = texImage->Level + texImage->TexObject->Attrib.MinLevel;
2752    blit.src.format = src_format;
2753    blit.dst.resource = dst;
2754    blit.dst.level = 0;
2755    blit.dst.format = dst->format;
2756    blit.src.box.x = xoffset;
2757    blit.dst.box.x = 0;
2758    blit.src.box.y = yoffset;
2759    blit.dst.box.y = 0;
2760    blit.src.box.z = texImage->Face + texImage->TexObject->Attrib.MinLayer + zoffset;
2761    blit.dst.box.z = 0;
2762    blit.src.box.width = blit.dst.box.width = width;
2763    blit.src.box.height = blit.dst.box.height = height;
2764    blit.src.box.depth = blit.dst.box.depth = depth;
2765    blit.mask = st_get_blit_mask(texImage->_BaseFormat, format);
2766    blit.filter = PIPE_TEX_FILTER_NEAREST;
2767    blit.scissor_enable = false;
2768 
2769    /* blit/render/decompress */
2770    st->pipe->blit(st->pipe, &blit);
2771 
2772    done = copy_to_staging_dest(ctx, dst, xoffset, yoffset, zoffset, width, height,
2773                            depth, format, type, pixels, texImage);
2774    pipe_resource_reference(&dst, NULL);
2775 
2776 non_blit_transfer:
2777    if (done)
2778       return;
2779    if (st->allow_compute_based_texture_transfer || st->force_compute_based_texture_transfer) {
2780       if (st_GetTexSubImage_shader(ctx, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels, texImage))
2781          return;
2782    }
2783 cpu_transfer:
2784    _mesa_GetTexSubImage_sw(ctx, xoffset, yoffset, zoffset,
2785                            width, height, depth,
2786                            format, type, pixels, texImage);
2787 }
2788 
2789 
2790 /**
2791  * Do a CopyTexSubImage operation using a read transfer from the source,
2792  * a write transfer to the destination and get_tile()/put_tile() to access
2793  * the pixels/texels.
2794  *
2795  * Note: srcY=0=TOP of renderbuffer
2796  */
2797 static void
fallback_copy_texsubimage(struct gl_context * ctx,struct gl_renderbuffer * rb,struct gl_texture_image * stImage,GLenum baseFormat,GLint destX,GLint destY,GLint slice,GLint srcX,GLint srcY,GLsizei width,GLsizei height)2798 fallback_copy_texsubimage(struct gl_context *ctx,
2799                           struct gl_renderbuffer *rb,
2800                           struct gl_texture_image *stImage,
2801                           GLenum baseFormat,
2802                           GLint destX, GLint destY, GLint slice,
2803                           GLint srcX, GLint srcY,
2804                           GLsizei width, GLsizei height)
2805 {
2806    struct st_context *st = st_context(ctx);
2807    struct pipe_context *pipe = st->pipe;
2808    struct pipe_transfer *src_trans;
2809    GLubyte *texDest;
2810    enum pipe_map_flags transfer_usage;
2811    void *map;
2812    unsigned dst_width = width;
2813    unsigned dst_height = height;
2814    unsigned dst_depth = 1;
2815    struct pipe_transfer *transfer;
2816 
2817    if (ST_DEBUG & DEBUG_FALLBACK)
2818       debug_printf("%s: fallback processing\n", __func__);
2819 
2820    if (_mesa_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
2821       srcY = rb->Height - srcY - height;
2822    }
2823 
2824    map = pipe_texture_map(pipe,
2825                            rb->texture,
2826                            rb->surface->u.tex.level,
2827                            rb->surface->u.tex.first_layer,
2828                            PIPE_MAP_READ,
2829                            srcX, srcY,
2830                            width, height, &src_trans);
2831    if (!map) {
2832       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()");
2833       return;
2834    }
2835 
2836    if ((baseFormat == GL_DEPTH_COMPONENT ||
2837         baseFormat == GL_DEPTH_STENCIL) &&
2838        util_format_is_depth_and_stencil(stImage->pt->format))
2839       transfer_usage = PIPE_MAP_READ_WRITE;
2840    else
2841       transfer_usage = PIPE_MAP_WRITE;
2842 
2843    texDest = st_texture_image_map(st, stImage, transfer_usage,
2844                                   destX, destY, slice,
2845                                   dst_width, dst_height, dst_depth,
2846                                   &transfer);
2847    if (!texDest) {
2848       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()");
2849       goto err;
2850    }
2851 
2852    if (baseFormat == GL_DEPTH_COMPONENT ||
2853        baseFormat == GL_DEPTH_STENCIL) {
2854       const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F ||
2855                                      ctx->Pixel.DepthBias != 0.0F);
2856       GLint row, yStep;
2857       uint *data;
2858 
2859       /* determine bottom-to-top vs. top-to-bottom order for src buffer */
2860       if (_mesa_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
2861          srcY = height - 1;
2862          yStep = -1;
2863       }
2864       else {
2865          srcY = 0;
2866          yStep = 1;
2867       }
2868 
2869       data = malloc(width * sizeof(uint));
2870 
2871       if (data) {
2872          unsigned dst_stride = (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY ?
2873                                 transfer->layer_stride : transfer->stride);
2874          /* To avoid a large temp memory allocation, do copy row by row */
2875          for (row = 0; row < height; row++, srcY += yStep) {
2876             util_format_unpack_z_32unorm(rb->texture->format,
2877                                          data, (uint8_t *)map + src_trans->stride * srcY,
2878                                          width);
2879             if (scaleOrBias) {
2880                _mesa_scale_and_bias_depth_uint(ctx, width, data);
2881             }
2882 
2883             util_format_pack_z_32unorm(stImage->pt->format,
2884                                        texDest + row * dst_stride, data, width);
2885          }
2886       }
2887       else {
2888          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()");
2889       }
2890 
2891       free(data);
2892    }
2893    else {
2894       /* RGBA format */
2895       GLfloat *tempSrc =
2896          malloc(width * height * 4 * sizeof(GLfloat));
2897 
2898       if (tempSrc) {
2899          const GLint dims = 2;
2900          GLint dstRowStride;
2901          struct gl_texture_image *texImage = stImage;
2902          struct gl_pixelstore_attrib unpack = ctx->DefaultPacking;
2903 
2904          if (_mesa_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
2905             unpack.Invert = GL_TRUE;
2906          }
2907 
2908          if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {
2909             dstRowStride = transfer->layer_stride;
2910          }
2911          else {
2912             dstRowStride = transfer->stride;
2913          }
2914 
2915          /* get float/RGBA image from framebuffer */
2916          /* XXX this usually involves a lot of int/float conversion.
2917           * try to avoid that someday.
2918           */
2919          pipe_get_tile_rgba(src_trans, map, 0, 0, width, height,
2920                             util_format_linear(rb->texture->format),
2921                             tempSrc);
2922 
2923          /* Store into texture memory.
2924           * Note that this does some special things such as pixel transfer
2925           * ops and format conversion.  In particular, if the dest tex format
2926           * is actually RGBA but the user created the texture as GL_RGB we
2927           * need to fill-in/override the alpha channel with 1.0.
2928           */
2929          _mesa_texstore(ctx, dims,
2930                         texImage->_BaseFormat,
2931                         texImage->TexFormat,
2932                         dstRowStride,
2933                         &texDest,
2934                         width, height, 1,
2935                         GL_RGBA, GL_FLOAT, tempSrc, /* src */
2936                         &unpack);
2937       }
2938       else {
2939          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
2940       }
2941 
2942       free(tempSrc);
2943    }
2944 
2945    st_texture_image_unmap(st, stImage, slice);
2946 err:
2947    pipe->texture_unmap(pipe, src_trans);
2948 }
2949 
2950 
2951 static bool
st_can_copyteximage_using_blit(const struct gl_texture_image * texImage,const struct gl_renderbuffer * rb)2952 st_can_copyteximage_using_blit(const struct gl_texture_image *texImage,
2953                                const struct gl_renderbuffer *rb)
2954 {
2955    GLenum tex_baseformat = _mesa_get_format_base_format(texImage->TexFormat);
2956 
2957    /* We don't blit to a teximage where the GL base format doesn't match the
2958     * texture's chosen format, except in the case of a GL_RGB texture
2959     * represented with GL_RGBA (where the alpha channel is just being
2960     * dropped).
2961     */
2962    if (texImage->_BaseFormat != tex_baseformat &&
2963        ((texImage->_BaseFormat != GL_RGB || tex_baseformat != GL_RGBA))) {
2964       return false;
2965    }
2966 
2967    /* We can't blit from a RB where the GL base format doesn't match the RB's
2968     * chosen format (for example, GL RGB or ALPHA with rb->Format of an RGBA
2969     * type, because the other channels will be undefined).
2970     */
2971    if (rb->_BaseFormat != _mesa_get_format_base_format(rb->Format))
2972       return false;
2973 
2974    return true;
2975 }
2976 
2977 
2978 /**
2979  * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible.
2980  * Note that the region to copy has already been clipped so we know we
2981  * won't read from outside the source renderbuffer's bounds.
2982  *
2983  * Note: srcY=0=Bottom of renderbuffer (GL convention)
2984  */
2985 void
st_CopyTexSubImage(struct gl_context * ctx,GLuint dims,struct gl_texture_image * texImage,GLint destX,GLint destY,GLint slice,struct gl_renderbuffer * rb,GLint srcX,GLint srcY,GLsizei width,GLsizei height)2986 st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
2987                    struct gl_texture_image *texImage,
2988                    GLint destX, GLint destY, GLint slice,
2989                    struct gl_renderbuffer *rb,
2990                    GLint srcX, GLint srcY, GLsizei width, GLsizei height)
2991 {
2992    struct gl_texture_image *stImage = texImage;
2993    struct gl_texture_object *stObj = texImage->TexObject;
2994    struct st_context *st = st_context(ctx);
2995    struct pipe_context *pipe = st->pipe;
2996    struct pipe_screen *screen = st->screen;
2997    struct pipe_blit_info blit;
2998    enum pipe_format dst_format;
2999    GLboolean do_flip = (_mesa_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
3000    unsigned bind;
3001    GLint srcY0, srcY1;
3002 
3003    st_flush_bitmap_cache(st);
3004    st_invalidate_readpix_cache(st);
3005 
3006    assert(!_mesa_is_format_etc2(texImage->TexFormat) &&
3007           !_mesa_is_format_astc_2d(texImage->TexFormat) &&
3008           texImage->TexFormat != MESA_FORMAT_ETC1_RGB8);
3009 
3010    if (!rb || !rb->surface || !stImage->pt) {
3011       debug_printf("%s: null rb or stImage\n", __func__);
3012       return;
3013    }
3014 
3015    if (_mesa_texstore_needs_transfer_ops(ctx, texImage->_BaseFormat,
3016                                          texImage->TexFormat)) {
3017       goto fallback;
3018    }
3019 
3020    if (!st_can_copyteximage_using_blit(texImage, rb)) {
3021       goto fallback;
3022    }
3023 
3024    /* Choose the destination format to match the TexImage behavior. */
3025    dst_format = util_format_linear(stImage->pt->format);
3026    dst_format = util_format_luminance_to_red(dst_format);
3027    dst_format = util_format_intensity_to_red(dst_format);
3028 
3029    /* See if the destination format is supported. */
3030    if (texImage->_BaseFormat == GL_DEPTH_STENCIL ||
3031        texImage->_BaseFormat == GL_DEPTH_COMPONENT) {
3032       bind = PIPE_BIND_DEPTH_STENCIL;
3033    }
3034    else {
3035       bind = PIPE_BIND_RENDER_TARGET;
3036    }
3037 
3038    if (!dst_format ||
3039        !screen->is_format_supported(screen, dst_format, stImage->pt->target,
3040                                     stImage->pt->nr_samples,
3041                                     stImage->pt->nr_storage_samples, bind)) {
3042       goto fallback;
3043    }
3044 
3045    /* Y flipping for the main framebuffer. */
3046    if (do_flip) {
3047       srcY1 = rb->Height - srcY - height;
3048       srcY0 = srcY1 + height;
3049    }
3050    else {
3051       srcY0 = srcY;
3052       srcY1 = srcY0 + height;
3053    }
3054 
3055    /* Blit the texture.
3056     * This supports flipping, format conversions, and downsampling.
3057     */
3058    memset(&blit, 0, sizeof(blit));
3059    blit.src.resource = rb->texture;
3060    blit.src.format = util_format_linear(rb->surface->format);
3061    blit.src.level = rb->surface->u.tex.level;
3062    blit.src.box.x = srcX;
3063    blit.src.box.y = srcY0;
3064    blit.src.box.z = rb->surface->u.tex.first_layer;
3065    blit.src.box.width = width;
3066    blit.src.box.height = srcY1 - srcY0;
3067    blit.src.box.depth = 1;
3068    blit.dst.resource = stImage->pt;
3069    blit.dst.format = dst_format;
3070    blit.dst.level = stObj->pt != stImage->pt
3071       ? 0 : texImage->Level + texImage->TexObject->Attrib.MinLevel;
3072    blit.dst.box.x = destX;
3073    blit.dst.box.y = destY;
3074    blit.dst.box.z = stImage->Face + slice +
3075                     texImage->TexObject->Attrib.MinLayer;
3076    blit.dst.box.width = width;
3077    blit.dst.box.height = height;
3078    blit.dst.box.depth = 1;
3079    blit.mask = st_get_blit_mask(rb->_BaseFormat, texImage->_BaseFormat);
3080    blit.filter = PIPE_TEX_FILTER_NEAREST;
3081    pipe->blit(pipe, &blit);
3082    return;
3083 
3084 fallback:
3085    /* software fallback */
3086    fallback_copy_texsubimage(ctx,
3087                              rb, stImage, texImage->_BaseFormat,
3088                              destX, destY, slice,
3089                              srcX, srcY, width, height);
3090 }
3091 
3092 
3093 /**
3094  * Copy image data from stImage into the texture object 'stObj' at level
3095  * 'dstLevel'.
3096  */
3097 static void
copy_image_data_to_texture(struct st_context * st,struct gl_texture_object * stObj,GLuint dstLevel,struct gl_texture_image * stImage)3098 copy_image_data_to_texture(struct st_context *st,
3099                            struct gl_texture_object *stObj,
3100                            GLuint dstLevel,
3101                            struct gl_texture_image *stImage)
3102 {
3103    /* debug checks */
3104    {
3105       ASSERTED const struct gl_texture_image *dstImage =
3106          stObj->Image[stImage->Face][dstLevel];
3107       assert(dstImage);
3108       assert(dstImage->Width == stImage->Width);
3109       assert(dstImage->Height == stImage->Height);
3110       assert(dstImage->Depth == stImage->Depth);
3111    }
3112 
3113    if (stImage->pt) {
3114       /* Copy potentially with the blitter:
3115        */
3116       GLuint src_level;
3117       if (stImage->pt->last_level == 0)
3118          src_level = 0;
3119       else
3120          src_level = stImage->Level;
3121 
3122       assert(src_level <= stImage->pt->last_level);
3123       assert(u_minify(stImage->pt->width0, src_level) == stImage->Width);
3124       assert(stImage->pt->target == PIPE_TEXTURE_1D_ARRAY ||
3125              u_minify(stImage->pt->height0, src_level) == stImage->Height);
3126       assert(stImage->pt->target == PIPE_TEXTURE_2D_ARRAY ||
3127              stImage->pt->target == PIPE_TEXTURE_CUBE_ARRAY ||
3128              u_minify(stImage->pt->depth0, src_level) == stImage->Depth);
3129 
3130       st_texture_image_copy(st->pipe,
3131                             stObj->pt, dstLevel,  /* dest texture, level */
3132                             stImage->pt, src_level, /* src texture, level */
3133                             stImage->Face);
3134 
3135       pipe_resource_reference(&stImage->pt, NULL);
3136    }
3137    pipe_resource_reference(&stImage->pt, stObj->pt);
3138 }
3139 
3140 
3141 /**
3142  * Called during state validation.  When this function is finished,
3143  * the texture object should be ready for rendering.
3144  * \return GL_TRUE for success, GL_FALSE for failure (out of mem)
3145  */
3146 GLboolean
st_finalize_texture(struct gl_context * ctx,struct pipe_context * pipe,struct gl_texture_object * tObj,GLuint cubeMapFace)3147 st_finalize_texture(struct gl_context *ctx,
3148                     struct pipe_context *pipe,
3149                     struct gl_texture_object *tObj,
3150                     GLuint cubeMapFace)
3151 {
3152    struct st_context *st = st_context(ctx);
3153    const GLuint nr_faces = _mesa_num_tex_faces(tObj->Target);
3154    GLuint face;
3155    const struct gl_texture_image *firstImage;
3156    enum pipe_format firstImageFormat;
3157    unsigned ptWidth;
3158    uint16_t ptHeight, ptDepth, ptLayers, ptNumSamples;
3159 
3160    if (tObj->Immutable)
3161       return GL_TRUE;
3162 
3163    if (tObj->_MipmapComplete)
3164       tObj->lastLevel = tObj->_MaxLevel;
3165    else if (tObj->_BaseComplete)
3166       tObj->lastLevel = tObj->Attrib.BaseLevel;
3167 
3168    /* Skip the loop over images in the common case of no images having
3169     * changed.  But if the GL_BASE_LEVEL or GL_MAX_LEVEL change to something we
3170     * haven't looked at, then we do need to look at those new images.
3171     */
3172    if (!tObj->needs_validation &&
3173        tObj->Attrib.BaseLevel >= tObj->validated_first_level &&
3174        tObj->lastLevel <= tObj->validated_last_level) {
3175       return GL_TRUE;
3176    }
3177 
3178    /* If this texture comes from a window system, there is nothing else to do. */
3179    if (tObj->surface_based) {
3180       return GL_TRUE;
3181    }
3182 
3183    firstImage = st_texture_image_const(tObj->Image[cubeMapFace]
3184                                        [tObj->Attrib.BaseLevel]);
3185    if (!firstImage)
3186       return false;
3187 
3188    /* If both firstImage and tObj point to a texture which can contain
3189     * all active images, favour firstImage.  Note that because of the
3190     * completeness requirement, we know that the image dimensions
3191     * will match.
3192     */
3193    if (firstImage->pt &&
3194        firstImage->pt != tObj->pt &&
3195        (!tObj->pt || firstImage->pt->last_level >= tObj->pt->last_level)) {
3196       pipe_resource_reference(&tObj->pt, firstImage->pt);
3197       st_texture_release_all_sampler_views(st, tObj);
3198    }
3199 
3200    /* Find gallium format for the Mesa texture */
3201    firstImageFormat =
3202       st_mesa_format_to_pipe_format(st, firstImage->TexFormat);
3203 
3204    /* Find size of level=0 Gallium mipmap image, plus number of texture layers */
3205    {
3206       unsigned width;
3207       uint16_t height, depth;
3208 
3209       st_gl_texture_dims_to_pipe_dims(tObj->Target,
3210                                       firstImage->Width2,
3211                                       firstImage->Height2,
3212                                       firstImage->Depth2,
3213                                       &width, &height, &depth, &ptLayers);
3214 
3215       /* If we previously allocated a pipe texture and its sizes are
3216        * compatible, use them.
3217        */
3218       if (tObj->pt &&
3219           u_minify(tObj->pt->width0, firstImage->Level) == width &&
3220           u_minify(tObj->pt->height0, firstImage->Level) == height &&
3221           u_minify(tObj->pt->depth0, firstImage->Level) == depth) {
3222          ptWidth = tObj->pt->width0;
3223          ptHeight = tObj->pt->height0;
3224          ptDepth = tObj->pt->depth0;
3225       } else {
3226          /* Otherwise, compute a new level=0 size that is compatible with the
3227           * base level image.
3228           */
3229          ptWidth = width > 1 ? width << firstImage->Level : 1;
3230          ptHeight = height > 1 ? height << firstImage->Level : 1;
3231          ptDepth = depth > 1 ? depth << firstImage->Level : 1;
3232 
3233          /* If the base level image is 1x1x1, we still need to ensure that the
3234           * resulting pipe texture ends up with the required number of levels
3235           * in total.
3236           */
3237          if (ptWidth == 1 && ptHeight == 1 && ptDepth == 1) {
3238             ptWidth <<= firstImage->Level;
3239 
3240             if (tObj->Target == GL_TEXTURE_CUBE_MAP ||
3241                 tObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY)
3242                ptHeight = ptWidth;
3243          }
3244 
3245          /* At this point, the texture may be incomplete (mismatched cube
3246           * face sizes, for example).  If that's the case, give up, but
3247           * don't return GL_FALSE as that would raise an incorrect
3248           * GL_OUT_OF_MEMORY error.  See Piglit fbo-incomplete-texture-03 test.
3249           */
3250          if (!tObj->_BaseComplete) {
3251             _mesa_test_texobj_completeness(ctx, tObj);
3252             if (!tObj->_BaseComplete) {
3253                return true;
3254             }
3255          }
3256       }
3257 
3258       ptNumSamples = firstImage->NumSamples;
3259    }
3260 
3261    /* If we already have a gallium texture, check that it matches the texture
3262     * object's format, target, size, num_levels, etc.
3263     */
3264    if (tObj->pt) {
3265       if (tObj->pt->target != gl_target_to_pipe(tObj->Target) ||
3266           tObj->pt->format != firstImageFormat ||
3267           tObj->pt->last_level < tObj->lastLevel ||
3268           tObj->pt->width0 != ptWidth ||
3269           tObj->pt->height0 != ptHeight ||
3270           tObj->pt->depth0 != ptDepth ||
3271           tObj->pt->nr_samples != ptNumSamples ||
3272           tObj->pt->array_size != ptLayers)
3273       {
3274          /* The gallium texture does not match the Mesa texture so delete the
3275           * gallium texture now.  We'll make a new one below.
3276           */
3277          pipe_resource_reference(&tObj->pt, NULL);
3278          st_texture_release_all_sampler_views(st, tObj);
3279          ctx->NewDriverState |= ST_NEW_FRAMEBUFFER;
3280       }
3281    }
3282 
3283    /* May need to create a new gallium texture:
3284     */
3285    if (!tObj->pt && !tObj->NullTexture) {
3286       GLuint bindings = default_bindings(st, firstImageFormat);
3287 
3288       tObj->pt = st_texture_create(st,
3289                                     gl_target_to_pipe(tObj->Target),
3290                                     firstImageFormat,
3291                                     tObj->lastLevel,
3292                                     ptWidth,
3293                                     ptHeight,
3294                                     ptDepth,
3295                                     ptLayers, ptNumSamples,
3296                                     bindings,
3297                                     false,
3298                                     PIPE_COMPRESSION_FIXED_RATE_NONE);
3299 
3300       if (!tObj->pt) {
3301          _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
3302          return GL_FALSE;
3303       }
3304    }
3305 
3306    /* Pull in any images not in the object's texture:
3307     */
3308    for (face = 0; face < nr_faces; face++) {
3309       GLuint level;
3310       for (level = tObj->Attrib.BaseLevel; level <= tObj->lastLevel; level++) {
3311          struct gl_texture_image *stImage =
3312             tObj->Image[face][level];
3313 
3314          /* Need to import images in main memory or held in other textures.
3315           */
3316          if (stImage && !tObj->NullTexture && tObj->pt != stImage->pt) {
3317             GLuint height;
3318             GLuint depth;
3319 
3320             if (tObj->Target != GL_TEXTURE_1D_ARRAY)
3321                height = u_minify(ptHeight, level);
3322             else
3323                height = ptLayers;
3324 
3325             if (tObj->Target == GL_TEXTURE_3D)
3326                depth = u_minify(ptDepth, level);
3327             else if (tObj->Target == GL_TEXTURE_CUBE_MAP)
3328                depth = 1;
3329             else
3330                depth = ptLayers;
3331 
3332             if (level == 0 ||
3333                 (stImage->Width == u_minify(ptWidth, level) &&
3334                  stImage->Height == height &&
3335                  stImage->Depth == depth)) {
3336                /* src image fits expected dest mipmap level size */
3337                copy_image_data_to_texture(st, tObj, level, stImage);
3338             }
3339          }
3340       }
3341    }
3342 
3343    tObj->validated_first_level = tObj->Attrib.BaseLevel;
3344    tObj->validated_last_level = tObj->lastLevel;
3345    tObj->needs_validation = false;
3346 
3347    return GL_TRUE;
3348 }
3349 
3350 
3351 /**
3352  * Allocate a new pipe_resource object
3353  * width0, height0, depth0 are the dimensions of the level 0 image
3354  * (the highest resolution).  last_level indicates how many mipmap levels
3355  * to allocate storage for.  For non-mipmapped textures, this will be zero.
3356  */
3357 static struct pipe_resource *
st_texture_create_from_memory(struct st_context * st,struct gl_memory_object * memObj,GLuint64 offset,enum pipe_texture_target target,enum pipe_format format,GLuint last_level,GLuint width0,GLuint height0,GLuint depth0,GLuint layers,GLuint nr_samples,GLuint bind)3358 st_texture_create_from_memory(struct st_context *st,
3359                               struct gl_memory_object *memObj,
3360                               GLuint64 offset,
3361                               enum pipe_texture_target target,
3362                               enum pipe_format format,
3363                               GLuint last_level,
3364                               GLuint width0,
3365                               GLuint height0,
3366                               GLuint depth0,
3367                               GLuint layers,
3368                               GLuint nr_samples,
3369                               GLuint bind)
3370 {
3371    struct pipe_resource pt, *newtex;
3372    struct pipe_screen *screen = st->screen;
3373 
3374    assert(target < PIPE_MAX_TEXTURE_TYPES);
3375    assert(width0 > 0);
3376    assert(height0 > 0);
3377    assert(depth0 > 0);
3378    if (target == PIPE_TEXTURE_CUBE)
3379       assert(layers == 6);
3380 
3381    DBG("%s target %d format %s last_level %d\n", __func__,
3382        (int) target, util_format_name(format), last_level);
3383 
3384    assert(format);
3385    assert(screen->is_format_supported(screen, format, target, 0, 0,
3386                                       PIPE_BIND_SAMPLER_VIEW));
3387 
3388    memset(&pt, 0, sizeof(pt));
3389    pt.target = target;
3390    pt.format = format;
3391    pt.last_level = last_level;
3392    pt.width0 = width0;
3393    pt.height0 = height0;
3394    pt.depth0 = depth0;
3395    pt.array_size = layers;
3396    pt.usage = PIPE_USAGE_DEFAULT;
3397    pt.bind = bind;
3398    /* only set this for OpenGL textures, not renderbuffers */
3399    pt.flags = PIPE_RESOURCE_FLAG_TEXTURING_MORE_LIKELY;
3400    if (memObj->TextureTiling == GL_LINEAR_TILING_EXT) {
3401       pt.bind |= PIPE_BIND_LINEAR;
3402    } else if (memObj->TextureTiling == GL_CONST_BW_TILING_MESA) {
3403       pt.bind |= PIPE_BIND_CONST_BW;
3404    }
3405 
3406    pt.nr_samples = nr_samples;
3407    pt.nr_storage_samples = nr_samples;
3408 
3409    newtex = screen->resource_from_memobj(screen, &pt, memObj->memory, offset);
3410 
3411    assert(!newtex || pipe_is_referenced(&newtex->reference));
3412 
3413    return newtex;
3414 }
3415 
3416 
3417 /**
3418  * Allocate texture memory for a whole mipmap stack.
3419  * Note: for multisample textures if the requested sample count is not
3420  * supported, we search for the next higher supported sample count.
3421  */
3422 static GLboolean
st_texture_storage(struct gl_context * ctx,struct gl_texture_object * texObj,GLsizei levels,GLsizei width,GLsizei height,GLsizei depth,struct gl_memory_object * memObj,GLuint64 offset,const char * func)3423 st_texture_storage(struct gl_context *ctx,
3424                    struct gl_texture_object *texObj,
3425                    GLsizei levels, GLsizei width,
3426                    GLsizei height, GLsizei depth,
3427                    struct gl_memory_object *memObj,
3428                    GLuint64 offset, const char *func)
3429 {
3430    const GLuint numFaces = _mesa_num_tex_faces(texObj->Target);
3431    struct gl_texture_image *texImage = texObj->Image[0][0];
3432    struct st_context *st = st_context(ctx);
3433    struct pipe_screen *screen = st->screen;
3434    unsigned ptWidth, bindings;
3435    uint16_t ptHeight, ptDepth, ptLayers;
3436    enum pipe_format fmt;
3437    GLint level;
3438    GLuint num_samples = texImage->NumSamples;
3439 
3440    assert(levels > 0);
3441 
3442    texObj->lastLevel = levels - 1;
3443 
3444    fmt = st_mesa_format_to_pipe_format(st, texImage->TexFormat);
3445 
3446    bindings = default_bindings(st, fmt);
3447 
3448    if (memObj) {
3449       memObj->TextureTiling = texObj->TextureTiling;
3450       bindings |= PIPE_BIND_SHARED;
3451    }
3452 
3453    if (num_samples > 0) {
3454       /* Find msaa sample count which is actually supported.  For example,
3455        * if the user requests 1x but only 4x or 8x msaa is supported, we'll
3456        * choose 4x here.
3457        */
3458       enum pipe_texture_target ptarget = gl_target_to_pipe(texObj->Target);
3459       bool found = false;
3460 
3461       if (ctx->Const.MaxSamples > 1 && num_samples == 1) {
3462          /* don't try num_samples = 1 with drivers that support real msaa */
3463          num_samples = 2;
3464       }
3465 
3466       for (; num_samples <= ctx->Const.MaxSamples; num_samples++) {
3467          if (screen->is_format_supported(screen, fmt, ptarget,
3468                                          num_samples, num_samples,
3469                                          PIPE_BIND_SAMPLER_VIEW)) {
3470             /* Update the sample count in gl_texture_image as well. */
3471             texImage->NumSamples = num_samples;
3472             found = true;
3473             break;
3474          }
3475       }
3476 
3477       if (!found) {
3478          _mesa_error(st->ctx, GL_INVALID_OPERATION, "%s(format/samplecount not supported)", func);
3479          return GL_FALSE;
3480       }
3481    }
3482 
3483    st_gl_texture_dims_to_pipe_dims(texObj->Target,
3484                                    width, height, depth,
3485                                    &ptWidth, &ptHeight, &ptDepth, &ptLayers);
3486 
3487    pipe_resource_reference(&texObj->pt, NULL);
3488 
3489    if (memObj) {
3490       texObj->pt = st_texture_create_from_memory(st,
3491                                                 memObj,
3492                                                 offset,
3493                                                 gl_target_to_pipe(texObj->Target),
3494                                                 fmt,
3495                                                 levels - 1,
3496                                                 ptWidth,
3497                                                 ptHeight,
3498                                                 ptDepth,
3499                                                 ptLayers, num_samples,
3500                                                 bindings);
3501    }
3502    else {
3503       uint32_t rate = st_gl_compression_rate_to_pipe(texObj->CompressionRate);
3504       texObj->pt = st_texture_create(st,
3505                                     gl_target_to_pipe(texObj->Target),
3506                                     fmt,
3507                                     levels - 1,
3508                                     ptWidth,
3509                                     ptHeight,
3510                                     ptDepth,
3511                                     ptLayers, num_samples,
3512                                     bindings,
3513                                     texObj->IsSparse,
3514                                     rate);
3515    }
3516 
3517    if (!texObj->pt) {
3518       _mesa_error(st->ctx, GL_OUT_OF_MEMORY, "%s", func);
3519       return GL_FALSE;
3520    }
3521 
3522    /* Set image resource pointers */
3523    for (level = 0; level < levels; level++) {
3524       GLuint face;
3525       for (face = 0; face < numFaces; face++) {
3526          struct gl_texture_image *stImage =
3527             texObj->Image[face][level];
3528          pipe_resource_reference(&stImage->pt, texObj->pt);
3529 
3530          compressed_tex_fallback_allocate(st, stImage);
3531       }
3532    }
3533 
3534    /* Update gl_texture_object for texture parameter query. */
3535    texObj->NumSparseLevels = texObj->pt->nr_sparse_levels;
3536    texObj->CompressionRate =
3537       st_from_pipe_compression_rate(texObj->pt->compression_rate);
3538 
3539    /* The texture is in a validated state, so no need to check later. */
3540    texObj->needs_validation = false;
3541    texObj->validated_first_level = 0;
3542    texObj->validated_last_level = levels - 1;
3543 
3544    return GL_TRUE;
3545 }
3546 
3547 /**
3548  * Called via ctx->Driver.AllocTextureStorage() to allocate texture memory
3549  * for a whole mipmap stack.
3550  */
3551 GLboolean
st_AllocTextureStorage(struct gl_context * ctx,struct gl_texture_object * texObj,GLsizei levels,GLsizei width,GLsizei height,GLsizei depth,const char * func)3552 st_AllocTextureStorage(struct gl_context *ctx,
3553                        struct gl_texture_object *texObj,
3554                        GLsizei levels, GLsizei width,
3555                        GLsizei height, GLsizei depth,
3556                        const char *func)
3557 {
3558    return st_texture_storage(ctx, texObj, levels,
3559                              width, height, depth,
3560                              NULL, 0, func);
3561 }
3562 
3563 
3564 GLboolean
st_TestProxyTexImage(struct gl_context * ctx,GLenum target,GLuint numLevels,GLint level,mesa_format format,GLuint numSamples,GLint width,GLint height,GLint depth)3565 st_TestProxyTexImage(struct gl_context *ctx, GLenum target,
3566                      GLuint numLevels, GLint level,
3567                      mesa_format format, GLuint numSamples,
3568                      GLint width, GLint height, GLint depth)
3569 {
3570    struct st_context *st = st_context(ctx);
3571 
3572    if (width == 0 || height == 0 || depth == 0) {
3573       /* zero-sized images are legal, and always fit! */
3574       return GL_TRUE;
3575    }
3576 
3577    if (st->screen->can_create_resource) {
3578       /* Ask the gallium driver if the texture is too large */
3579       struct gl_texture_object *texObj =
3580          _mesa_get_current_tex_object(ctx, target);
3581       struct pipe_resource pt;
3582 
3583       /* Setup the pipe_resource object
3584        */
3585       memset(&pt, 0, sizeof(pt));
3586 
3587       pt.target = gl_target_to_pipe(target);
3588       pt.format = st_mesa_format_to_pipe_format(st, format);
3589       pt.nr_samples = numSamples;
3590       pt.nr_storage_samples = numSamples;
3591 
3592       st_gl_texture_dims_to_pipe_dims(target,
3593                                       width, height, depth,
3594                                       &pt.width0, &pt.height0,
3595                                       &pt.depth0, &pt.array_size);
3596 
3597       if (numLevels > 0) {
3598          /* For immutable textures we know the final number of mip levels */
3599          pt.last_level = numLevels - 1;
3600       }
3601       else if (level == 0 && (texObj->Sampler.Attrib.MinFilter == GL_LINEAR ||
3602                               texObj->Sampler.Attrib.MinFilter == GL_NEAREST)) {
3603          /* assume just one mipmap level */
3604          pt.last_level = 0;
3605       }
3606       else {
3607          /* assume a full set of mipmaps */
3608          pt.last_level = util_logbase2(MAX4(width, height, depth, 0));
3609       }
3610 
3611       return st->screen->can_create_resource(st->screen, &pt);
3612    }
3613    else {
3614       /* Use core Mesa fallback */
3615       return _mesa_test_proxy_teximage(ctx, target, numLevels, level, format,
3616                                        numSamples, width, height, depth);
3617    }
3618 }
3619 
3620 GLboolean
st_TextureView(struct gl_context * ctx,struct gl_texture_object * texObj,struct gl_texture_object * origTexObj)3621 st_TextureView(struct gl_context *ctx,
3622                struct gl_texture_object *texObj,
3623                struct gl_texture_object *origTexObj)
3624 {
3625    struct st_context *st = st_context(ctx);
3626    struct gl_texture_object *orig = origTexObj;
3627    struct gl_texture_object *tex = texObj;
3628    struct gl_texture_image *image = texObj->Image[0][0];
3629 
3630    const int numFaces = _mesa_num_tex_faces(texObj->Target);
3631    const int numLevels = texObj->Attrib.NumLevels;
3632 
3633    int face;
3634    int level;
3635 
3636    pipe_resource_reference(&tex->pt, orig->pt);
3637 
3638    /* Set image resource pointers */
3639    for (level = 0; level < numLevels; level++) {
3640       for (face = 0; face < numFaces; face++) {
3641          struct gl_texture_image *stImage =
3642             texObj->Image[face][level];
3643          struct gl_texture_image *origImage =
3644             origTexObj->Image[face][level];
3645          pipe_resource_reference(&stImage->pt, tex->pt);
3646          if (origImage &&
3647              origImage->compressed_data) {
3648             pipe_reference(NULL,
3649                            &origImage->compressed_data->reference);
3650             stImage->compressed_data = origImage->compressed_data;
3651          }
3652       }
3653    }
3654 
3655    tex->surface_based = GL_TRUE;
3656    tex->surface_format =
3657       st_mesa_format_to_pipe_format(st_context(ctx), image->TexFormat);
3658 
3659    tex->lastLevel = numLevels - 1;
3660 
3661    /* free texture sampler views.  They need to be recreated when we
3662     * change the texture view parameters.
3663     */
3664    st_texture_release_all_sampler_views(st, tex);
3665 
3666    /* The texture is in a validated state, so no need to check later. */
3667    tex->needs_validation = false;
3668    tex->validated_first_level = 0;
3669    tex->validated_last_level = numLevels - 1;
3670 
3671    return GL_TRUE;
3672 }
3673 
3674 
3675 /**
3676  * Find the mipmap level in 'pt' which matches the level described by
3677  * 'texImage'.
3678  */
3679 static unsigned
find_mipmap_level(const struct gl_texture_image * texImage,const struct pipe_resource * pt)3680 find_mipmap_level(const struct gl_texture_image *texImage,
3681                   const struct pipe_resource *pt)
3682 {
3683    const GLenum target = texImage->TexObject->Target;
3684    GLint texWidth = texImage->Width;
3685    GLint texHeight = texImage->Height;
3686    GLint texDepth = texImage->Depth;
3687    unsigned level, w;
3688    uint16_t h, d, layers;
3689 
3690    st_gl_texture_dims_to_pipe_dims(target, texWidth, texHeight, texDepth,
3691                                    &w, &h, &d, &layers);
3692 
3693    for (level = 0; level <= pt->last_level; level++) {
3694       if (u_minify(pt->width0, level) == w &&
3695           u_minify(pt->height0, level) == h &&
3696           u_minify(pt->depth0, level) == d) {
3697          return level;
3698       }
3699    }
3700 
3701    /* If we get here, there must be some sort of inconsistency between
3702     * the Mesa texture object/images and the gallium resource.
3703     */
3704    debug_printf("Inconsistent textures in find_mipmap_level()\n");
3705 
3706    return texImage->Level;
3707 }
3708 
3709 
3710 void
st_ClearTexSubImage(struct gl_context * ctx,struct gl_texture_image * texImage,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,const void * clearValue)3711 st_ClearTexSubImage(struct gl_context *ctx,
3712                     struct gl_texture_image *texImage,
3713                     GLint xoffset, GLint yoffset, GLint zoffset,
3714                     GLsizei width, GLsizei height, GLsizei depth,
3715                     const void *clearValue)
3716 {
3717    static const char zeros[16] = {0};
3718    struct gl_texture_object *texObj = texImage->TexObject;
3719    struct gl_texture_image *stImage = texImage;
3720    struct pipe_resource *pt = stImage->pt;
3721    struct st_context *st = st_context(ctx);
3722    struct pipe_context *pipe = st->pipe;
3723    unsigned level;
3724    struct pipe_box box;
3725 
3726    if (!pt)
3727       return;
3728 
3729    st_flush_bitmap_cache(st);
3730    st_invalidate_readpix_cache(st);
3731 
3732    u_box_3d(xoffset, yoffset, zoffset + texImage->Face,
3733             width, height, depth, &box);
3734 
3735    if (pt->target == PIPE_TEXTURE_1D_ARRAY) {
3736       box.z = box.y;
3737       box.depth = box.height;
3738       box.y = 0;
3739       box.height = 1;
3740    }
3741 
3742    if (texObj->Immutable) {
3743       /* The texture object has to be consistent (no "loose", per-image
3744        * gallium resources).  If this texture is a view into another
3745        * texture, we have to apply the MinLevel/Layer offsets.  If this is
3746        * not a texture view, the offsets will be zero.
3747        */
3748       assert(stImage->pt == texObj->pt);
3749       level = texImage->Level + texObj->Attrib.MinLevel;
3750       box.z += texObj->Attrib.MinLayer;
3751    }
3752    else {
3753       /* Texture level sizes may be inconsistent.  We my have "loose",
3754        * per-image gallium resources.  The texImage->Level may not match
3755        * the gallium resource texture level.
3756        */
3757       level = find_mipmap_level(texImage, pt);
3758    }
3759 
3760    assert(level <= pt->last_level);
3761 
3762    if (pipe->clear_texture) {
3763       pipe->clear_texture(pipe, pt, level, &box,
3764                           clearValue ? clearValue : zeros);
3765    } else {
3766       u_default_clear_texture(pipe, pt, level, &box,
3767                               clearValue ? clearValue : zeros);
3768    }
3769 }
3770 
3771 
3772 GLboolean
st_SetTextureStorageForMemoryObject(struct gl_context * ctx,struct gl_texture_object * texObj,struct gl_memory_object * memObj,GLsizei levels,GLsizei width,GLsizei height,GLsizei depth,GLuint64 offset,const char * func)3773 st_SetTextureStorageForMemoryObject(struct gl_context *ctx,
3774                                     struct gl_texture_object *texObj,
3775                                     struct gl_memory_object *memObj,
3776                                     GLsizei levels, GLsizei width,
3777                                     GLsizei height, GLsizei depth,
3778                                     GLuint64 offset, const char *func)
3779 {
3780    return st_texture_storage(ctx, texObj, levels,
3781                              width, height, depth,
3782                              memObj, offset, func);
3783 }
3784 
3785 GLboolean
st_GetSparseTextureVirtualPageSize(struct gl_context * ctx,GLenum target,mesa_format format,unsigned index,int * x,int * y,int * z)3786 st_GetSparseTextureVirtualPageSize(struct gl_context *ctx,
3787                                    GLenum target, mesa_format format,
3788                                    unsigned index, int *x, int *y, int *z)
3789 {
3790    struct st_context *st = st_context(ctx);
3791    struct pipe_screen *screen = st->screen;
3792    enum pipe_texture_target ptarget = gl_target_to_pipe(target);
3793    enum pipe_format pformat = st_mesa_format_to_pipe_format(st, format);
3794    bool multi_sample = _mesa_is_multisample_target(target);
3795 
3796    /* Get an XYZ page size combination specified by index. */
3797    return !!screen->get_sparse_texture_virtual_page_size(
3798       screen, ptarget, multi_sample, pformat, index, 1, x, y, z);
3799 }
3800 
3801 void
st_TexturePageCommitment(struct gl_context * ctx,struct gl_texture_object * tex_obj,int level,int xoffset,int yoffset,int zoffset,int width,int height,int depth,bool commit)3802 st_TexturePageCommitment(struct gl_context *ctx,
3803                          struct gl_texture_object *tex_obj,
3804                          int level, int xoffset, int yoffset, int zoffset,
3805                          int width, int height, int depth, bool commit)
3806 {
3807    struct st_context *st = st_context(ctx);
3808    struct pipe_context *pipe = st->pipe;
3809    struct pipe_box box;
3810 
3811    u_box_3d(xoffset, yoffset, zoffset, width, height, depth, &box);
3812 
3813    if (!pipe->resource_commit(pipe, tex_obj->pt, level, &box, commit)) {
3814       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexPageCommitmentARB(out of memory)");
3815       return;
3816    }
3817 }
3818