2 /**************************************************************************
4 * Copyright 2003 VMware, Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 **************************************************************************/
29 #include "main/bufferobj.h"
30 #include "main/image.h"
31 #include "main/macros.h"
32 #include "main/mtypes.h"
34 #include "main/texobj.h"
35 #include "main/texstore.h"
36 #include "main/texcompress.h"
37 #include "main/enums.h"
39 #include "brw_context.h"
40 #include "intel_batchbuffer.h"
41 #include "intel_tex.h"
42 #include "intel_mipmap_tree.h"
43 #include "intel_blit.h"
46 #include <tmmintrin.h>
49 #define FILE_DEBUG_FLAG DEBUG_TEXTURE
51 #define ALIGN_DOWN(a, b) ROUND_DOWN_TO(a, b)
52 #define ALIGN_UP(a, b) ALIGN(a, b)
55 * Width and span are in bytes, height is in pixels (i.e. unitless).
56 * A "span" is the most number of bytes we can copy from linear to tiled
57 * without needing to calculate a new destination address.
59 static const uint32_t xtile_width
= 512;
60 static const uint32_t xtile_height
= 8;
61 static const uint32_t xtile_span
= 64;
62 static const uint32_t ytile_width
= 128;
63 static const uint32_t ytile_height
= 32;
64 static const uint32_t ytile_span
= 16;
66 typedef void *(*mem_copy_fn
)(void *dest
, const void *src
, size_t n
);
69 * Each row from y0 to y1 is copied in three parts: [x0,x1), [x1,x2), [x2,x3).
70 * These ranges are in bytes, i.e. pixels * bytes-per-pixel.
71 * The first and last ranges must be shorter than a "span" (the longest linear
72 * stretch within a tile) and the middle must equal a whole number of spans.
73 * Ranges may be empty. The region copied must land entirely within one tile.
74 * 'dst' is the start of the tile and 'src' is the corresponding
75 * address to copy from, though copying begins at (x0, y0).
76 * To enable swizzling 'swizzle_bit' must be 1<<6, otherwise zero.
77 * Swizzling flips bit 6 in the copy destination offset, when certain other
80 typedef void (*tile_copy_fn
)(uint32_t x0
, uint32_t x1
, uint32_t x2
, uint32_t x3
,
81 uint32_t y0
, uint32_t y1
,
82 char *dst
, const char *src
,
85 mem_copy_fn mem_copy
);
89 intel_blit_texsubimage(struct gl_context
* ctx
,
90 struct gl_texture_image
*texImage
,
91 GLint xoffset
, GLint yoffset
,
92 GLint width
, GLint height
,
93 GLenum format
, GLenum type
, const void *pixels
,
94 const struct gl_pixelstore_attrib
*packing
)
96 struct brw_context
*brw
= brw_context(ctx
);
97 struct intel_texture_image
*intelImage
= intel_texture_image(texImage
);
99 /* Try to do a blit upload of the subimage if the texture is
105 /* Prior to Sandybridge, the blitter can't handle Y tiling */
106 if (brw
->gen
< 6 && intelImage
->mt
->tiling
== I915_TILING_Y
)
109 if (texImage
->TexObject
->Target
!= GL_TEXTURE_2D
)
112 /* On gen6, it's probably not worth swapping to the blit ring to do
113 * this because of all the overhead involved.
118 if (!drm_intel_bo_busy(intelImage
->mt
->bo
))
121 DBG("BLT subimage %s target %s level %d offset %d,%d %dx%d\n",
123 _mesa_lookup_enum_by_nr(texImage
->TexObject
->Target
),
124 texImage
->Level
, xoffset
, yoffset
, width
, height
);
126 pixels
= _mesa_validate_pbo_teximage(ctx
, 2, width
, height
, 1,
127 format
, type
, pixels
, packing
,
132 struct intel_mipmap_tree
*temp_mt
=
133 intel_miptree_create(brw
, GL_TEXTURE_2D
, texImage
->TexFormat
,
136 false, 0, INTEL_MIPTREE_TILING_NONE
);
140 GLubyte
*dst
= intel_miptree_map_raw(brw
, temp_mt
);
144 if (!_mesa_texstore(ctx
, 2, texImage
->_BaseFormat
,
149 format
, type
, pixels
, packing
)) {
150 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "intelTexSubImage");
153 intel_miptree_unmap_raw(brw
, temp_mt
);
157 ret
= intel_miptree_blit(brw
,
160 intelImage
->mt
, texImage
->Level
, texImage
->Face
,
161 xoffset
, yoffset
, false,
162 width
, height
, GL_COPY
);
165 intel_miptree_release(&temp_mt
);
166 _mesa_unmap_teximage_pbo(ctx
, packing
);
171 _mesa_error(ctx
, GL_OUT_OF_MEMORY
, "intelTexSubImage");
172 intel_miptree_release(&temp_mt
);
173 _mesa_unmap_teximage_pbo(ctx
, packing
);
178 static const uint8_t rgba8_permutation
[16] =
179 { 2,1,0,3, 6,5,4,7, 10,9,8,11, 14,13,12,15 };
181 /* NOTE: dst must be 16 byte aligned */
182 #define rgba8_copy_16(dst, src) \
183 *(__m128i *)(dst) = _mm_shuffle_epi8( \
184 (__m128i) _mm_loadu_ps((float *)(src)), \
185 *(__m128i *) rgba8_permutation \
190 * Copy RGBA to BGRA - swap R and B.
193 rgba8_copy(void *dst
, const void *src
, size_t bytes
)
196 uint8_t const *s
= src
;
199 /* Fast copying for tile spans.
201 * As long as the destination texture is 16 aligned,
202 * any 16 or 64 spans we get here should also be 16 aligned.
206 assert(!(((uintptr_t)dst
) & 0xf));
207 rgba8_copy_16(d
+ 0, s
+ 0);
212 assert(!(((uintptr_t)dst
) & 0xf));
213 rgba8_copy_16(d
+ 0, s
+ 0);
214 rgba8_copy_16(d
+16, s
+16);
215 rgba8_copy_16(d
+32, s
+32);
216 rgba8_copy_16(d
+48, s
+48);
234 * Copy texture data from linear to X tile layout.
236 * \copydoc tile_copy_fn
239 xtile_copy(uint32_t x0
, uint32_t x1
, uint32_t x2
, uint32_t x3
,
240 uint32_t y0
, uint32_t y1
,
241 char *dst
, const char *src
,
243 uint32_t swizzle_bit
,
244 mem_copy_fn mem_copy
)
246 /* The copy destination offset for each range copied is the sum of
247 * an X offset 'x0' or 'xo' and a Y offset 'yo.'
251 src
+= y0
* src_pitch
;
253 for (yo
= y0
* xtile_width
; yo
< y1
* xtile_width
; yo
+= xtile_width
) {
254 /* Bits 9 and 10 of the copy destination offset control swizzling.
255 * Only 'yo' contributes to those bits in the total offset,
256 * so calculate 'swizzle' just once per row.
257 * Move bits 9 and 10 three and four places respectively down
258 * to bit 6 and xor them.
260 uint32_t swizzle
= ((yo
>> 3) ^ (yo
>> 4)) & swizzle_bit
;
262 mem_copy(dst
+ ((x0
+ yo
) ^ swizzle
), src
+ x0
, x1
- x0
);
264 for (xo
= x1
; xo
< x2
; xo
+= xtile_span
) {
265 mem_copy(dst
+ ((xo
+ yo
) ^ swizzle
), src
+ xo
, xtile_span
);
268 mem_copy(dst
+ ((xo
+ yo
) ^ swizzle
), src
+ x2
, x3
- x2
);
275 * Copy texture data from linear to Y tile layout.
277 * \copydoc tile_copy_fn
281 uint32_t x0
, uint32_t x1
, uint32_t x2
, uint32_t x3
,
282 uint32_t y0
, uint32_t y1
,
283 char *dst
, const char *src
,
285 uint32_t swizzle_bit
,
286 mem_copy_fn mem_copy
)
288 /* Y tiles consist of columns that are 'ytile_span' wide (and the same height
289 * as the tile). Thus the destination offset for (x,y) is the sum of:
290 * (x % column_width) // position within column
291 * (x / column_width) * bytes_per_column // column number * bytes per column
294 * The copy destination offset for each range copied is the sum of
295 * an X offset 'xo0' or 'xo' and a Y offset 'yo.'
297 const uint32_t column_width
= ytile_span
;
298 const uint32_t bytes_per_column
= column_width
* ytile_height
;
300 uint32_t xo0
= (x0
% ytile_span
) + (x0
/ ytile_span
) * bytes_per_column
;
301 uint32_t xo1
= (x1
% ytile_span
) + (x1
/ ytile_span
) * bytes_per_column
;
303 /* Bit 9 of the destination offset control swizzling.
304 * Only the X offset contributes to bit 9 of the total offset,
305 * so swizzle can be calculated in advance for these X positions.
306 * Move bit 9 three places down to bit 6.
308 uint32_t swizzle0
= (xo0
>> 3) & swizzle_bit
;
309 uint32_t swizzle1
= (xo1
>> 3) & swizzle_bit
;
313 src
+= y0
* src_pitch
;
315 for (yo
= y0
* column_width
; yo
< y1
* column_width
; yo
+= column_width
) {
317 uint32_t swizzle
= swizzle1
;
319 mem_copy(dst
+ ((xo0
+ yo
) ^ swizzle0
), src
+ x0
, x1
- x0
);
321 /* Step by spans/columns. As it happens, the swizzle bit flips
322 * at each step so we don't need to calculate it explicitly.
324 for (x
= x1
; x
< x2
; x
+= ytile_span
) {
325 mem_copy(dst
+ ((xo
+ yo
) ^ swizzle
), src
+ x
, ytile_span
);
326 xo
+= bytes_per_column
;
327 swizzle
^= swizzle_bit
;
330 mem_copy(dst
+ ((xo
+ yo
) ^ swizzle
), src
+ x2
, x3
- x2
);
337 #define FLATTEN __attribute__((flatten))
343 * Copy texture data from linear to X tile layout, faster.
345 * Same as \ref xtile_copy but faster, because it passes constant parameters
346 * for common cases, allowing the compiler to inline code optimized for those
349 * \copydoc tile_copy_fn
352 xtile_copy_faster(uint32_t x0
, uint32_t x1
, uint32_t x2
, uint32_t x3
,
353 uint32_t y0
, uint32_t y1
,
354 char *dst
, const char *src
,
356 uint32_t swizzle_bit
,
357 mem_copy_fn mem_copy
)
359 if (x0
== 0 && x3
== xtile_width
&& y0
== 0 && y1
== xtile_height
) {
360 if (mem_copy
== memcpy
)
361 return xtile_copy(0, 0, xtile_width
, xtile_width
, 0, xtile_height
,
362 dst
, src
, src_pitch
, swizzle_bit
, memcpy
);
363 else if (mem_copy
== rgba8_copy
)
364 return xtile_copy(0, 0, xtile_width
, xtile_width
, 0, xtile_height
,
365 dst
, src
, src_pitch
, swizzle_bit
, rgba8_copy
);
367 if (mem_copy
== memcpy
)
368 return xtile_copy(x0
, x1
, x2
, x3
, y0
, y1
,
369 dst
, src
, src_pitch
, swizzle_bit
, memcpy
);
370 else if (mem_copy
== rgba8_copy
)
371 return xtile_copy(x0
, x1
, x2
, x3
, y0
, y1
,
372 dst
, src
, src_pitch
, swizzle_bit
, rgba8_copy
);
374 xtile_copy(x0
, x1
, x2
, x3
, y0
, y1
,
375 dst
, src
, src_pitch
, swizzle_bit
, mem_copy
);
379 * Copy texture data from linear to Y tile layout, faster.
381 * Same as \ref ytile_copy but faster, because it passes constant parameters
382 * for common cases, allowing the compiler to inline code optimized for those
385 * \copydoc tile_copy_fn
388 ytile_copy_faster(uint32_t x0
, uint32_t x1
, uint32_t x2
, uint32_t x3
,
389 uint32_t y0
, uint32_t y1
,
390 char *dst
, const char *src
,
392 uint32_t swizzle_bit
,
393 mem_copy_fn mem_copy
)
395 if (x0
== 0 && x3
== ytile_width
&& y0
== 0 && y1
== ytile_height
) {
396 if (mem_copy
== memcpy
)
397 return ytile_copy(0, 0, ytile_width
, ytile_width
, 0, ytile_height
,
398 dst
, src
, src_pitch
, swizzle_bit
, memcpy
);
399 else if (mem_copy
== rgba8_copy
)
400 return ytile_copy(0, 0, ytile_width
, ytile_width
, 0, ytile_height
,
401 dst
, src
, src_pitch
, swizzle_bit
, rgba8_copy
);
403 if (mem_copy
== memcpy
)
404 return ytile_copy(x0
, x1
, x2
, x3
, y0
, y1
,
405 dst
, src
, src_pitch
, swizzle_bit
, memcpy
);
406 else if (mem_copy
== rgba8_copy
)
407 return ytile_copy(x0
, x1
, x2
, x3
, y0
, y1
,
408 dst
, src
, src_pitch
, swizzle_bit
, rgba8_copy
);
410 ytile_copy(x0
, x1
, x2
, x3
, y0
, y1
,
411 dst
, src
, src_pitch
, swizzle_bit
, mem_copy
);
415 * Copy from linear to tiled texture.
417 * Divide the region given by X range [xt1, xt2) and Y range [yt1, yt2) into
418 * pieces that do not cross tile boundaries and copy each piece with a tile
419 * copy function (\ref tile_copy_fn).
420 * The X range is in bytes, i.e. pixels * bytes-per-pixel.
421 * The Y range is in pixels (i.e. unitless).
422 * 'dst' is the start of the texture and 'src' is the corresponding
423 * address to copy from, though copying begins at (xt1, yt1).
426 linear_to_tiled(uint32_t xt1
, uint32_t xt2
,
427 uint32_t yt1
, uint32_t yt2
,
428 char *dst
, const char *src
,
429 uint32_t dst_pitch
, uint32_t src_pitch
,
432 mem_copy_fn mem_copy
)
434 tile_copy_fn tile_copy
;
438 uint32_t tw
, th
, span
;
439 uint32_t swizzle_bit
= has_swizzling
? 1<<6 : 0;
441 if (tiling
== I915_TILING_X
) {
445 tile_copy
= xtile_copy_faster
;
446 } else if (tiling
== I915_TILING_Y
) {
450 tile_copy
= ytile_copy_faster
;
452 unreachable("unsupported tiling");
455 /* Round out to tile boundaries. */
456 xt0
= ALIGN_DOWN(xt1
, tw
);
457 xt3
= ALIGN_UP (xt2
, tw
);
458 yt0
= ALIGN_DOWN(yt1
, th
);
459 yt3
= ALIGN_UP (yt2
, th
);
461 /* Loop over all tiles to which we have something to copy.
462 * 'xt' and 'yt' are the origin of the destination tile, whether copying
463 * copying a full or partial tile.
464 * tile_copy() copies one tile or partial tile.
465 * Looping x inside y is the faster memory access pattern.
467 for (yt
= yt0
; yt
< yt3
; yt
+= th
) {
468 for (xt
= xt0
; xt
< xt3
; xt
+= tw
) {
469 /* The area to update is [x0,x3) x [y0,y1).
470 * May not want the whole tile, hence the min and max.
472 uint32_t x0
= MAX2(xt1
, xt
);
473 uint32_t y0
= MAX2(yt1
, yt
);
474 uint32_t x3
= MIN2(xt2
, xt
+ tw
);
475 uint32_t y1
= MIN2(yt2
, yt
+ th
);
477 /* [x0,x3) is split into [x0,x1), [x1,x2), [x2,x3) such that
478 * the middle interval is the longest span-aligned part.
479 * The sub-ranges could be empty.
482 x1
= ALIGN_UP(x0
, span
);
486 x2
= ALIGN_DOWN(x3
, span
);
488 assert(x0
<= x1
&& x1
<= x2
&& x2
<= x3
);
489 assert(x1
- x0
< span
&& x3
- x2
< span
);
490 assert(x3
- x0
<= tw
);
491 assert((x2
- x1
) % span
== 0);
493 /* Translate by (xt,yt) for single-tile copier. */
494 tile_copy(x0
-xt
, x1
-xt
, x2
-xt
, x3
-xt
,
496 dst
+ xt
* th
+ yt
* dst_pitch
,
497 src
+ xt
+ yt
* src_pitch
,
506 * \brief A fast path for glTexImage and glTexSubImage.
508 * \param for_glTexImage Was this called from glTexImage or glTexSubImage?
510 * This fast path is taken when the texture format is BGRA, RGBA,
511 * A or L and when the texture memory is X- or Y-tiled. It uploads
512 * the texture data by mapping the texture memory without a GTT fence, thus
513 * acquiring a tiled view of the memory, and then copying sucessive
514 * spans within each tile.
516 * This is a performance win over the conventional texture upload path because
517 * it avoids the performance penalty of writing through the write-combine
518 * buffer. In the conventional texture upload path,
519 * texstore.c:store_texsubimage(), the texture memory is mapped through a GTT
520 * fence, thus acquiring a linear view of the memory, then each row in the
521 * image is memcpy'd. In this fast path, we replace each row's copy with
522 * a sequence of copies over each linear span in tile.
524 * One use case is Google Chrome's paint rectangles. Chrome (as
525 * of version 21) renders each page as a tiling of 256x256 GL_BGRA textures.
526 * Each page's content is initially uploaded with glTexImage2D and damaged
527 * regions are updated with glTexSubImage2D. On some workloads, the
528 * performance gain of this fastpath on Sandybridge is over 5x.
531 intel_texsubimage_tiled_memcpy(struct gl_context
* ctx
,
533 struct gl_texture_image
*texImage
,
534 GLint xoffset
, GLint yoffset
, GLint zoffset
,
535 GLsizei width
, GLsizei height
, GLsizei depth
,
536 GLenum format
, GLenum type
,
537 const GLvoid
*pixels
,
538 const struct gl_pixelstore_attrib
*packing
,
541 struct brw_context
*brw
= brw_context(ctx
);
542 struct intel_texture_image
*image
= intel_texture_image(texImage
);
545 /* The miptree's buffer. */
551 mem_copy_fn mem_copy
= NULL
;
553 /* This fastpath is restricted to specific texture types:
554 * a 2D BGRA, RGBA, L8 or A8 texture. It could be generalized to support
557 * FINISHME: The restrictions below on packing alignment and packing row
558 * length are likely unneeded now because we calculate the source stride
559 * with _mesa_image_row_stride. However, before removing the restrictions
563 !(type
== GL_UNSIGNED_BYTE
|| type
== GL_UNSIGNED_INT_8_8_8_8_REV
) ||
564 texImage
->TexObject
->Target
!= GL_TEXTURE_2D
||
566 _mesa_is_bufferobj(packing
->BufferObj
) ||
567 packing
->Alignment
> 4 ||
568 packing
->SkipPixels
> 0 ||
569 packing
->SkipRows
> 0 ||
570 (packing
->RowLength
!= 0 && packing
->RowLength
!= width
) ||
571 packing
->SwapBytes
||
576 if (type
== GL_UNSIGNED_INT_8_8_8_8_REV
&&
577 !(format
== GL_RGBA
|| format
== GL_BGRA
))
578 return false; /* Invalid type/format combination */
580 if ((texImage
->TexFormat
== MESA_FORMAT_L_UNORM8
&& format
== GL_LUMINANCE
) ||
581 (texImage
->TexFormat
== MESA_FORMAT_A_UNORM8
&& format
== GL_ALPHA
)) {
584 } else if ((texImage
->TexFormat
== MESA_FORMAT_B8G8R8A8_UNORM
) ||
585 (texImage
->TexFormat
== MESA_FORMAT_B8G8R8X8_UNORM
)) {
587 if (format
== GL_BGRA
) {
589 } else if (format
== GL_RGBA
) {
590 mem_copy
= rgba8_copy
;
592 } else if ((texImage
->TexFormat
== MESA_FORMAT_R8G8B8A8_UNORM
) ||
593 (texImage
->TexFormat
== MESA_FORMAT_R8G8B8X8_UNORM
)) {
595 if (format
== GL_BGRA
) {
596 /* Copying from RGBA to BGRA is the same as BGRA to RGBA so we can
597 * use the same function.
599 mem_copy
= rgba8_copy
;
600 } else if (format
== GL_RGBA
) {
607 /* If this is a nontrivial texture view, let another path handle it instead. */
608 if (texImage
->TexObject
->MinLayer
)
612 ctx
->Driver
.AllocTextureImageBuffer(ctx
, texImage
);
615 (image
->mt
->tiling
!= I915_TILING_X
&&
616 image
->mt
->tiling
!= I915_TILING_Y
)) {
617 /* The algorithm is written only for X- or Y-tiled memory. */
621 /* Since we are going to write raw data to the miptree, we need to resolve
622 * any pending fast color clears before we start.
624 intel_miptree_resolve_color(brw
, image
->mt
);
628 if (drm_intel_bo_references(brw
->batch
.bo
, bo
)) {
629 perf_debug("Flushing before mapping a referenced bo.\n");
630 intel_batchbuffer_flush(brw
);
633 error
= brw_bo_map(brw
, bo
, true /* write enable */, "miptree");
634 if (error
|| bo
->virtual == NULL
) {
635 DBG("%s: failed to map bo\n", __FUNCTION__
);
639 src_pitch
= _mesa_image_row_stride(packing
, width
, format
, type
);
641 /* We postponed printing this message until having committed to executing
644 DBG("%s: level=%d offset=(%d,%d) (w,h)=(%d,%d) format=0x%x type=0x%x "
645 "mesa_format=0x%x tiling=%d "
646 "packing=(alignment=%d row_length=%d skip_pixels=%d skip_rows=%d) "
647 "for_glTexImage=%d\n",
648 __FUNCTION__
, texImage
->Level
, xoffset
, yoffset
, width
, height
,
649 format
, type
, texImage
->TexFormat
, image
->mt
->tiling
,
650 packing
->Alignment
, packing
->RowLength
, packing
->SkipPixels
,
651 packing
->SkipRows
, for_glTexImage
);
653 int level
= texImage
->Level
+ texImage
->TexObject
->MinLevel
;
655 /* Adjust x and y offset based on miplevel */
656 xoffset
+= image
->mt
->level
[level
].level_x
;
657 yoffset
+= image
->mt
->level
[level
].level_y
;
660 xoffset
* cpp
, (xoffset
+ width
) * cpp
,
661 yoffset
, yoffset
+ height
,
662 bo
->virtual, pixels
- yoffset
* src_pitch
- xoffset
* cpp
,
663 image
->mt
->pitch
, src_pitch
,
669 drm_intel_bo_unmap(bo
);
674 intelTexSubImage(struct gl_context
* ctx
,
676 struct gl_texture_image
*texImage
,
677 GLint xoffset
, GLint yoffset
, GLint zoffset
,
678 GLsizei width
, GLsizei height
, GLsizei depth
,
679 GLenum format
, GLenum type
,
680 const GLvoid
* pixels
,
681 const struct gl_pixelstore_attrib
*packing
)
685 DBG("%s mesa_format %s target %s format %s type %s level %d %dx%dx%d\n",
686 __FUNCTION__
, _mesa_get_format_name(texImage
->TexFormat
),
687 _mesa_lookup_enum_by_nr(texImage
->TexObject
->Target
),
688 _mesa_lookup_enum_by_nr(format
), _mesa_lookup_enum_by_nr(type
),
689 texImage
->Level
, texImage
->Width
, texImage
->Height
, texImage
->Depth
);
691 ok
= intel_texsubimage_tiled_memcpy(ctx
, dims
, texImage
,
692 xoffset
, yoffset
, zoffset
,
693 width
, height
, depth
,
694 format
, type
, pixels
, packing
,
695 false /*for_glTexImage*/);
699 /* The intel_blit_texsubimage() function only handles 2D images */
700 if (dims
!= 2 || !intel_blit_texsubimage(ctx
, texImage
,
703 format
, type
, pixels
, packing
)) {
704 _mesa_store_texsubimage(ctx
, dims
, texImage
,
705 xoffset
, yoffset
, zoffset
,
706 width
, height
, depth
,
707 format
, type
, pixels
, packing
);
712 intelInitTextureSubImageFuncs(struct dd_function_table
*functions
)
714 functions
->TexSubImage
= intelTexSubImage
;