st/mesa: don't expose ARB_color_buffer_float without driver support in GL core
[mesa.git] / src / mesa / state_tracker / st_cb_texture.c
1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
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 TUNGSTEN GRAPHICS 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 "main/mfeatures.h"
29 #include "main/bufferobj.h"
30 #include "main/enums.h"
31 #include "main/fbobject.h"
32 #include "main/formats.h"
33 #include "main/image.h"
34 #include "main/imports.h"
35 #include "main/macros.h"
36 #include "main/mipmap.h"
37 #include "main/pack.h"
38 #include "main/pbo.h"
39 #include "main/pixeltransfer.h"
40 #include "main/texcompress.h"
41 #include "main/texgetimage.h"
42 #include "main/teximage.h"
43 #include "main/texobj.h"
44 #include "main/texstore.h"
45
46 #include "state_tracker/st_debug.h"
47 #include "state_tracker/st_context.h"
48 #include "state_tracker/st_cb_fbo.h"
49 #include "state_tracker/st_cb_flush.h"
50 #include "state_tracker/st_cb_texture.h"
51 #include "state_tracker/st_cb_bufferobjects.h"
52 #include "state_tracker/st_format.h"
53 #include "state_tracker/st_texture.h"
54 #include "state_tracker/st_gen_mipmap.h"
55 #include "state_tracker/st_atom.h"
56
57 #include "pipe/p_context.h"
58 #include "pipe/p_defines.h"
59 #include "util/u_inlines.h"
60 #include "pipe/p_shader_tokens.h"
61 #include "util/u_tile.h"
62 #include "util/u_format.h"
63 #include "util/u_surface.h"
64 #include "util/u_sampler.h"
65 #include "util/u_math.h"
66 #include "util/u_box.h"
67
68 #define DBG if (0) printf
69
70
71 enum pipe_texture_target
72 gl_target_to_pipe(GLenum target)
73 {
74 switch (target) {
75 case GL_TEXTURE_1D:
76 case GL_PROXY_TEXTURE_1D:
77 return PIPE_TEXTURE_1D;
78 case GL_TEXTURE_2D:
79 case GL_PROXY_TEXTURE_2D:
80 case GL_TEXTURE_EXTERNAL_OES:
81 return PIPE_TEXTURE_2D;
82 case GL_TEXTURE_RECTANGLE_NV:
83 case GL_PROXY_TEXTURE_RECTANGLE_NV:
84 return PIPE_TEXTURE_RECT;
85 case GL_TEXTURE_3D:
86 case GL_PROXY_TEXTURE_3D:
87 return PIPE_TEXTURE_3D;
88 case GL_TEXTURE_CUBE_MAP_ARB:
89 case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
90 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
91 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
92 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
93 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
94 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
95 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
96 return PIPE_TEXTURE_CUBE;
97 case GL_TEXTURE_1D_ARRAY_EXT:
98 case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
99 return PIPE_TEXTURE_1D_ARRAY;
100 case GL_TEXTURE_2D_ARRAY_EXT:
101 case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
102 return PIPE_TEXTURE_2D_ARRAY;
103 case GL_TEXTURE_BUFFER:
104 return PIPE_BUFFER;
105 case GL_TEXTURE_CUBE_MAP_ARRAY:
106 case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
107 return PIPE_TEXTURE_CUBE_ARRAY;
108 default:
109 assert(0);
110 return 0;
111 }
112 }
113
114
115 /** called via ctx->Driver.NewTextureImage() */
116 static struct gl_texture_image *
117 st_NewTextureImage(struct gl_context * ctx)
118 {
119 DBG("%s\n", __FUNCTION__);
120 (void) ctx;
121 return (struct gl_texture_image *) ST_CALLOC_STRUCT(st_texture_image);
122 }
123
124
125 /** called via ctx->Driver.DeleteTextureImage() */
126 static void
127 st_DeleteTextureImage(struct gl_context * ctx, struct gl_texture_image *img)
128 {
129 /* nothing special (yet) for st_texture_image */
130 _mesa_delete_texture_image(ctx, img);
131 }
132
133
134 /** called via ctx->Driver.NewTextureObject() */
135 static struct gl_texture_object *
136 st_NewTextureObject(struct gl_context * ctx, GLuint name, GLenum target)
137 {
138 struct st_texture_object *obj = ST_CALLOC_STRUCT(st_texture_object);
139
140 DBG("%s\n", __FUNCTION__);
141 _mesa_initialize_texture_object(&obj->base, name, target);
142
143 return &obj->base;
144 }
145
146 /** called via ctx->Driver.DeleteTextureObject() */
147 static void
148 st_DeleteTextureObject(struct gl_context *ctx,
149 struct gl_texture_object *texObj)
150 {
151 struct st_context *st = st_context(ctx);
152 struct st_texture_object *stObj = st_texture_object(texObj);
153 if (stObj->pt)
154 pipe_resource_reference(&stObj->pt, NULL);
155 if (stObj->sampler_view) {
156 pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
157 }
158 _mesa_delete_texture_object(ctx, texObj);
159 }
160
161
162 /** called via ctx->Driver.FreeTextureImageBuffer() */
163 static void
164 st_FreeTextureImageBuffer(struct gl_context *ctx,
165 struct gl_texture_image *texImage)
166 {
167 struct st_texture_image *stImage = st_texture_image(texImage);
168
169 DBG("%s\n", __FUNCTION__);
170
171 if (stImage->pt) {
172 pipe_resource_reference(&stImage->pt, NULL);
173 }
174
175 if (stImage->TexData) {
176 _mesa_align_free(stImage->TexData);
177 stImage->TexData = NULL;
178 }
179 }
180
181
182 /** called via ctx->Driver.MapTextureImage() */
183 static void
184 st_MapTextureImage(struct gl_context *ctx,
185 struct gl_texture_image *texImage,
186 GLuint slice, GLuint x, GLuint y, GLuint w, GLuint h,
187 GLbitfield mode,
188 GLubyte **mapOut, GLint *rowStrideOut)
189 {
190 struct st_context *st = st_context(ctx);
191 struct st_texture_image *stImage = st_texture_image(texImage);
192 unsigned pipeMode;
193 GLubyte *map;
194
195 pipeMode = 0x0;
196 if (mode & GL_MAP_READ_BIT)
197 pipeMode |= PIPE_TRANSFER_READ;
198 if (mode & GL_MAP_WRITE_BIT)
199 pipeMode |= PIPE_TRANSFER_WRITE;
200 if (mode & GL_MAP_INVALIDATE_RANGE_BIT)
201 pipeMode |= PIPE_TRANSFER_DISCARD_RANGE;
202
203 map = st_texture_image_map(st, stImage, pipeMode, x, y, slice, w, h, 1);
204 if (map) {
205 *mapOut = map;
206 *rowStrideOut = stImage->transfer->stride;
207 }
208 else {
209 *mapOut = NULL;
210 *rowStrideOut = 0;
211 }
212 }
213
214
215 /** called via ctx->Driver.UnmapTextureImage() */
216 static void
217 st_UnmapTextureImage(struct gl_context *ctx,
218 struct gl_texture_image *texImage,
219 GLuint slice)
220 {
221 struct st_context *st = st_context(ctx);
222 struct st_texture_image *stImage = st_texture_image(texImage);
223 st_texture_image_unmap(st, stImage);
224 }
225
226
227 /**
228 * Return default texture resource binding bitmask for the given format.
229 */
230 static GLuint
231 default_bindings(struct st_context *st, enum pipe_format format)
232 {
233 struct pipe_screen *screen = st->pipe->screen;
234 const unsigned target = PIPE_TEXTURE_2D;
235 unsigned bindings;
236
237 if (util_format_is_depth_or_stencil(format))
238 bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_DEPTH_STENCIL;
239 else
240 bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
241
242 if (screen->is_format_supported(screen, format, target, 0, bindings))
243 return bindings;
244 else {
245 /* Try non-sRGB. */
246 format = util_format_linear(format);
247
248 if (screen->is_format_supported(screen, format, target, 0, bindings))
249 return bindings;
250 else
251 return PIPE_BIND_SAMPLER_VIEW;
252 }
253 }
254
255
256 /**
257 * Given the size of a mipmap image, try to compute the size of the level=0
258 * mipmap image.
259 *
260 * Note that this isn't always accurate for odd-sized, non-POW textures.
261 * For example, if level=1 and width=40 then the level=0 width may be 80 or 81.
262 *
263 * \return GL_TRUE for success, GL_FALSE for failure
264 */
265 static GLboolean
266 guess_base_level_size(GLenum target,
267 GLuint width, GLuint height, GLuint depth, GLuint level,
268 GLuint *width0, GLuint *height0, GLuint *depth0)
269 {
270 assert(width >= 1);
271 assert(height >= 1);
272 assert(depth >= 1);
273
274 if (level > 0) {
275 /* Guess the size of the base level.
276 * Depending on the image's size, we can't always make a guess here.
277 */
278 switch (target) {
279 case GL_TEXTURE_1D:
280 case GL_TEXTURE_1D_ARRAY:
281 width <<= level;
282 break;
283
284 case GL_TEXTURE_2D:
285 case GL_TEXTURE_2D_ARRAY:
286 /* We can't make a good guess here, because the base level dimensions
287 * can be non-square.
288 */
289 if (width == 1 || height == 1) {
290 return GL_FALSE;
291 }
292 width <<= level;
293 height <<= level;
294 break;
295
296 case GL_TEXTURE_CUBE_MAP:
297 case GL_TEXTURE_CUBE_MAP_ARRAY:
298 width <<= level;
299 height <<= level;
300 break;
301
302 case GL_TEXTURE_3D:
303 /* We can't make a good guess here, because the base level dimensions
304 * can be non-cube.
305 */
306 if (width == 1 || height == 1 || depth == 1) {
307 return GL_FALSE;
308 }
309 width <<= level;
310 height <<= level;
311 depth <<= level;
312 break;
313
314 case GL_TEXTURE_RECTANGLE:
315 break;
316
317 default:
318 assert(0);
319 }
320 }
321
322 *width0 = width;
323 *height0 = height;
324 *depth0 = depth;
325
326 return GL_TRUE;
327 }
328
329
330 /**
331 * Try to allocate a pipe_resource object for the given st_texture_object.
332 *
333 * We use the given st_texture_image as a clue to determine the size of the
334 * mipmap image at level=0.
335 *
336 * \return GL_TRUE for success, GL_FALSE if out of memory.
337 */
338 static GLboolean
339 guess_and_alloc_texture(struct st_context *st,
340 struct st_texture_object *stObj,
341 const struct st_texture_image *stImage)
342 {
343 GLuint lastLevel, width, height, depth;
344 GLuint bindings;
345 GLuint ptWidth, ptHeight, ptDepth, ptLayers;
346 enum pipe_format fmt;
347
348 DBG("%s\n", __FUNCTION__);
349
350 assert(!stObj->pt);
351
352 if (!guess_base_level_size(stObj->base.Target,
353 stImage->base.Width2,
354 stImage->base.Height2,
355 stImage->base.Depth2,
356 stImage->base.Level,
357 &width, &height, &depth)) {
358 /* we can't determine the image size at level=0 */
359 stObj->width0 = stObj->height0 = stObj->depth0 = 0;
360 /* this is not an out of memory error */
361 return GL_TRUE;
362 }
363
364 /* At this point, (width x height x depth) is the expected size of
365 * the level=0 mipmap image.
366 */
367
368 /* Guess a reasonable value for lastLevel. With OpenGL we have no
369 * idea how many mipmap levels will be in a texture until we start
370 * to render with it. Make an educated guess here but be prepared
371 * to re-allocating a texture buffer with space for more (or fewer)
372 * mipmap levels later.
373 */
374 if ((stObj->base.Sampler.MinFilter == GL_NEAREST ||
375 stObj->base.Sampler.MinFilter == GL_LINEAR ||
376 (stObj->base.BaseLevel == 0 &&
377 stObj->base.MaxLevel == 0) ||
378 stImage->base._BaseFormat == GL_DEPTH_COMPONENT ||
379 stImage->base._BaseFormat == GL_DEPTH_STENCIL_EXT) &&
380 !stObj->base.GenerateMipmap &&
381 stImage->base.Level == 0) {
382 /* only alloc space for a single mipmap level */
383 lastLevel = 0;
384 }
385 else {
386 /* alloc space for a full mipmap */
387 lastLevel = _mesa_get_tex_max_num_levels(stObj->base.Target,
388 width, height, depth) - 1;
389 }
390
391 /* Save the level=0 dimensions */
392 stObj->width0 = width;
393 stObj->height0 = height;
394 stObj->depth0 = depth;
395
396 fmt = st_mesa_format_to_pipe_format(stImage->base.TexFormat);
397
398 bindings = default_bindings(st, fmt);
399
400 st_gl_texture_dims_to_pipe_dims(stObj->base.Target,
401 width, height, depth,
402 &ptWidth, &ptHeight, &ptDepth, &ptLayers);
403
404 stObj->pt = st_texture_create(st,
405 gl_target_to_pipe(stObj->base.Target),
406 fmt,
407 lastLevel,
408 ptWidth,
409 ptHeight,
410 ptDepth,
411 ptLayers,
412 bindings);
413
414 stObj->lastLevel = lastLevel;
415
416 DBG("%s returning %d\n", __FUNCTION__, (stObj->pt != NULL));
417
418 return stObj->pt != NULL;
419 }
420
421
422 /**
423 * Called via ctx->Driver.AllocTextureImageBuffer().
424 * If the texture object/buffer already has space for the indicated image,
425 * we're done. Otherwise, allocate memory for the new texture image.
426 */
427 static GLboolean
428 st_AllocTextureImageBuffer(struct gl_context *ctx,
429 struct gl_texture_image *texImage)
430 {
431 struct st_context *st = st_context(ctx);
432 struct st_texture_image *stImage = st_texture_image(texImage);
433 struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
434 const GLuint level = texImage->Level;
435 GLuint width = texImage->Width;
436 GLuint height = texImage->Height;
437 GLuint depth = texImage->Depth;
438
439 DBG("%s\n", __FUNCTION__);
440
441 assert(!stImage->TexData);
442 assert(!stImage->pt); /* xxx this might be wrong */
443
444 /* Look if the parent texture object has space for this image */
445 if (stObj->pt &&
446 level <= stObj->pt->last_level &&
447 st_texture_match_image(stObj->pt, texImage)) {
448 /* this image will fit in the existing texture object's memory */
449 pipe_resource_reference(&stImage->pt, stObj->pt);
450 return GL_TRUE;
451 }
452
453 /* The parent texture object does not have space for this image */
454
455 pipe_resource_reference(&stObj->pt, NULL);
456 pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
457
458 if (!guess_and_alloc_texture(st, stObj, stImage)) {
459 /* Probably out of memory.
460 * Try flushing any pending rendering, then retry.
461 */
462 st_finish(st);
463 if (!guess_and_alloc_texture(st, stObj, stImage)) {
464 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
465 return GL_FALSE;
466 }
467 }
468
469 if (stObj->pt &&
470 st_texture_match_image(stObj->pt, texImage)) {
471 /* The image will live in the object's mipmap memory */
472 pipe_resource_reference(&stImage->pt, stObj->pt);
473 assert(stImage->pt);
474 return GL_TRUE;
475 }
476 else {
477 /* Create a new, temporary texture/resource/buffer to hold this
478 * one texture image. Note that when we later access this image
479 * (either for mapping or copying) we'll want to always specify
480 * mipmap level=0, even if the image represents some other mipmap
481 * level.
482 */
483 enum pipe_format format =
484 st_mesa_format_to_pipe_format(texImage->TexFormat);
485 GLuint bindings = default_bindings(st, format);
486 GLuint ptWidth, ptHeight, ptDepth, ptLayers;
487
488 st_gl_texture_dims_to_pipe_dims(stObj->base.Target,
489 width, height, depth,
490 &ptWidth, &ptHeight, &ptDepth, &ptLayers);
491
492 stImage->pt = st_texture_create(st,
493 gl_target_to_pipe(stObj->base.Target),
494 format,
495 0, /* lastLevel */
496 ptWidth,
497 ptHeight,
498 ptDepth,
499 ptLayers,
500 bindings);
501 return stImage->pt != NULL;
502 }
503 }
504
505
506 /**
507 * Preparation prior to glTexImage. Basically check the 'surface_based'
508 * field and switch to a "normal" tex image if necessary.
509 */
510 static void
511 prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage,
512 GLenum format, GLenum type)
513 {
514 struct gl_texture_object *texObj = texImage->TexObject;
515 struct st_texture_object *stObj = st_texture_object(texObj);
516
517 /* switch to "normal" */
518 if (stObj->surface_based) {
519 const GLenum target = texObj->Target;
520 const GLuint level = texImage->Level;
521 gl_format texFormat;
522
523 _mesa_clear_texture_object(ctx, texObj);
524 pipe_resource_reference(&stObj->pt, NULL);
525
526 /* oops, need to init this image again */
527 texFormat = _mesa_choose_texture_format(ctx, texObj, target, level,
528 texImage->InternalFormat, format,
529 type);
530
531 _mesa_init_teximage_fields(ctx, texImage,
532 texImage->Width, texImage->Height,
533 texImage->Depth, texImage->Border,
534 texImage->InternalFormat, texFormat);
535
536 stObj->surface_based = GL_FALSE;
537 }
538 }
539
540
541 /**
542 * Return a writemask for the gallium blit. The parameters can be base
543 * formats or "format" from glDrawPixels/glTexImage/glGetTexImage.
544 */
545 unsigned
546 st_get_blit_mask(GLenum srcFormat, GLenum dstFormat)
547 {
548 switch (dstFormat) {
549 case GL_DEPTH_STENCIL:
550 switch (srcFormat) {
551 case GL_DEPTH_STENCIL:
552 return PIPE_MASK_ZS;
553 case GL_DEPTH_COMPONENT:
554 return PIPE_MASK_Z;
555 case GL_STENCIL_INDEX:
556 return PIPE_MASK_S;
557 default:
558 assert(0);
559 return 0;
560 }
561
562 case GL_DEPTH_COMPONENT:
563 switch (srcFormat) {
564 case GL_DEPTH_STENCIL:
565 case GL_DEPTH_COMPONENT:
566 return PIPE_MASK_Z;
567 default:
568 assert(0);
569 return 0;
570 }
571
572 case GL_STENCIL_INDEX:
573 switch (srcFormat) {
574 case GL_STENCIL_INDEX:
575 return PIPE_MASK_S;
576 default:
577 assert(0);
578 return 0;
579 }
580
581 default:
582 return PIPE_MASK_RGBA;
583 }
584 }
585
586
587 static void
588 st_TexSubImage(struct gl_context *ctx, GLuint dims,
589 struct gl_texture_image *texImage,
590 GLint xoffset, GLint yoffset, GLint zoffset,
591 GLint width, GLint height, GLint depth,
592 GLenum format, GLenum type, const void *pixels,
593 const struct gl_pixelstore_attrib *unpack)
594 {
595 struct st_context *st = st_context(ctx);
596 struct st_texture_image *stImage = st_texture_image(texImage);
597 struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
598 struct pipe_context *pipe = st->pipe;
599 struct pipe_screen *screen = pipe->screen;
600 struct pipe_resource *dst = stImage->pt;
601 struct pipe_resource *src = NULL;
602 struct pipe_resource src_templ;
603 struct pipe_transfer *transfer;
604 struct pipe_blit_info blit;
605 enum pipe_format src_format, dst_format;
606 gl_format mesa_src_format;
607 GLenum gl_target = texImage->TexObject->Target;
608 unsigned bind;
609 GLubyte *map;
610
611 if (!st->prefer_blit_based_texture_transfer) {
612 goto fallback;
613 }
614
615 if (!dst) {
616 goto fallback;
617 }
618
619 /* XXX Fallback for depth-stencil formats due to an incomplete stencil
620 * blit implementation in some drivers. */
621 if (format == GL_DEPTH_STENCIL) {
622 goto fallback;
623 }
624
625 /* If the base internal format and the texture format don't match,
626 * we can't use blit-based TexSubImage. */
627 if (texImage->_BaseFormat !=
628 _mesa_get_format_base_format(texImage->TexFormat)) {
629 goto fallback;
630 }
631
632 /* See if the texture format already matches the format and type,
633 * in which case the memcpy-based fast path will likely be used and
634 * we don't have to blit. */
635 if (_mesa_format_matches_format_and_type(texImage->TexFormat, format,
636 type, unpack->SwapBytes)) {
637 goto fallback;
638 }
639
640 if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL)
641 bind = PIPE_BIND_DEPTH_STENCIL;
642 else
643 bind = PIPE_BIND_RENDER_TARGET;
644
645 /* See if the destination format is supported.
646 * For luminance and intensity, only the red channel is stored there. */
647 dst_format = util_format_linear(dst->format);
648 dst_format = util_format_luminance_to_red(dst_format);
649 dst_format = util_format_intensity_to_red(dst_format);
650
651 if (!dst_format ||
652 !screen->is_format_supported(screen, dst_format, dst->target,
653 dst->nr_samples, bind)) {
654 goto fallback;
655 }
656
657 /* Choose the source format. */
658 src_format = st_choose_matching_format(screen, PIPE_BIND_SAMPLER_VIEW,
659 format, type, unpack->SwapBytes);
660 if (!src_format) {
661 goto fallback;
662 }
663
664 mesa_src_format = st_pipe_format_to_mesa_format(src_format);
665
666 /* There is no reason to do this if we cannot use memcpy for the temporary
667 * source texture at least. This also takes transfer ops into account,
668 * etc. */
669 if (!_mesa_texstore_can_use_memcpy(ctx,
670 _mesa_get_format_base_format(mesa_src_format),
671 mesa_src_format, format, type, unpack)) {
672 goto fallback;
673 }
674
675 /* TexSubImage only sets a single cubemap face. */
676 if (gl_target == GL_TEXTURE_CUBE_MAP) {
677 gl_target = GL_TEXTURE_2D;
678 }
679
680 /* Initialize the source texture description. */
681 memset(&src_templ, 0, sizeof(src_templ));
682 src_templ.target = gl_target_to_pipe(gl_target);
683 src_templ.format = src_format;
684 src_templ.bind = PIPE_BIND_SAMPLER_VIEW;
685 src_templ.usage = PIPE_USAGE_STAGING;
686
687 st_gl_texture_dims_to_pipe_dims(gl_target, width, height, depth,
688 &src_templ.width0, &src_templ.height0,
689 &src_templ.depth0, &src_templ.array_size);
690
691 /* Check for NPOT texture support. */
692 if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES) &&
693 (!util_is_power_of_two(src_templ.width0) ||
694 !util_is_power_of_two(src_templ.height0) ||
695 !util_is_power_of_two(src_templ.depth0))) {
696 goto fallback;
697 }
698
699 /* Create the source texture. */
700 src = screen->resource_create(screen, &src_templ);
701 if (!src) {
702 goto fallback;
703 }
704
705 /* Map source pixels. */
706 pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
707 format, type, pixels, unpack,
708 "glTexSubImage");
709 if (!pixels) {
710 /* This is a GL error. */
711 pipe_resource_reference(&src, NULL);
712 return;
713 }
714
715 /* From now on, we need the gallium representation of dimensions. */
716 if (gl_target == GL_TEXTURE_1D_ARRAY) {
717 depth = height;
718 height = 1;
719 }
720
721 map = pipe_transfer_map_3d(pipe, src, 0, PIPE_TRANSFER_WRITE, 0, 0, 0,
722 width, height, depth, &transfer);
723 if (!map) {
724 _mesa_unmap_teximage_pbo(ctx, unpack);
725 pipe_resource_reference(&src, NULL);
726 goto fallback;
727 }
728
729 /* Upload pixels (just memcpy). */
730 {
731 const uint bytesPerRow = width * util_format_get_blocksize(src_format);
732 GLuint row, slice;
733
734 for (slice = 0; slice < depth; slice++) {
735 if (gl_target == GL_TEXTURE_1D_ARRAY) {
736 /* 1D array textures.
737 * We need to convert gallium coords to GL coords.
738 */
739 GLvoid *src = _mesa_image_address3d(unpack, pixels,
740 width, depth, format,
741 type, 0, slice, 0);
742 memcpy(map, src, bytesPerRow);
743 }
744 else {
745 ubyte *slice_map = map;
746
747 for (row = 0; row < height; row++) {
748 GLvoid *src = _mesa_image_address3d(unpack, pixels,
749 width, height, format,
750 type, slice, row, 0);
751 memcpy(slice_map, src, bytesPerRow);
752 slice_map += transfer->stride;
753 }
754 }
755 map += transfer->layer_stride;
756 }
757 }
758
759 pipe_transfer_unmap(pipe, transfer);
760 _mesa_unmap_teximage_pbo(ctx, unpack);
761
762 /* Blit. */
763 blit.src.resource = src;
764 blit.src.level = 0;
765 blit.src.format = src_format;
766 blit.dst.resource = dst;
767 blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->Level;
768 blit.dst.format = dst_format;
769 blit.src.box.x = blit.src.box.y = blit.src.box.z = 0;
770 blit.dst.box.x = xoffset;
771 blit.dst.box.y = yoffset;
772 blit.dst.box.z = zoffset + texImage->Face;
773 blit.src.box.width = blit.dst.box.width = width;
774 blit.src.box.height = blit.dst.box.height = height;
775 blit.src.box.depth = blit.dst.box.depth = depth;
776 blit.mask = st_get_blit_mask(format, texImage->_BaseFormat);
777 blit.filter = PIPE_TEX_FILTER_NEAREST;
778 blit.scissor_enable = FALSE;
779
780 st->pipe->blit(st->pipe, &blit);
781
782 pipe_resource_reference(&src, NULL);
783 return;
784
785 fallback:
786 _mesa_store_texsubimage(ctx, dims, texImage, xoffset, yoffset, zoffset,
787 width, height, depth, format, type, pixels,
788 unpack);
789 }
790
791 static void
792 st_TexImage(struct gl_context * ctx, GLuint dims,
793 struct gl_texture_image *texImage,
794 GLenum format, GLenum type, const void *pixels,
795 const struct gl_pixelstore_attrib *unpack)
796 {
797 assert(dims == 1 || dims == 2 || dims == 3);
798
799 prep_teximage(ctx, texImage, format, type);
800
801 if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0)
802 return;
803
804 /* allocate storage for texture data */
805 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
806 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
807 return;
808 }
809
810 st_TexSubImage(ctx, dims, texImage, 0, 0, 0,
811 texImage->Width, texImage->Height, texImage->Depth,
812 format, type, pixels, unpack);
813 }
814
815
816 static void
817 st_CompressedTexImage(struct gl_context *ctx, GLuint dims,
818 struct gl_texture_image *texImage,
819 GLsizei imageSize, const GLvoid *data)
820 {
821 prep_teximage(ctx, texImage, GL_NONE, GL_NONE);
822 _mesa_store_compressed_teximage(ctx, dims, texImage, imageSize, data);
823 }
824
825
826
827
828 /**
829 * Called via ctx->Driver.GetTexImage()
830 *
831 * This uses a blit to copy the texture to a texture format which matches
832 * the format and type combo and then a fast read-back is done using memcpy.
833 * We can do arbitrary X/Y/Z/W/0/1 swizzling here as long as there is
834 * a format which matches the swizzling.
835 *
836 * If such a format isn't available, it falls back to _mesa_get_teximage.
837 *
838 * NOTE: Drivers usually do a blit to convert between tiled and linear
839 * texture layouts during texture uploads/downloads, so the blit
840 * we do here should be free in such cases.
841 */
842 static void
843 st_GetTexImage(struct gl_context * ctx,
844 GLenum format, GLenum type, GLvoid * pixels,
845 struct gl_texture_image *texImage)
846 {
847 struct st_context *st = st_context(ctx);
848 struct pipe_context *pipe = st->pipe;
849 struct pipe_screen *screen = pipe->screen;
850 GLuint width = texImage->Width;
851 GLuint height = texImage->Height;
852 GLuint depth = texImage->Depth;
853 struct st_texture_image *stImage = st_texture_image(texImage);
854 struct pipe_resource *src = st_texture_object(texImage->TexObject)->pt;
855 struct pipe_resource *dst = NULL;
856 struct pipe_resource dst_templ;
857 enum pipe_format dst_format, src_format;
858 gl_format mesa_format;
859 GLenum gl_target = texImage->TexObject->Target;
860 enum pipe_texture_target pipe_target;
861 struct pipe_blit_info blit;
862 unsigned bind = PIPE_BIND_TRANSFER_READ;
863 struct pipe_transfer *tex_xfer;
864 ubyte *map = NULL;
865 boolean done = FALSE;
866
867 if (!st->prefer_blit_based_texture_transfer) {
868 goto fallback;
869 }
870
871 if (!stImage->pt || !src) {
872 goto fallback;
873 }
874
875 /* XXX Fallback to _mesa_get_teximage for depth-stencil formats
876 * due to an incomplete stencil blit implementation in some drivers. */
877 if (format == GL_DEPTH_STENCIL) {
878 goto fallback;
879 }
880
881 /* If the base internal format and the texture format don't match, we have
882 * to fall back to _mesa_get_teximage. */
883 if (texImage->_BaseFormat !=
884 _mesa_get_format_base_format(texImage->TexFormat)) {
885 goto fallback;
886 }
887
888 /* See if the texture format already matches the format and type,
889 * in which case the memcpy-based fast path will be used. */
890 if (_mesa_format_matches_format_and_type(texImage->TexFormat, format,
891 type, ctx->Pack.SwapBytes)) {
892 goto fallback;
893 }
894
895 /* Convert the source format to what is expected by GetTexImage
896 * and see if it's supported.
897 *
898 * This only applies to glGetTexImage:
899 * - Luminance must be returned as (L,0,0,1).
900 * - Luminance alpha must be returned as (L,0,0,A).
901 * - Intensity must be returned as (I,0,0,1)
902 */
903 src_format = util_format_linear(src->format);
904 src_format = util_format_luminance_to_red(src_format);
905 src_format = util_format_intensity_to_red(src_format);
906
907 if (!src_format ||
908 !screen->is_format_supported(screen, src_format, src->target,
909 src->nr_samples,
910 PIPE_BIND_SAMPLER_VIEW)) {
911 goto fallback;
912 }
913
914 if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL)
915 bind |= PIPE_BIND_DEPTH_STENCIL;
916 else
917 bind |= PIPE_BIND_RENDER_TARGET;
918
919 /* GetTexImage only returns a single face for cubemaps. */
920 if (gl_target == GL_TEXTURE_CUBE_MAP) {
921 gl_target = GL_TEXTURE_2D;
922 }
923 pipe_target = gl_target_to_pipe(gl_target);
924
925 /* Choose the destination format by finding the best match
926 * for the format+type combo. */
927 dst_format = st_choose_matching_format(screen, bind, format, type,
928 ctx->Pack.SwapBytes);
929
930 if (dst_format == PIPE_FORMAT_NONE) {
931 GLenum dst_glformat;
932
933 /* Fall back to _mesa_get_teximage except for compressed formats,
934 * where decompression with a blit is always preferred. */
935 if (!util_format_is_compressed(src->format)) {
936 goto fallback;
937 }
938
939 /* Set the appropriate format for the decompressed texture.
940 * Luminance and sRGB formats shouldn't appear here.*/
941 switch (src_format) {
942 case PIPE_FORMAT_DXT1_RGB:
943 case PIPE_FORMAT_DXT1_RGBA:
944 case PIPE_FORMAT_DXT3_RGBA:
945 case PIPE_FORMAT_DXT5_RGBA:
946 case PIPE_FORMAT_RGTC1_UNORM:
947 case PIPE_FORMAT_RGTC2_UNORM:
948 case PIPE_FORMAT_ETC1_RGB8:
949 dst_glformat = GL_RGBA8;
950 break;
951 case PIPE_FORMAT_RGTC1_SNORM:
952 case PIPE_FORMAT_RGTC2_SNORM:
953 if (!ctx->Extensions.EXT_texture_snorm)
954 goto fallback;
955 dst_glformat = GL_RGBA8_SNORM;
956 break;
957 /* TODO: for BPTC_*FLOAT, set RGBA32F and check for ARB_texture_float */
958 default:
959 assert(0);
960 goto fallback;
961 }
962
963 dst_format = st_choose_format(st, dst_glformat, format, type,
964 pipe_target, 0, bind, FALSE);
965
966 if (dst_format == PIPE_FORMAT_NONE) {
967 /* unable to get an rgba format!?! */
968 goto fallback;
969 }
970 }
971
972 /* create the destination texture */
973 memset(&dst_templ, 0, sizeof(dst_templ));
974 dst_templ.target = pipe_target;
975 dst_templ.format = dst_format;
976 dst_templ.bind = bind;
977 dst_templ.usage = PIPE_USAGE_STAGING;
978
979 st_gl_texture_dims_to_pipe_dims(gl_target, width, height, depth,
980 &dst_templ.width0, &dst_templ.height0,
981 &dst_templ.depth0, &dst_templ.array_size);
982
983 dst = screen->resource_create(screen, &dst_templ);
984 if (!dst) {
985 goto fallback;
986 }
987
988 /* From now on, we need the gallium representation of dimensions. */
989 if (gl_target == GL_TEXTURE_1D_ARRAY) {
990 depth = height;
991 height = 1;
992 }
993
994 blit.src.resource = src;
995 blit.src.level = texImage->Level;
996 blit.src.format = src_format;
997 blit.dst.resource = dst;
998 blit.dst.level = 0;
999 blit.dst.format = dst->format;
1000 blit.src.box.x = blit.dst.box.x = 0;
1001 blit.src.box.y = blit.dst.box.y = 0;
1002 blit.src.box.z = texImage->Face;
1003 blit.dst.box.z = 0;
1004 blit.src.box.width = blit.dst.box.width = width;
1005 blit.src.box.height = blit.dst.box.height = height;
1006 blit.src.box.depth = blit.dst.box.depth = depth;
1007 blit.mask = st_get_blit_mask(texImage->_BaseFormat, format);
1008 blit.filter = PIPE_TEX_FILTER_NEAREST;
1009 blit.scissor_enable = FALSE;
1010
1011 /* blit/render/decompress */
1012 st->pipe->blit(st->pipe, &blit);
1013
1014 pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels);
1015
1016 map = pipe_transfer_map_3d(pipe, dst, 0, PIPE_TRANSFER_READ,
1017 0, 0, 0, width, height, depth, &tex_xfer);
1018 if (!map) {
1019 goto end;
1020 }
1021
1022 mesa_format = st_pipe_format_to_mesa_format(dst_format);
1023
1024 /* copy/pack data into user buffer */
1025 if (_mesa_format_matches_format_and_type(mesa_format, format, type,
1026 ctx->Pack.SwapBytes)) {
1027 /* memcpy */
1028 const uint bytesPerRow = width * util_format_get_blocksize(dst_format);
1029 GLuint row, slice;
1030
1031 for (slice = 0; slice < depth; slice++) {
1032 if (gl_target == GL_TEXTURE_1D_ARRAY) {
1033 /* 1D array textures.
1034 * We need to convert gallium coords to GL coords.
1035 */
1036 GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels,
1037 width, depth, format,
1038 type, 0, slice, 0);
1039 memcpy(dest, map, bytesPerRow);
1040 }
1041 else {
1042 ubyte *slice_map = map;
1043
1044 for (row = 0; row < height; row++) {
1045 GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels,
1046 width, height, format,
1047 type, slice, row, 0);
1048 memcpy(dest, slice_map, bytesPerRow);
1049 slice_map += tex_xfer->stride;
1050 }
1051 }
1052 map += tex_xfer->layer_stride;
1053 }
1054 }
1055 else {
1056 /* format translation via floats */
1057 GLuint row, slice;
1058 GLfloat *rgba;
1059
1060 assert(util_format_is_compressed(src->format));
1061
1062 rgba = malloc(width * 4 * sizeof(GLfloat));
1063 if (!rgba) {
1064 goto end;
1065 }
1066
1067 if (ST_DEBUG & DEBUG_FALLBACK)
1068 debug_printf("%s: fallback format translation\n", __FUNCTION__);
1069
1070 for (slice = 0; slice < depth; slice++) {
1071 if (gl_target == GL_TEXTURE_1D_ARRAY) {
1072 /* 1D array textures.
1073 * We need to convert gallium coords to GL coords.
1074 */
1075 GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels,
1076 width, depth, format,
1077 type, 0, slice, 0);
1078
1079 /* get float[4] rgba row from surface */
1080 pipe_get_tile_rgba_format(tex_xfer, map, 0, 0, width, 1,
1081 dst_format, rgba);
1082
1083 _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
1084 type, dest, &ctx->Pack, 0);
1085 }
1086 else {
1087 for (row = 0; row < height; row++) {
1088 GLvoid *dest = _mesa_image_address3d(&ctx->Pack, pixels,
1089 width, height, format,
1090 type, slice, row, 0);
1091
1092 /* get float[4] rgba row from surface */
1093 pipe_get_tile_rgba_format(tex_xfer, map, 0, row, width, 1,
1094 dst_format, rgba);
1095
1096 _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) rgba, format,
1097 type, dest, &ctx->Pack, 0);
1098 }
1099 }
1100 map += tex_xfer->layer_stride;
1101 }
1102
1103 free(rgba);
1104 }
1105 done = TRUE;
1106
1107 end:
1108 if (map)
1109 pipe_transfer_unmap(pipe, tex_xfer);
1110
1111 _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
1112 pipe_resource_reference(&dst, NULL);
1113
1114 fallback:
1115 if (!done) {
1116 _mesa_get_teximage(ctx, format, type, pixels, texImage);
1117 }
1118 }
1119
1120
1121 /**
1122 * Do a CopyTexSubImage operation using a read transfer from the source,
1123 * a write transfer to the destination and get_tile()/put_tile() to access
1124 * the pixels/texels.
1125 *
1126 * Note: srcY=0=TOP of renderbuffer
1127 */
1128 static void
1129 fallback_copy_texsubimage(struct gl_context *ctx,
1130 struct st_renderbuffer *strb,
1131 struct st_texture_image *stImage,
1132 GLenum baseFormat,
1133 GLint destX, GLint destY, GLint destZ,
1134 GLint srcX, GLint srcY,
1135 GLsizei width, GLsizei height)
1136 {
1137 struct st_context *st = st_context(ctx);
1138 struct pipe_context *pipe = st->pipe;
1139 struct pipe_transfer *src_trans;
1140 GLubyte *texDest;
1141 enum pipe_transfer_usage transfer_usage;
1142 void *map;
1143 unsigned dst_width = width;
1144 unsigned dst_height = height;
1145 unsigned dst_depth = 1;
1146
1147 if (ST_DEBUG & DEBUG_FALLBACK)
1148 debug_printf("%s: fallback processing\n", __FUNCTION__);
1149
1150 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1151 srcY = strb->Base.Height - srcY - height;
1152 }
1153
1154 if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {
1155 /* Move y/height to z/depth for 1D array textures. */
1156 destZ = destY;
1157 destY = 0;
1158 dst_depth = dst_height;
1159 dst_height = 1;
1160 }
1161
1162 map = pipe_transfer_map(pipe,
1163 strb->texture,
1164 strb->rtt_level,
1165 strb->rtt_face + strb->rtt_slice,
1166 PIPE_TRANSFER_READ,
1167 srcX, srcY,
1168 width, height, &src_trans);
1169
1170 if ((baseFormat == GL_DEPTH_COMPONENT ||
1171 baseFormat == GL_DEPTH_STENCIL) &&
1172 util_format_is_depth_and_stencil(stImage->pt->format))
1173 transfer_usage = PIPE_TRANSFER_READ_WRITE;
1174 else
1175 transfer_usage = PIPE_TRANSFER_WRITE;
1176
1177 texDest = st_texture_image_map(st, stImage, transfer_usage,
1178 destX, destY, destZ,
1179 dst_width, dst_height, dst_depth);
1180
1181 if (baseFormat == GL_DEPTH_COMPONENT ||
1182 baseFormat == GL_DEPTH_STENCIL) {
1183 const GLboolean scaleOrBias = (ctx->Pixel.DepthScale != 1.0F ||
1184 ctx->Pixel.DepthBias != 0.0F);
1185 GLint row, yStep;
1186 uint *data;
1187
1188 /* determine bottom-to-top vs. top-to-bottom order for src buffer */
1189 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1190 srcY = height - 1;
1191 yStep = -1;
1192 }
1193 else {
1194 srcY = 0;
1195 yStep = 1;
1196 }
1197
1198 data = malloc(width * sizeof(uint));
1199
1200 if (data) {
1201 /* To avoid a large temp memory allocation, do copy row by row */
1202 for (row = 0; row < height; row++, srcY += yStep) {
1203 pipe_get_tile_z(src_trans, map, 0, srcY, width, 1, data);
1204 if (scaleOrBias) {
1205 _mesa_scale_and_bias_depth_uint(ctx, width, data);
1206 }
1207
1208 if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {
1209 pipe_put_tile_z(stImage->transfer,
1210 texDest + row*stImage->transfer->layer_stride,
1211 0, 0, width, 1, data);
1212 }
1213 else {
1214 pipe_put_tile_z(stImage->transfer, texDest, 0, row, width, 1,
1215 data);
1216 }
1217 }
1218 }
1219 else {
1220 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage()");
1221 }
1222
1223 free(data);
1224 }
1225 else {
1226 /* RGBA format */
1227 GLfloat *tempSrc =
1228 malloc(width * height * 4 * sizeof(GLfloat));
1229
1230 if (tempSrc && texDest) {
1231 const GLint dims = 2;
1232 GLint dstRowStride;
1233 struct gl_texture_image *texImage = &stImage->base;
1234 struct gl_pixelstore_attrib unpack = ctx->DefaultPacking;
1235
1236 if (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP) {
1237 unpack.Invert = GL_TRUE;
1238 }
1239
1240 if (stImage->pt->target == PIPE_TEXTURE_1D_ARRAY) {
1241 dstRowStride = stImage->transfer->layer_stride;
1242 }
1243 else {
1244 dstRowStride = stImage->transfer->stride;
1245 }
1246
1247 /* get float/RGBA image from framebuffer */
1248 /* XXX this usually involves a lot of int/float conversion.
1249 * try to avoid that someday.
1250 */
1251 pipe_get_tile_rgba_format(src_trans, map, 0, 0, width, height,
1252 util_format_linear(strb->texture->format),
1253 tempSrc);
1254
1255 /* Store into texture memory.
1256 * Note that this does some special things such as pixel transfer
1257 * ops and format conversion. In particular, if the dest tex format
1258 * is actually RGBA but the user created the texture as GL_RGB we
1259 * need to fill-in/override the alpha channel with 1.0.
1260 */
1261 _mesa_texstore(ctx, dims,
1262 texImage->_BaseFormat,
1263 texImage->TexFormat,
1264 dstRowStride,
1265 &texDest,
1266 width, height, 1,
1267 GL_RGBA, GL_FLOAT, tempSrc, /* src */
1268 &unpack);
1269 }
1270 else {
1271 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
1272 }
1273
1274 free(tempSrc);
1275 }
1276
1277 st_texture_image_unmap(st, stImage);
1278 pipe->transfer_unmap(pipe, src_trans);
1279 }
1280
1281
1282 /**
1283 * Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible.
1284 * Note that the region to copy has already been clipped so we know we
1285 * won't read from outside the source renderbuffer's bounds.
1286 *
1287 * Note: srcY=0=Bottom of renderbuffer (GL convention)
1288 */
1289 static void
1290 st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
1291 struct gl_texture_image *texImage,
1292 GLint destX, GLint destY, GLint destZ,
1293 struct gl_renderbuffer *rb,
1294 GLint srcX, GLint srcY, GLsizei width, GLsizei height)
1295 {
1296 struct st_texture_image *stImage = st_texture_image(texImage);
1297 struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
1298 struct st_renderbuffer *strb = st_renderbuffer(rb);
1299 struct st_context *st = st_context(ctx);
1300 struct pipe_context *pipe = st->pipe;
1301 struct pipe_screen *screen = pipe->screen;
1302 struct pipe_blit_info blit;
1303 enum pipe_format dst_format;
1304 GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
1305 unsigned bind;
1306 GLint srcY0, srcY1, yStep;
1307
1308 if (!strb || !strb->surface || !stImage->pt) {
1309 debug_printf("%s: null strb or stImage\n", __FUNCTION__);
1310 return;
1311 }
1312
1313 if (_mesa_texstore_needs_transfer_ops(ctx, texImage->_BaseFormat,
1314 texImage->TexFormat)) {
1315 goto fallback;
1316 }
1317
1318 /* The base internal format must match the mesa format, so make sure
1319 * e.g. an RGB internal format is really allocated as RGB and not as RGBA.
1320 */
1321 if (texImage->_BaseFormat !=
1322 _mesa_get_format_base_format(texImage->TexFormat) ||
1323 rb->_BaseFormat != _mesa_get_format_base_format(rb->Format)) {
1324 goto fallback;
1325 }
1326
1327 /* Choose the destination format to match the TexImage behavior. */
1328 dst_format = util_format_linear(stImage->pt->format);
1329 dst_format = util_format_luminance_to_red(dst_format);
1330 dst_format = util_format_intensity_to_red(dst_format);
1331
1332 /* See if the destination format is supported. */
1333 if (texImage->_BaseFormat == GL_DEPTH_STENCIL ||
1334 texImage->_BaseFormat == GL_DEPTH_COMPONENT) {
1335 bind = PIPE_BIND_DEPTH_STENCIL;
1336 }
1337 else {
1338 bind = PIPE_BIND_RENDER_TARGET;
1339 }
1340
1341 if (!dst_format ||
1342 !screen->is_format_supported(screen, dst_format, stImage->pt->target,
1343 stImage->pt->nr_samples, bind)) {
1344 goto fallback;
1345 }
1346
1347 /* Y flipping for the main framebuffer. */
1348 if (do_flip) {
1349 srcY1 = strb->Base.Height - srcY - height;
1350 srcY0 = srcY1 + height;
1351 yStep = -1;
1352 }
1353 else {
1354 srcY0 = srcY;
1355 srcY1 = srcY0 + height;
1356 yStep = 1;
1357 }
1358
1359 /* Blit the texture.
1360 * This supports flipping, format conversions, and downsampling.
1361 */
1362 memset(&blit, 0, sizeof(blit));
1363 blit.src.resource = strb->texture;
1364 blit.src.format = util_format_linear(strb->surface->format);
1365 blit.src.level = strb->surface->u.tex.level;
1366 blit.src.box.x = srcX;
1367 blit.src.box.y = srcY0;
1368 blit.src.box.z = strb->surface->u.tex.first_layer;
1369 blit.src.box.width = width;
1370 blit.src.box.height = srcY1 - srcY0;
1371 blit.src.box.depth = 1;
1372 blit.dst.resource = stImage->pt;
1373 blit.dst.format = dst_format;
1374 blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->Level;
1375 blit.dst.box.x = destX;
1376 blit.dst.box.y = destY;
1377 blit.dst.box.z = stImage->base.Face + destZ;
1378 blit.dst.box.width = width;
1379 blit.dst.box.height = height;
1380 blit.dst.box.depth = 1;
1381 blit.mask = st_get_blit_mask(rb->_BaseFormat, texImage->_BaseFormat);
1382 blit.filter = PIPE_TEX_FILTER_NEAREST;
1383
1384 /* 1D array textures need special treatment.
1385 * Blit rows from the source to layers in the destination. */
1386 if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
1387 int y, layer;
1388
1389 for (y = srcY0, layer = 0; layer < height; y += yStep, layer++) {
1390 blit.src.box.y = y;
1391 blit.src.box.height = 1;
1392 blit.dst.box.y = 0;
1393 blit.dst.box.height = 1;
1394 blit.dst.box.z = destY + layer;
1395
1396 pipe->blit(pipe, &blit);
1397 }
1398 }
1399 else {
1400 /* All the other texture targets. */
1401 pipe->blit(pipe, &blit);
1402 }
1403 return;
1404
1405 fallback:
1406 /* software fallback */
1407 fallback_copy_texsubimage(ctx,
1408 strb, stImage, texImage->_BaseFormat,
1409 destX, destY, destZ,
1410 srcX, srcY, width, height);
1411 }
1412
1413
1414 /**
1415 * Copy image data from stImage into the texture object 'stObj' at level
1416 * 'dstLevel'.
1417 */
1418 static void
1419 copy_image_data_to_texture(struct st_context *st,
1420 struct st_texture_object *stObj,
1421 GLuint dstLevel,
1422 struct st_texture_image *stImage)
1423 {
1424 /* debug checks */
1425 {
1426 const struct gl_texture_image *dstImage =
1427 stObj->base.Image[stImage->base.Face][dstLevel];
1428 assert(dstImage);
1429 assert(dstImage->Width == stImage->base.Width);
1430 assert(dstImage->Height == stImage->base.Height);
1431 assert(dstImage->Depth == stImage->base.Depth);
1432 }
1433
1434 if (stImage->pt) {
1435 /* Copy potentially with the blitter:
1436 */
1437 GLuint src_level;
1438 if (stImage->pt->last_level == 0)
1439 src_level = 0;
1440 else
1441 src_level = stImage->base.Level;
1442
1443 assert(src_level <= stImage->pt->last_level);
1444 assert(u_minify(stImage->pt->width0, src_level) == stImage->base.Width);
1445 assert(stImage->pt->target == PIPE_TEXTURE_1D_ARRAY ||
1446 u_minify(stImage->pt->height0, src_level) == stImage->base.Height);
1447 assert(stImage->pt->target == PIPE_TEXTURE_2D_ARRAY ||
1448 stImage->pt->target == PIPE_TEXTURE_CUBE_ARRAY ||
1449 u_minify(stImage->pt->depth0, src_level) == stImage->base.Depth);
1450
1451 st_texture_image_copy(st->pipe,
1452 stObj->pt, dstLevel, /* dest texture, level */
1453 stImage->pt, src_level, /* src texture, level */
1454 stImage->base.Face);
1455
1456 pipe_resource_reference(&stImage->pt, NULL);
1457 }
1458 else if (stImage->TexData) {
1459 /* Copy from malloc'd memory */
1460 /* XXX this should be re-examined/tested with a compressed format */
1461 GLuint blockSize = util_format_get_blocksize(stObj->pt->format);
1462 GLuint srcRowStride = stImage->base.Width * blockSize;
1463 GLuint srcSliceStride = stImage->base.Height * srcRowStride;
1464 st_texture_image_data(st,
1465 stObj->pt,
1466 stImage->base.Face,
1467 dstLevel,
1468 stImage->TexData,
1469 srcRowStride,
1470 srcSliceStride);
1471 _mesa_align_free(stImage->TexData);
1472 stImage->TexData = NULL;
1473 }
1474
1475 pipe_resource_reference(&stImage->pt, stObj->pt);
1476 }
1477
1478
1479 /**
1480 * Called during state validation. When this function is finished,
1481 * the texture object should be ready for rendering.
1482 * \return GL_TRUE for success, GL_FALSE for failure (out of mem)
1483 */
1484 GLboolean
1485 st_finalize_texture(struct gl_context *ctx,
1486 struct pipe_context *pipe,
1487 struct gl_texture_object *tObj)
1488 {
1489 struct st_context *st = st_context(ctx);
1490 struct st_texture_object *stObj = st_texture_object(tObj);
1491 const GLuint nr_faces = (stObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
1492 GLuint face;
1493 struct st_texture_image *firstImage;
1494 enum pipe_format firstImageFormat;
1495 GLuint ptWidth, ptHeight, ptDepth, ptLayers;
1496
1497 if (_mesa_is_texture_complete(tObj, &tObj->Sampler)) {
1498 /* The texture is complete and we know exactly how many mipmap levels
1499 * are present/needed. This is conditional because we may be called
1500 * from the st_generate_mipmap() function when the texture object is
1501 * incomplete. In that case, we'll have set stObj->lastLevel before
1502 * we get here.
1503 */
1504 if (stObj->base.Sampler.MinFilter == GL_LINEAR ||
1505 stObj->base.Sampler.MinFilter == GL_NEAREST)
1506 stObj->lastLevel = stObj->base.BaseLevel;
1507 else
1508 stObj->lastLevel = stObj->base._MaxLevel;
1509 }
1510
1511 if (tObj->Target == GL_TEXTURE_BUFFER) {
1512 struct st_buffer_object *st_obj = st_buffer_object(tObj->BufferObject);
1513
1514 if (st_obj->buffer != stObj->pt) {
1515 pipe_resource_reference(&stObj->pt, st_obj->buffer);
1516 pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
1517 stObj->width0 = stObj->pt->width0 / _mesa_get_format_bytes(tObj->_BufferObjectFormat);
1518 stObj->height0 = 1;
1519 stObj->depth0 = 1;
1520 }
1521 return GL_TRUE;
1522
1523 }
1524
1525 firstImage = st_texture_image(stObj->base.Image[0][stObj->base.BaseLevel]);
1526 assert(firstImage);
1527
1528 /* If both firstImage and stObj point to a texture which can contain
1529 * all active images, favour firstImage. Note that because of the
1530 * completeness requirement, we know that the image dimensions
1531 * will match.
1532 */
1533 if (firstImage->pt &&
1534 firstImage->pt != stObj->pt &&
1535 (!stObj->pt || firstImage->pt->last_level >= stObj->pt->last_level)) {
1536 pipe_resource_reference(&stObj->pt, firstImage->pt);
1537 pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
1538 }
1539
1540 /* Find gallium format for the Mesa texture */
1541 firstImageFormat = st_mesa_format_to_pipe_format(firstImage->base.TexFormat);
1542
1543 /* Find size of level=0 Gallium mipmap image, plus number of texture layers */
1544 {
1545 GLuint width, height, depth;
1546 if (!guess_base_level_size(stObj->base.Target,
1547 firstImage->base.Width2,
1548 firstImage->base.Height2,
1549 firstImage->base.Depth2,
1550 firstImage->base.Level,
1551 &width, &height, &depth)) {
1552 width = stObj->width0;
1553 height = stObj->height0;
1554 depth = stObj->depth0;
1555 }
1556 /* convert GL dims to Gallium dims */
1557 st_gl_texture_dims_to_pipe_dims(stObj->base.Target, width, height, depth,
1558 &ptWidth, &ptHeight, &ptDepth, &ptLayers);
1559 }
1560
1561 /* If we already have a gallium texture, check that it matches the texture
1562 * object's format, target, size, num_levels, etc.
1563 */
1564 if (stObj->pt) {
1565 if (stObj->pt->target != gl_target_to_pipe(stObj->base.Target) ||
1566 !st_sampler_compat_formats(stObj->pt->format, firstImageFormat) ||
1567 stObj->pt->last_level < stObj->lastLevel ||
1568 stObj->pt->width0 != ptWidth ||
1569 stObj->pt->height0 != ptHeight ||
1570 stObj->pt->depth0 != ptDepth ||
1571 stObj->pt->array_size != ptLayers)
1572 {
1573 /* The gallium texture does not match the Mesa texture so delete the
1574 * gallium texture now. We'll make a new one below.
1575 */
1576 pipe_resource_reference(&stObj->pt, NULL);
1577 pipe_sampler_view_release(st->pipe, &stObj->sampler_view);
1578 st->dirty.st |= ST_NEW_FRAMEBUFFER;
1579 }
1580 }
1581
1582 /* May need to create a new gallium texture:
1583 */
1584 if (!stObj->pt) {
1585 GLuint bindings = default_bindings(st, firstImageFormat);
1586
1587 stObj->pt = st_texture_create(st,
1588 gl_target_to_pipe(stObj->base.Target),
1589 firstImageFormat,
1590 stObj->lastLevel,
1591 ptWidth,
1592 ptHeight,
1593 ptDepth,
1594 ptLayers,
1595 bindings);
1596
1597 if (!stObj->pt) {
1598 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage");
1599 return GL_FALSE;
1600 }
1601 }
1602
1603 /* Pull in any images not in the object's texture:
1604 */
1605 for (face = 0; face < nr_faces; face++) {
1606 GLuint level;
1607 for (level = stObj->base.BaseLevel; level <= stObj->lastLevel; level++) {
1608 struct st_texture_image *stImage =
1609 st_texture_image(stObj->base.Image[face][level]);
1610
1611 /* Need to import images in main memory or held in other textures.
1612 */
1613 if (stImage && stObj->pt != stImage->pt) {
1614 if (level == 0 ||
1615 (stImage->base.Width == u_minify(stObj->width0, level) &&
1616 stImage->base.Height == u_minify(stObj->height0, level) &&
1617 stImage->base.Depth == u_minify(stObj->depth0, level))) {
1618 /* src image fits expected dest mipmap level size */
1619 copy_image_data_to_texture(st, stObj, level, stImage);
1620 }
1621 }
1622 }
1623 }
1624
1625 return GL_TRUE;
1626 }
1627
1628
1629 /**
1630 * Called via ctx->Driver.AllocTextureStorage() to allocate texture memory
1631 * for a whole mipmap stack.
1632 */
1633 static GLboolean
1634 st_AllocTextureStorage(struct gl_context *ctx,
1635 struct gl_texture_object *texObj,
1636 GLsizei levels, GLsizei width,
1637 GLsizei height, GLsizei depth)
1638 {
1639 const GLuint numFaces = _mesa_num_tex_faces(texObj->Target);
1640 struct st_context *st = st_context(ctx);
1641 struct st_texture_object *stObj = st_texture_object(texObj);
1642 GLuint ptWidth, ptHeight, ptDepth, ptLayers, bindings;
1643 enum pipe_format fmt;
1644 GLint level;
1645
1646 assert(levels > 0);
1647
1648 /* Save the level=0 dimensions */
1649 stObj->width0 = width;
1650 stObj->height0 = height;
1651 stObj->depth0 = depth;
1652 stObj->lastLevel = levels - 1;
1653
1654 fmt = st_mesa_format_to_pipe_format(texObj->Image[0][0]->TexFormat);
1655
1656 bindings = default_bindings(st, fmt);
1657
1658 st_gl_texture_dims_to_pipe_dims(texObj->Target,
1659 width, height, depth,
1660 &ptWidth, &ptHeight, &ptDepth, &ptLayers);
1661
1662 stObj->pt = st_texture_create(st,
1663 gl_target_to_pipe(texObj->Target),
1664 fmt,
1665 levels,
1666 ptWidth,
1667 ptHeight,
1668 ptDepth,
1669 ptLayers,
1670 bindings);
1671 if (!stObj->pt)
1672 return GL_FALSE;
1673
1674 /* Set image resource pointers */
1675 for (level = 0; level < levels; level++) {
1676 GLuint face;
1677 for (face = 0; face < numFaces; face++) {
1678 struct st_texture_image *stImage =
1679 st_texture_image(texObj->Image[face][level]);
1680 pipe_resource_reference(&stImage->pt, stObj->pt);
1681 }
1682 }
1683
1684 return GL_TRUE;
1685 }
1686
1687
1688 static GLboolean
1689 st_TestProxyTexImage(struct gl_context *ctx, GLenum target,
1690 GLint level, gl_format format,
1691 GLint width, GLint height,
1692 GLint depth, GLint border)
1693 {
1694 struct st_context *st = st_context(ctx);
1695 struct pipe_context *pipe = st->pipe;
1696
1697 if (width == 0 || height == 0 || depth == 0) {
1698 /* zero-sized images are legal, and always fit! */
1699 return GL_TRUE;
1700 }
1701
1702 if (pipe->screen->can_create_resource) {
1703 /* Ask the gallium driver if the texture is too large */
1704 struct gl_texture_object *texObj =
1705 _mesa_get_current_tex_object(ctx, target);
1706 struct pipe_resource pt;
1707
1708 /* Setup the pipe_resource object
1709 */
1710 memset(&pt, 0, sizeof(pt));
1711
1712 pt.target = gl_target_to_pipe(target);
1713 pt.format = st_mesa_format_to_pipe_format(format);
1714
1715 st_gl_texture_dims_to_pipe_dims(target,
1716 width, height, depth,
1717 &pt.width0, &pt.height0,
1718 &pt.depth0, &pt.array_size);
1719
1720 if (level == 0 && (texObj->Sampler.MinFilter == GL_LINEAR ||
1721 texObj->Sampler.MinFilter == GL_NEAREST)) {
1722 /* assume just one mipmap level */
1723 pt.last_level = 0;
1724 }
1725 else {
1726 /* assume a full set of mipmaps */
1727 pt.last_level = _mesa_logbase2(MAX3(width, height, depth));
1728 }
1729
1730 return pipe->screen->can_create_resource(pipe->screen, &pt);
1731 }
1732 else {
1733 /* Use core Mesa fallback */
1734 return _mesa_test_proxy_teximage(ctx, target, level, format,
1735 width, height, depth, border);
1736 }
1737 }
1738
1739
1740 void
1741 st_init_texture_functions(struct dd_function_table *functions)
1742 {
1743 functions->ChooseTextureFormat = st_ChooseTextureFormat;
1744 functions->QuerySamplesForFormat = st_QuerySamplesForFormat;
1745 functions->TexImage = st_TexImage;
1746 functions->TexSubImage = st_TexSubImage;
1747 functions->CompressedTexSubImage = _mesa_store_compressed_texsubimage;
1748 functions->CopyTexSubImage = st_CopyTexSubImage;
1749 functions->GenerateMipmap = st_generate_mipmap;
1750
1751 functions->GetTexImage = st_GetTexImage;
1752
1753 /* compressed texture functions */
1754 functions->CompressedTexImage = st_CompressedTexImage;
1755 functions->GetCompressedTexImage = _mesa_get_compressed_teximage;
1756
1757 functions->NewTextureObject = st_NewTextureObject;
1758 functions->NewTextureImage = st_NewTextureImage;
1759 functions->DeleteTextureImage = st_DeleteTextureImage;
1760 functions->DeleteTexture = st_DeleteTextureObject;
1761 functions->AllocTextureImageBuffer = st_AllocTextureImageBuffer;
1762 functions->FreeTextureImageBuffer = st_FreeTextureImageBuffer;
1763 functions->MapTextureImage = st_MapTextureImage;
1764 functions->UnmapTextureImage = st_UnmapTextureImage;
1765
1766 /* XXX Temporary until we can query pipe's texture sizes */
1767 functions->TestProxyTexImage = st_TestProxyTexImage;
1768
1769 functions->AllocTextureStorage = st_AllocTextureStorage;
1770 }