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