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