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