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