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