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