1 /**************************************************************************
3 * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
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:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
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.
26 **************************************************************************/
28 #include "intel_batchbuffer.h"
29 #include "intel_context.h"
30 #include "intel_mipmap_tree.h"
31 #include "intel_regions.h"
32 #include "intel_resolve_map.h"
33 #include "intel_span.h"
34 #include "intel_tex_layout.h"
35 #include "intel_tex.h"
36 #include "intel_blit.h"
38 #include "main/enums.h"
39 #include "main/formats.h"
40 #include "main/image.h"
41 #include "main/teximage.h"
43 #define FILE_DEBUG_FLAG DEBUG_MIPTREE
46 target_to_target(GLenum target
)
49 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB
:
50 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB
:
51 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB
:
52 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB
:
53 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB
:
54 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
:
55 return GL_TEXTURE_CUBE_MAP_ARB
;
62 * @param for_region Indicates that the caller is
63 * intel_miptree_create_for_region(). If true, then do not create
66 static struct intel_mipmap_tree
*
67 intel_miptree_create_internal(struct intel_context
*intel
,
77 enum intel_msaa_layout msaa_layout
)
79 struct intel_mipmap_tree
*mt
= calloc(sizeof(*mt
), 1);
80 int compress_byte
= 0;
82 DBG("%s target %s format %s level %d..%d <-- %p\n", __FUNCTION__
,
83 _mesa_lookup_enum_by_nr(target
),
84 _mesa_get_format_name(format
),
85 first_level
, last_level
, mt
);
87 if (_mesa_is_format_compressed(format
))
88 compress_byte
= intel_compressed_num_bytes(format
);
90 mt
->target
= target_to_target(target
);
92 mt
->first_level
= first_level
;
93 mt
->last_level
= last_level
;
95 mt
->height0
= height0
;
96 mt
->cpp
= compress_byte
? compress_byte
: _mesa_get_format_bytes(mt
->format
);
97 mt
->num_samples
= num_samples
;
98 mt
->compressed
= compress_byte
? 1 : 0;
99 mt
->msaa_layout
= msaa_layout
;
102 /* array_spacing_lod0 is only used for non-IMS MSAA surfaces. TODO: can we
105 switch (msaa_layout
) {
106 case INTEL_MSAA_LAYOUT_NONE
:
107 case INTEL_MSAA_LAYOUT_IMS
:
108 mt
->array_spacing_lod0
= false;
110 case INTEL_MSAA_LAYOUT_UMS
:
111 case INTEL_MSAA_LAYOUT_CMS
:
112 mt
->array_spacing_lod0
= true;
116 if (target
== GL_TEXTURE_CUBE_MAP
) {
124 _mesa_is_depthstencil_format(_mesa_get_format_base_format(format
)) &&
125 (intel
->must_use_separate_stencil
||
126 (intel
->has_separate_stencil
&&
127 intel
->vtbl
.is_hiz_depth_format(intel
, format
)))) {
128 /* MSAA stencil surfaces always use IMS layout. */
129 enum intel_msaa_layout msaa_layout
=
130 num_samples
> 0 ? INTEL_MSAA_LAYOUT_IMS
: INTEL_MSAA_LAYOUT_NONE
;
131 mt
->stencil_mt
= intel_miptree_create(intel
,
142 if (!mt
->stencil_mt
) {
143 intel_miptree_release(&mt
);
147 /* Fix up the Z miptree format for how we're splitting out separate
148 * stencil. Gen7 expects there to be no stencil bits in its depth buffer.
150 if (mt
->format
== MESA_FORMAT_S8_Z24
) {
151 mt
->format
= MESA_FORMAT_X8_Z24
;
152 } else if (mt
->format
== MESA_FORMAT_Z32_FLOAT_X24S8
) {
153 mt
->format
= MESA_FORMAT_Z32_FLOAT
;
156 _mesa_problem(NULL
, "Unknown format %s in separate stencil mt\n",
157 _mesa_get_format_name(mt
->format
));
161 intel_get_texture_alignment_unit(intel
, mt
->format
,
162 &mt
->align_w
, &mt
->align_h
);
167 i945_miptree_layout(mt
);
169 i915_miptree_layout(mt
);
171 brw_miptree_layout(intel
, mt
);
178 struct intel_mipmap_tree
*
179 intel_miptree_create(struct intel_context
*intel
,
187 bool expect_accelerated_upload
,
189 enum intel_msaa_layout msaa_layout
)
191 struct intel_mipmap_tree
*mt
;
192 uint32_t tiling
= I915_TILING_NONE
;
193 GLenum base_format
= _mesa_get_format_base_format(format
);
195 if (intel
->use_texture_tiling
&& !_mesa_is_format_compressed(format
)) {
196 if (intel
->gen
>= 4 &&
197 (base_format
== GL_DEPTH_COMPONENT
||
198 base_format
== GL_DEPTH_STENCIL_EXT
))
199 tiling
= I915_TILING_Y
;
200 else if (msaa_layout
!= INTEL_MSAA_LAYOUT_NONE
) {
201 /* From p82 of the Sandy Bridge PRM, dw3[1] of SURFACE_STATE ("Tiled
204 * [DevSNB+]: For multi-sample render targets, this field must be
205 * 1. MSRTs can only be tiled.
207 * Our usual reason for preferring X tiling (fast blits using the
208 * blitting engine) doesn't apply to MSAA, since we'll generally be
209 * downsampling or upsampling when blitting between the MSAA buffer
210 * and another buffer, and the blitting engine doesn't support that.
211 * So use Y tiling, since it makes better use of the cache.
213 tiling
= I915_TILING_Y
;
214 } else if (width0
>= 64)
215 tiling
= I915_TILING_X
;
218 if (format
== MESA_FORMAT_S8
) {
219 /* The stencil buffer is W tiled. However, we request from the kernel a
220 * non-tiled buffer because the GTT is incapable of W fencing. So round
221 * up the width and height to match the size of W tiles (64x64).
223 tiling
= I915_TILING_NONE
;
224 width0
= ALIGN(width0
, 64);
225 height0
= ALIGN(height0
, 64);
228 mt
= intel_miptree_create_internal(intel
, target
, format
,
229 first_level
, last_level
, width0
,
231 false, num_samples
, msaa_layout
);
233 * pitch == 0 || height == 0 indicates the null texture
235 if (!mt
|| !mt
->total_width
|| !mt
->total_height
) {
236 intel_miptree_release(&mt
);
240 mt
->region
= intel_region_alloc(intel
->intelScreen
,
245 expect_accelerated_upload
);
249 intel_miptree_release(&mt
);
257 struct intel_mipmap_tree
*
258 intel_miptree_create_for_region(struct intel_context
*intel
,
261 struct intel_region
*region
)
263 struct intel_mipmap_tree
*mt
;
265 mt
= intel_miptree_create_internal(intel
, target
, format
,
267 region
->width
, region
->height
, 1,
268 true, 0 /* num_samples */,
269 INTEL_MSAA_LAYOUT_NONE
);
273 intel_region_reference(&mt
->region
, region
);
279 * Determine which MSAA layout should be used by the MSAA surface being
280 * created, based on the chip generation and the surface type.
282 static enum intel_msaa_layout
283 compute_msaa_layout(struct intel_context
*intel
, gl_format format
)
285 /* Prior to Gen7, all MSAA surfaces used IMS layout. */
287 return INTEL_MSAA_LAYOUT_IMS
;
289 /* In Gen7, IMS layout is only used for depth and stencil buffers. */
290 switch (_mesa_get_format_base_format(format
)) {
291 case GL_DEPTH_COMPONENT
:
292 case GL_STENCIL_INDEX
:
293 case GL_DEPTH_STENCIL
:
294 return INTEL_MSAA_LAYOUT_IMS
;
296 return INTEL_MSAA_LAYOUT_UMS
;
300 struct intel_mipmap_tree
*
301 intel_miptree_create_for_renderbuffer(struct intel_context
*intel
,
305 uint32_t num_samples
)
307 struct intel_mipmap_tree
*mt
;
309 enum intel_msaa_layout msaa_layout
= INTEL_MSAA_LAYOUT_NONE
;
311 if (num_samples
> 0) {
312 /* Adjust width/height/depth for MSAA */
313 msaa_layout
= compute_msaa_layout(intel
, format
);
314 if (msaa_layout
== INTEL_MSAA_LAYOUT_IMS
) {
315 /* In the Sandy Bridge PRM, volume 4, part 1, page 31, it says:
317 * "Any of the other messages (sample*, LOD, load4) used with a
318 * (4x) multisampled surface will in-effect sample a surface with
319 * double the height and width as that indicated in the surface
320 * state. Each pixel position on the original-sized surface is
321 * replaced with a 2x2 of samples with the following arrangement:
326 * Thus, when sampling from a multisampled texture, it behaves as
327 * though the layout in memory for (x,y,sample) is:
329 * (0,0,0) (0,0,2) (1,0,0) (1,0,2)
330 * (0,0,1) (0,0,3) (1,0,1) (1,0,3)
332 * (0,1,0) (0,1,2) (1,1,0) (1,1,2)
333 * (0,1,1) (0,1,3) (1,1,1) (1,1,3)
335 * However, the actual layout of multisampled data in memory is:
337 * (0,0,0) (1,0,0) (0,0,1) (1,0,1)
338 * (0,1,0) (1,1,0) (0,1,1) (1,1,1)
340 * (0,0,2) (1,0,2) (0,0,3) (1,0,3)
341 * (0,1,2) (1,1,2) (0,1,3) (1,1,3)
343 * This pattern repeats for each 2x2 pixel block.
345 * As a result, when calculating the size of our 4-sample buffer for
346 * an odd width or height, we have to align before scaling up because
347 * sample 3 is in that bottom right 2x2 block.
349 switch (num_samples
) {
351 width
= ALIGN(width
, 2) * 2;
352 height
= ALIGN(height
, 2) * 2;
355 width
= ALIGN(width
, 2) * 4;
356 height
= ALIGN(height
, 2) * 2;
359 /* num_samples should already have been quantized to 0, 4, or
365 /* Non-interleaved */
370 mt
= intel_miptree_create(intel
, GL_TEXTURE_2D
, format
, 0, 0,
371 width
, height
, depth
, true, num_samples
,
378 intel_miptree_reference(struct intel_mipmap_tree
**dst
,
379 struct intel_mipmap_tree
*src
)
384 intel_miptree_release(dst
);
388 DBG("%s %p refcount now %d\n", __FUNCTION__
, src
, src
->refcount
);
396 intel_miptree_release(struct intel_mipmap_tree
**mt
)
401 DBG("%s %p refcount will be %d\n", __FUNCTION__
, *mt
, (*mt
)->refcount
- 1);
402 if (--(*mt
)->refcount
<= 0) {
405 DBG("%s deleting %p\n", __FUNCTION__
, *mt
);
407 intel_region_release(&((*mt
)->region
));
408 intel_miptree_release(&(*mt
)->stencil_mt
);
409 intel_miptree_release(&(*mt
)->hiz_mt
);
410 intel_miptree_release(&(*mt
)->mcs_mt
);
411 intel_resolve_map_clear(&(*mt
)->hiz_map
);
413 for (i
= 0; i
< MAX_TEXTURE_LEVELS
; i
++) {
414 free((*mt
)->level
[i
].slice
);
423 intel_miptree_get_dimensions_for_image(struct gl_texture_image
*image
,
424 int *width
, int *height
, int *depth
)
426 switch (image
->TexObject
->Target
) {
427 case GL_TEXTURE_1D_ARRAY
:
428 *width
= image
->Width
;
430 *depth
= image
->Height
;
433 *width
= image
->Width
;
434 *height
= image
->Height
;
435 *depth
= image
->Depth
;
441 * Can the image be pulled into a unified mipmap tree? This mirrors
442 * the completeness test in a lot of ways.
444 * Not sure whether I want to pass gl_texture_image here.
447 intel_miptree_match_image(struct intel_mipmap_tree
*mt
,
448 struct gl_texture_image
*image
)
450 struct intel_texture_image
*intelImage
= intel_texture_image(image
);
451 GLuint level
= intelImage
->base
.Base
.Level
;
452 int width
, height
, depth
;
454 if (target_to_target(image
->TexObject
->Target
) != mt
->target
)
457 if (image
->TexFormat
!= mt
->format
&&
458 !(image
->TexFormat
== MESA_FORMAT_S8_Z24
&&
459 mt
->format
== MESA_FORMAT_X8_Z24
&&
464 intel_miptree_get_dimensions_for_image(image
, &width
, &height
, &depth
);
466 if (mt
->target
== GL_TEXTURE_CUBE_MAP
)
469 /* Test image dimensions against the base level image adjusted for
470 * minification. This will also catch images not present in the
471 * tree, changed targets, etc.
473 if (width
!= mt
->level
[level
].width
||
474 height
!= mt
->level
[level
].height
||
475 depth
!= mt
->level
[level
].depth
)
483 intel_miptree_set_level_info(struct intel_mipmap_tree
*mt
,
486 GLuint w
, GLuint h
, GLuint d
)
488 mt
->level
[level
].width
= w
;
489 mt
->level
[level
].height
= h
;
490 mt
->level
[level
].depth
= d
;
491 mt
->level
[level
].level_x
= x
;
492 mt
->level
[level
].level_y
= y
;
494 DBG("%s level %d size: %d,%d,%d offset %d,%d\n", __FUNCTION__
,
495 level
, w
, h
, d
, x
, y
);
497 assert(mt
->level
[level
].slice
== NULL
);
499 mt
->level
[level
].slice
= calloc(d
, sizeof(*mt
->level
[0].slice
));
500 mt
->level
[level
].slice
[0].x_offset
= mt
->level
[level
].level_x
;
501 mt
->level
[level
].slice
[0].y_offset
= mt
->level
[level
].level_y
;
506 intel_miptree_set_image_offset(struct intel_mipmap_tree
*mt
,
507 GLuint level
, GLuint img
,
510 if (img
== 0 && level
== 0)
511 assert(x
== 0 && y
== 0);
513 assert(img
< mt
->level
[level
].depth
);
515 mt
->level
[level
].slice
[img
].x_offset
= mt
->level
[level
].level_x
+ x
;
516 mt
->level
[level
].slice
[img
].y_offset
= mt
->level
[level
].level_y
+ y
;
518 DBG("%s level %d img %d pos %d,%d\n",
519 __FUNCTION__
, level
, img
,
520 mt
->level
[level
].slice
[img
].x_offset
,
521 mt
->level
[level
].slice
[img
].y_offset
);
526 * For cube map textures, either the \c face parameter can be used, of course,
527 * or the cube face can be interpreted as a depth layer and the \c layer
531 intel_miptree_get_image_offset(struct intel_mipmap_tree
*mt
,
532 GLuint level
, GLuint face
, GLuint layer
,
533 GLuint
*x
, GLuint
*y
)
538 assert(mt
->target
== GL_TEXTURE_CUBE_MAP
);
543 /* This branch may be taken even if the texture target is a cube map. In
544 * that case, the caller chose to interpret each cube face as a layer.
550 *x
= mt
->level
[level
].slice
[slice
].x_offset
;
551 *y
= mt
->level
[level
].slice
[slice
].y_offset
;
555 intel_miptree_copy_slice(struct intel_context
*intel
,
556 struct intel_mipmap_tree
*dst_mt
,
557 struct intel_mipmap_tree
*src_mt
,
563 gl_format format
= src_mt
->format
;
564 uint32_t width
= src_mt
->level
[level
].width
;
565 uint32_t height
= src_mt
->level
[level
].height
;
567 assert(depth
< src_mt
->level
[level
].depth
);
569 if (dst_mt
->compressed
) {
570 height
= ALIGN(height
, dst_mt
->align_h
) / dst_mt
->align_h
;
571 width
= ALIGN(width
, dst_mt
->align_w
);
574 uint32_t dst_x
, dst_y
, src_x
, src_y
;
575 intel_miptree_get_image_offset(dst_mt
, level
, face
, depth
,
577 intel_miptree_get_image_offset(src_mt
, level
, face
, depth
,
580 DBG("validate blit mt %p %d,%d/%d -> mt %p %d,%d/%d (%dx%d)\n",
581 src_mt
, src_x
, src_y
, src_mt
->region
->pitch
* src_mt
->region
->cpp
,
582 dst_mt
, dst_x
, dst_y
, dst_mt
->region
->pitch
* dst_mt
->region
->cpp
,
585 if (!intelEmitCopyBlit(intel
,
587 src_mt
->region
->pitch
, src_mt
->region
->bo
,
588 0, src_mt
->region
->tiling
,
589 dst_mt
->region
->pitch
, dst_mt
->region
->bo
,
590 0, dst_mt
->region
->tiling
,
596 fallback_debug("miptree validate blit for %s failed\n",
597 _mesa_get_format_name(format
));
598 void *dst
= intel_region_map(intel
, dst_mt
->region
, GL_MAP_WRITE_BIT
);
599 void *src
= intel_region_map(intel
, src_mt
->region
, GL_MAP_READ_BIT
);
603 dst_mt
->region
->pitch
,
606 src
, src_mt
->region
->pitch
,
609 intel_region_unmap(intel
, dst_mt
->region
);
610 intel_region_unmap(intel
, src_mt
->region
);
613 if (src_mt
->stencil_mt
) {
614 intel_miptree_copy_slice(intel
,
615 dst_mt
->stencil_mt
, src_mt
->stencil_mt
,
621 * Copies the image's current data to the given miptree, and associates that
622 * miptree with the image.
625 intel_miptree_copy_teximage(struct intel_context
*intel
,
626 struct intel_texture_image
*intelImage
,
627 struct intel_mipmap_tree
*dst_mt
)
629 struct intel_mipmap_tree
*src_mt
= intelImage
->mt
;
630 int level
= intelImage
->base
.Base
.Level
;
631 int face
= intelImage
->base
.Base
.Face
;
632 GLuint depth
= intelImage
->base
.Base
.Depth
;
634 for (int slice
= 0; slice
< depth
; slice
++) {
635 intel_miptree_copy_slice(intel
, dst_mt
, src_mt
, level
, face
, slice
);
638 intel_miptree_reference(&intelImage
->mt
, dst_mt
);
642 intel_miptree_alloc_mcs(struct intel_context
*intel
,
643 struct intel_mipmap_tree
*mt
,
646 assert(mt
->mcs_mt
== NULL
);
647 assert(intel
->gen
>= 7); /* MCS only used on Gen7+ */
648 assert(num_samples
== 4); /* TODO: support 8x MSAA */
650 /* From the Ivy Bridge PRM, Vol4 Part1 p76, "MCS Base Address":
652 * "The MCS surface must be stored as Tile Y."
654 * We set msaa_format to INTEL_MSAA_LAYOUT_CMS to force
655 * intel_miptree_create() to use Y tiling. msaa_format is otherwise
656 * ignored for the MCS miptree.
658 mt
->mcs_mt
= intel_miptree_create(intel
,
668 INTEL_MSAA_LAYOUT_CMS
);
670 /* From the Ivy Bridge PRM, Vol 2 Part 1 p326:
672 * When MCS buffer is enabled and bound to MSRT, it is required that it
673 * is cleared prior to any rendering.
675 * Since we don't use the MCS buffer for any purpose other than rendering,
676 * it makes sense to just clear it immediately upon allocation.
678 * Note: the clear value for MCS buffers is all 1's, so we memset to 0xff.
680 void *data
= intel_region_map(intel
, mt
->mcs_mt
->region
, 0);
681 memset(data
, 0xff, mt
->mcs_mt
->region
->bo
->size
);
682 intel_region_unmap(intel
, mt
->mcs_mt
->region
);
688 intel_miptree_alloc_hiz(struct intel_context
*intel
,
689 struct intel_mipmap_tree
*mt
,
692 assert(mt
->hiz_mt
== NULL
);
693 /* MSAA HiZ surfaces always use IMS layout. */
694 mt
->hiz_mt
= intel_miptree_create(intel
,
704 INTEL_MSAA_LAYOUT_IMS
);
709 /* Mark that all slices need a HiZ resolve. */
710 struct intel_resolve_map
*head
= &mt
->hiz_map
;
711 for (int level
= mt
->first_level
; level
<= mt
->last_level
; ++level
) {
712 for (int layer
= 0; layer
< mt
->level
[level
].depth
; ++layer
) {
713 head
->next
= malloc(sizeof(*head
->next
));
714 head
->next
->prev
= head
;
715 head
->next
->next
= NULL
;
720 head
->need
= GEN6_HIZ_OP_HIZ_RESOLVE
;
728 intel_miptree_slice_set_needs_hiz_resolve(struct intel_mipmap_tree
*mt
,
732 intel_miptree_check_level_layer(mt
, level
, layer
);
737 intel_resolve_map_set(&mt
->hiz_map
,
738 level
, layer
, GEN6_HIZ_OP_HIZ_RESOLVE
);
743 intel_miptree_slice_set_needs_depth_resolve(struct intel_mipmap_tree
*mt
,
747 intel_miptree_check_level_layer(mt
, level
, layer
);
752 intel_resolve_map_set(&mt
->hiz_map
,
753 level
, layer
, GEN6_HIZ_OP_DEPTH_RESOLVE
);
757 intel_miptree_slice_resolve(struct intel_context
*intel
,
758 struct intel_mipmap_tree
*mt
,
761 enum gen6_hiz_op need
)
763 intel_miptree_check_level_layer(mt
, level
, layer
);
765 struct intel_resolve_map
*item
=
766 intel_resolve_map_get(&mt
->hiz_map
, level
, layer
);
768 if (!item
|| item
->need
!= need
)
771 intel_hiz_exec(intel
, mt
, level
, layer
, need
);
772 intel_resolve_map_remove(item
);
777 intel_miptree_slice_resolve_hiz(struct intel_context
*intel
,
778 struct intel_mipmap_tree
*mt
,
782 return intel_miptree_slice_resolve(intel
, mt
, level
, layer
,
783 GEN6_HIZ_OP_HIZ_RESOLVE
);
787 intel_miptree_slice_resolve_depth(struct intel_context
*intel
,
788 struct intel_mipmap_tree
*mt
,
792 return intel_miptree_slice_resolve(intel
, mt
, level
, layer
,
793 GEN6_HIZ_OP_DEPTH_RESOLVE
);
797 intel_miptree_all_slices_resolve(struct intel_context
*intel
,
798 struct intel_mipmap_tree
*mt
,
799 enum gen6_hiz_op need
)
801 bool did_resolve
= false;
802 struct intel_resolve_map
*i
, *next
;
804 for (i
= mt
->hiz_map
.next
; i
; i
= next
) {
809 intel_hiz_exec(intel
, mt
, i
->level
, i
->layer
, need
);
810 intel_resolve_map_remove(i
);
818 intel_miptree_all_slices_resolve_hiz(struct intel_context
*intel
,
819 struct intel_mipmap_tree
*mt
)
821 return intel_miptree_all_slices_resolve(intel
, mt
,
822 GEN6_HIZ_OP_HIZ_RESOLVE
);
826 intel_miptree_all_slices_resolve_depth(struct intel_context
*intel
,
827 struct intel_mipmap_tree
*mt
)
829 return intel_miptree_all_slices_resolve(intel
, mt
,
830 GEN6_HIZ_OP_DEPTH_RESOLVE
);
834 intel_miptree_map_gtt(struct intel_context
*intel
,
835 struct intel_mipmap_tree
*mt
,
836 struct intel_miptree_map
*map
,
837 unsigned int level
, unsigned int slice
)
841 unsigned int image_x
, image_y
;
845 /* For compressed formats, the stride is the number of bytes per
846 * row of blocks. intel_miptree_get_image_offset() already does
849 _mesa_get_format_block_size(mt
->format
, &bw
, &bh
);
853 base
= intel_region_map(intel
, mt
->region
, map
->mode
);
858 /* Note that in the case of cube maps, the caller must have passed the
859 * slice number referencing the face.
861 intel_miptree_get_image_offset(mt
, level
, 0, slice
, &image_x
, &image_y
);
865 map
->stride
= mt
->region
->pitch
* mt
->cpp
;
866 map
->ptr
= base
+ y
* map
->stride
+ x
* mt
->cpp
;
869 DBG("%s: %d,%d %dx%d from mt %p (%s) %d,%d = %p/%d\n", __FUNCTION__
,
870 map
->x
, map
->y
, map
->w
, map
->h
,
871 mt
, _mesa_get_format_name(mt
->format
),
872 x
, y
, map
->ptr
, map
->stride
);
876 intel_miptree_unmap_gtt(struct intel_context
*intel
,
877 struct intel_mipmap_tree
*mt
,
878 struct intel_miptree_map
*map
,
882 intel_region_unmap(intel
, mt
->region
);
886 intel_miptree_map_blit(struct intel_context
*intel
,
887 struct intel_mipmap_tree
*mt
,
888 struct intel_miptree_map
*map
,
889 unsigned int level
, unsigned int slice
)
891 unsigned int image_x
, image_y
;
896 /* The blitter requires the pitch to be aligned to 4. */
897 map
->stride
= ALIGN(map
->w
* mt
->region
->cpp
, 4);
899 map
->bo
= drm_intel_bo_alloc(intel
->bufmgr
, "intel_miptree_map_blit() temp",
900 map
->stride
* map
->h
, 4096);
902 fprintf(stderr
, "Failed to allocate blit temporary\n");
906 intel_miptree_get_image_offset(mt
, level
, 0, slice
, &image_x
, &image_y
);
910 if (!intelEmitCopyBlit(intel
,
912 mt
->region
->pitch
, mt
->region
->bo
,
913 0, mt
->region
->tiling
,
914 map
->stride
/ mt
->region
->cpp
, map
->bo
,
920 fprintf(stderr
, "Failed to blit\n");
924 intel_batchbuffer_flush(intel
);
925 ret
= drm_intel_bo_map(map
->bo
, (map
->mode
& GL_MAP_WRITE_BIT
) != 0);
927 fprintf(stderr
, "Failed to map blit temporary\n");
931 map
->ptr
= map
->bo
->virtual;
933 DBG("%s: %d,%d %dx%d from mt %p (%s) %d,%d = %p/%d\n", __FUNCTION__
,
934 map
->x
, map
->y
, map
->w
, map
->h
,
935 mt
, _mesa_get_format_name(mt
->format
),
936 x
, y
, map
->ptr
, map
->stride
);
941 drm_intel_bo_unreference(map
->bo
);
947 intel_miptree_unmap_blit(struct intel_context
*intel
,
948 struct intel_mipmap_tree
*mt
,
949 struct intel_miptree_map
*map
,
953 assert(!(map
->mode
& GL_MAP_WRITE_BIT
));
955 drm_intel_bo_unmap(map
->bo
);
956 drm_intel_bo_unreference(map
->bo
);
960 intel_miptree_map_s8(struct intel_context
*intel
,
961 struct intel_mipmap_tree
*mt
,
962 struct intel_miptree_map
*map
,
963 unsigned int level
, unsigned int slice
)
965 map
->stride
= map
->w
;
966 map
->buffer
= map
->ptr
= malloc(map
->stride
* map
->h
);
970 /* One of either READ_BIT or WRITE_BIT or both is set. READ_BIT implies no
971 * INVALIDATE_RANGE_BIT. WRITE_BIT needs the original values read in unless
972 * invalidate is set, since we'll be writing the whole rectangle from our
973 * temporary buffer back out.
975 if (!(map
->mode
& GL_MAP_INVALIDATE_RANGE_BIT
)) {
976 uint8_t *untiled_s8_map
= map
->ptr
;
977 uint8_t *tiled_s8_map
= intel_region_map(intel
, mt
->region
,
979 unsigned int image_x
, image_y
;
981 intel_miptree_get_image_offset(mt
, level
, 0, slice
, &image_x
, &image_y
);
983 for (uint32_t y
= 0; y
< map
->h
; y
++) {
984 for (uint32_t x
= 0; x
< map
->w
; x
++) {
985 ptrdiff_t offset
= intel_offset_S8(mt
->region
->pitch
,
986 x
+ image_x
+ map
->x
,
987 y
+ image_y
+ map
->y
,
988 intel
->has_swizzling
);
989 untiled_s8_map
[y
* map
->w
+ x
] = tiled_s8_map
[offset
];
993 intel_region_unmap(intel
, mt
->region
);
995 DBG("%s: %d,%d %dx%d from mt %p %d,%d = %p/%d\n", __FUNCTION__
,
996 map
->x
, map
->y
, map
->w
, map
->h
,
997 mt
, map
->x
+ image_x
, map
->y
+ image_y
, map
->ptr
, map
->stride
);
999 DBG("%s: %d,%d %dx%d from mt %p = %p/%d\n", __FUNCTION__
,
1000 map
->x
, map
->y
, map
->w
, map
->h
,
1001 mt
, map
->ptr
, map
->stride
);
1006 intel_miptree_unmap_s8(struct intel_context
*intel
,
1007 struct intel_mipmap_tree
*mt
,
1008 struct intel_miptree_map
*map
,
1012 if (map
->mode
& GL_MAP_WRITE_BIT
) {
1013 unsigned int image_x
, image_y
;
1014 uint8_t *untiled_s8_map
= map
->ptr
;
1015 uint8_t *tiled_s8_map
= intel_region_map(intel
, mt
->region
, map
->mode
);
1017 intel_miptree_get_image_offset(mt
, level
, 0, slice
, &image_x
, &image_y
);
1019 for (uint32_t y
= 0; y
< map
->h
; y
++) {
1020 for (uint32_t x
= 0; x
< map
->w
; x
++) {
1021 ptrdiff_t offset
= intel_offset_S8(mt
->region
->pitch
,
1024 intel
->has_swizzling
);
1025 tiled_s8_map
[offset
] = untiled_s8_map
[y
* map
->w
+ x
];
1029 intel_region_unmap(intel
, mt
->region
);
1036 * Mapping function for packed depth/stencil miptrees backed by real separate
1037 * miptrees for depth and stencil.
1039 * On gen7, and to support HiZ pre-gen7, we have to have the stencil buffer
1040 * separate from the depth buffer. Yet at the GL API level, we have to expose
1041 * packed depth/stencil textures and FBO attachments, and Mesa core expects to
1042 * be able to map that memory for texture storage and glReadPixels-type
1043 * operations. We give Mesa core that access by mallocing a temporary and
1044 * copying the data between the actual backing store and the temporary.
1047 intel_miptree_map_depthstencil(struct intel_context
*intel
,
1048 struct intel_mipmap_tree
*mt
,
1049 struct intel_miptree_map
*map
,
1050 unsigned int level
, unsigned int slice
)
1052 struct intel_mipmap_tree
*z_mt
= mt
;
1053 struct intel_mipmap_tree
*s_mt
= mt
->stencil_mt
;
1054 bool map_z32f_x24s8
= mt
->format
== MESA_FORMAT_Z32_FLOAT
;
1055 int packed_bpp
= map_z32f_x24s8
? 8 : 4;
1057 map
->stride
= map
->w
* packed_bpp
;
1058 map
->buffer
= map
->ptr
= malloc(map
->stride
* map
->h
);
1062 /* One of either READ_BIT or WRITE_BIT or both is set. READ_BIT implies no
1063 * INVALIDATE_RANGE_BIT. WRITE_BIT needs the original values read in unless
1064 * invalidate is set, since we'll be writing the whole rectangle from our
1065 * temporary buffer back out.
1067 if (!(map
->mode
& GL_MAP_INVALIDATE_RANGE_BIT
)) {
1068 uint32_t *packed_map
= map
->ptr
;
1069 uint8_t *s_map
= intel_region_map(intel
, s_mt
->region
, GL_MAP_READ_BIT
);
1070 uint32_t *z_map
= intel_region_map(intel
, z_mt
->region
, GL_MAP_READ_BIT
);
1071 unsigned int s_image_x
, s_image_y
;
1072 unsigned int z_image_x
, z_image_y
;
1074 intel_miptree_get_image_offset(s_mt
, level
, 0, slice
,
1075 &s_image_x
, &s_image_y
);
1076 intel_miptree_get_image_offset(z_mt
, level
, 0, slice
,
1077 &z_image_x
, &z_image_y
);
1079 for (uint32_t y
= 0; y
< map
->h
; y
++) {
1080 for (uint32_t x
= 0; x
< map
->w
; x
++) {
1081 int map_x
= map
->x
+ x
, map_y
= map
->y
+ y
;
1082 ptrdiff_t s_offset
= intel_offset_S8(s_mt
->region
->pitch
,
1085 intel
->has_swizzling
);
1086 ptrdiff_t z_offset
= ((map_y
+ z_image_y
) * z_mt
->region
->pitch
+
1087 (map_x
+ z_image_x
));
1088 uint8_t s
= s_map
[s_offset
];
1089 uint32_t z
= z_map
[z_offset
];
1091 if (map_z32f_x24s8
) {
1092 packed_map
[(y
* map
->w
+ x
) * 2 + 0] = z
;
1093 packed_map
[(y
* map
->w
+ x
) * 2 + 1] = s
;
1095 packed_map
[y
* map
->w
+ x
] = (s
<< 24) | (z
& 0x00ffffff);
1100 intel_region_unmap(intel
, s_mt
->region
);
1101 intel_region_unmap(intel
, z_mt
->region
);
1103 DBG("%s: %d,%d %dx%d from z mt %p %d,%d, s mt %p %d,%d = %p/%d\n",
1105 map
->x
, map
->y
, map
->w
, map
->h
,
1106 z_mt
, map
->x
+ z_image_x
, map
->y
+ z_image_y
,
1107 s_mt
, map
->x
+ s_image_x
, map
->y
+ s_image_y
,
1108 map
->ptr
, map
->stride
);
1110 DBG("%s: %d,%d %dx%d from mt %p = %p/%d\n", __FUNCTION__
,
1111 map
->x
, map
->y
, map
->w
, map
->h
,
1112 mt
, map
->ptr
, map
->stride
);
1117 intel_miptree_unmap_depthstencil(struct intel_context
*intel
,
1118 struct intel_mipmap_tree
*mt
,
1119 struct intel_miptree_map
*map
,
1123 struct intel_mipmap_tree
*z_mt
= mt
;
1124 struct intel_mipmap_tree
*s_mt
= mt
->stencil_mt
;
1125 bool map_z32f_x24s8
= mt
->format
== MESA_FORMAT_Z32_FLOAT
;
1127 if (map
->mode
& GL_MAP_WRITE_BIT
) {
1128 uint32_t *packed_map
= map
->ptr
;
1129 uint8_t *s_map
= intel_region_map(intel
, s_mt
->region
, map
->mode
);
1130 uint32_t *z_map
= intel_region_map(intel
, z_mt
->region
, map
->mode
);
1131 unsigned int s_image_x
, s_image_y
;
1132 unsigned int z_image_x
, z_image_y
;
1134 intel_miptree_get_image_offset(s_mt
, level
, 0, slice
,
1135 &s_image_x
, &s_image_y
);
1136 intel_miptree_get_image_offset(z_mt
, level
, 0, slice
,
1137 &z_image_x
, &z_image_y
);
1139 for (uint32_t y
= 0; y
< map
->h
; y
++) {
1140 for (uint32_t x
= 0; x
< map
->w
; x
++) {
1141 ptrdiff_t s_offset
= intel_offset_S8(s_mt
->region
->pitch
,
1142 x
+ s_image_x
+ map
->x
,
1143 y
+ s_image_y
+ map
->y
,
1144 intel
->has_swizzling
);
1145 ptrdiff_t z_offset
= ((y
+ z_image_y
) * z_mt
->region
->pitch
+
1148 if (map_z32f_x24s8
) {
1149 z_map
[z_offset
] = packed_map
[(y
* map
->w
+ x
) * 2 + 0];
1150 s_map
[s_offset
] = packed_map
[(y
* map
->w
+ x
) * 2 + 1];
1152 uint32_t packed
= packed_map
[y
* map
->w
+ x
];
1153 s_map
[s_offset
] = packed
>> 24;
1154 z_map
[z_offset
] = packed
;
1159 intel_region_unmap(intel
, s_mt
->region
);
1160 intel_region_unmap(intel
, z_mt
->region
);
1162 DBG("%s: %d,%d %dx%d from z mt %p (%s) %d,%d, s mt %p %d,%d = %p/%d\n",
1164 map
->x
, map
->y
, map
->w
, map
->h
,
1165 z_mt
, _mesa_get_format_name(z_mt
->format
),
1166 map
->x
+ z_image_x
, map
->y
+ z_image_y
,
1167 s_mt
, map
->x
+ s_image_x
, map
->y
+ s_image_y
,
1168 map
->ptr
, map
->stride
);
1175 intel_miptree_map(struct intel_context
*intel
,
1176 struct intel_mipmap_tree
*mt
,
1187 struct intel_miptree_map
*map
;
1189 map
= calloc(1, sizeof(struct intel_miptree_map
));
1196 assert(!mt
->level
[level
].slice
[slice
].map
);
1197 mt
->level
[level
].slice
[slice
].map
= map
;
1204 intel_miptree_slice_resolve_depth(intel
, mt
, level
, slice
);
1205 if (map
->mode
& GL_MAP_WRITE_BIT
) {
1206 intel_miptree_slice_set_needs_hiz_resolve(mt
, level
, slice
);
1209 if (mt
->format
== MESA_FORMAT_S8
) {
1210 intel_miptree_map_s8(intel
, mt
, map
, level
, slice
);
1211 } else if (mt
->stencil_mt
) {
1212 intel_miptree_map_depthstencil(intel
, mt
, map
, level
, slice
);
1213 } else if (intel
->has_llc
&&
1214 !(mode
& GL_MAP_WRITE_BIT
) &&
1216 mt
->region
->tiling
== I915_TILING_X
) {
1217 intel_miptree_map_blit(intel
, mt
, map
, level
, slice
);
1219 intel_miptree_map_gtt(intel
, mt
, map
, level
, slice
);
1222 *out_ptr
= map
->ptr
;
1223 *out_stride
= map
->stride
;
1225 if (map
->ptr
== NULL
) {
1226 mt
->level
[level
].slice
[slice
].map
= NULL
;
1232 intel_miptree_unmap(struct intel_context
*intel
,
1233 struct intel_mipmap_tree
*mt
,
1237 struct intel_miptree_map
*map
= mt
->level
[level
].slice
[slice
].map
;
1242 DBG("%s: mt %p (%s) level %d slice %d\n", __FUNCTION__
,
1243 mt
, _mesa_get_format_name(mt
->format
), level
, slice
);
1245 if (mt
->format
== MESA_FORMAT_S8
) {
1246 intel_miptree_unmap_s8(intel
, mt
, map
, level
, slice
);
1247 } else if (mt
->stencil_mt
) {
1248 intel_miptree_unmap_depthstencil(intel
, mt
, map
, level
, slice
);
1249 } else if (map
->bo
) {
1250 intel_miptree_unmap_blit(intel
, mt
, map
, level
, slice
);
1252 intel_miptree_unmap_gtt(intel
, mt
, map
, level
, slice
);
1255 mt
->level
[level
].slice
[slice
].map
= NULL
;