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