intel: Clean up confusion between logical and physical surface dimensions.
[mesa.git] / src / mesa / drivers / dri / intel / intel_mipmap_tree.c
1 /**************************************************************************
2 *
3 * Copyright 2006 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 <GL/gl.h>
29 #include <GL/internal/dri_interface.h>
30
31 #include "intel_batchbuffer.h"
32 #include "intel_context.h"
33 #include "intel_mipmap_tree.h"
34 #include "intel_regions.h"
35 #include "intel_resolve_map.h"
36 #include "intel_span.h"
37 #include "intel_tex_layout.h"
38 #include "intel_tex.h"
39 #include "intel_blit.h"
40
41 #ifndef I915
42 #include "brw_blorp.h"
43 #endif
44
45 #include "main/enums.h"
46 #include "main/formats.h"
47 #include "main/glformats.h"
48 #include "main/texcompress_etc.h"
49 #include "main/teximage.h"
50
51 #define FILE_DEBUG_FLAG DEBUG_MIPTREE
52
53 static GLenum
54 target_to_target(GLenum target)
55 {
56 switch (target) {
57 case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
58 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
59 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
60 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
61 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
62 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
63 return GL_TEXTURE_CUBE_MAP_ARB;
64 default:
65 return target;
66 }
67 }
68
69
70 /**
71 * Determine which MSAA layout should be used by the MSAA surface being
72 * created, based on the chip generation and the surface type.
73 */
74 static enum intel_msaa_layout
75 compute_msaa_layout(struct intel_context *intel, gl_format format)
76 {
77 /* Prior to Gen7, all MSAA surfaces used IMS layout. */
78 if (intel->gen < 7)
79 return INTEL_MSAA_LAYOUT_IMS;
80
81 /* In Gen7, IMS layout is only used for depth and stencil buffers. */
82 switch (_mesa_get_format_base_format(format)) {
83 case GL_DEPTH_COMPONENT:
84 case GL_STENCIL_INDEX:
85 case GL_DEPTH_STENCIL:
86 return INTEL_MSAA_LAYOUT_IMS;
87 default:
88 /* From the Ivy Bridge PRM, Vol4 Part1 p77 ("MCS Enable"):
89 *
90 * This field must be set to 0 for all SINT MSRTs when all RT channels
91 * are not written
92 *
93 * In practice this means that we have to disable MCS for all signed
94 * integer MSAA buffers. The alternative, to disable MCS only when one
95 * of the render target channels is disabled, is impractical because it
96 * would require converting between CMS and UMS MSAA layouts on the fly,
97 * which is expensive.
98 */
99 if (_mesa_get_format_datatype(format) == GL_INT) {
100 /* TODO: is this workaround needed for future chipsets? */
101 assert(intel->gen == 7);
102 return INTEL_MSAA_LAYOUT_UMS;
103 } else {
104 return INTEL_MSAA_LAYOUT_CMS;
105 }
106 }
107 }
108
109
110 /**
111 * @param for_region Indicates that the caller is
112 * intel_miptree_create_for_region(). If true, then do not create
113 * \c stencil_mt.
114 */
115 static struct intel_mipmap_tree *
116 intel_miptree_create_internal(struct intel_context *intel,
117 GLenum target,
118 gl_format format,
119 GLuint first_level,
120 GLuint last_level,
121 GLuint width0,
122 GLuint height0,
123 GLuint depth0,
124 bool for_region,
125 GLuint num_samples)
126 {
127 struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
128 int compress_byte = 0;
129
130 DBG("%s target %s format %s level %d..%d <-- %p\n", __FUNCTION__,
131 _mesa_lookup_enum_by_nr(target),
132 _mesa_get_format_name(format),
133 first_level, last_level, mt);
134
135 if (_mesa_is_format_compressed(format))
136 compress_byte = intel_compressed_num_bytes(format);
137
138 mt->target = target_to_target(target);
139 mt->format = format;
140 mt->first_level = first_level;
141 mt->last_level = last_level;
142 mt->logical_width0 = width0;
143 mt->logical_height0 = height0;
144 mt->logical_depth0 = depth0;
145 mt->cpp = compress_byte ? compress_byte : _mesa_get_format_bytes(mt->format);
146 mt->num_samples = num_samples;
147 mt->compressed = compress_byte ? 1 : 0;
148 mt->msaa_layout = INTEL_MSAA_LAYOUT_NONE;
149 mt->refcount = 1;
150
151 if (num_samples > 1) {
152 /* Adjust width/height/depth for MSAA */
153 mt->msaa_layout = compute_msaa_layout(intel, format);
154 if (mt->msaa_layout == INTEL_MSAA_LAYOUT_IMS) {
155 /* In the Sandy Bridge PRM, volume 4, part 1, page 31, it says:
156 *
157 * "Any of the other messages (sample*, LOD, load4) used with a
158 * (4x) multisampled surface will in-effect sample a surface with
159 * double the height and width as that indicated in the surface
160 * state. Each pixel position on the original-sized surface is
161 * replaced with a 2x2 of samples with the following arrangement:
162 *
163 * sample 0 sample 2
164 * sample 1 sample 3"
165 *
166 * Thus, when sampling from a multisampled texture, it behaves as
167 * though the layout in memory for (x,y,sample) is:
168 *
169 * (0,0,0) (0,0,2) (1,0,0) (1,0,2)
170 * (0,0,1) (0,0,3) (1,0,1) (1,0,3)
171 *
172 * (0,1,0) (0,1,2) (1,1,0) (1,1,2)
173 * (0,1,1) (0,1,3) (1,1,1) (1,1,3)
174 *
175 * However, the actual layout of multisampled data in memory is:
176 *
177 * (0,0,0) (1,0,0) (0,0,1) (1,0,1)
178 * (0,1,0) (1,1,0) (0,1,1) (1,1,1)
179 *
180 * (0,0,2) (1,0,2) (0,0,3) (1,0,3)
181 * (0,1,2) (1,1,2) (0,1,3) (1,1,3)
182 *
183 * This pattern repeats for each 2x2 pixel block.
184 *
185 * As a result, when calculating the size of our 4-sample buffer for
186 * an odd width or height, we have to align before scaling up because
187 * sample 3 is in that bottom right 2x2 block.
188 */
189 switch (num_samples) {
190 case 4:
191 width0 = ALIGN(width0, 2) * 2;
192 height0 = ALIGN(height0, 2) * 2;
193 break;
194 case 8:
195 width0 = ALIGN(width0, 2) * 4;
196 height0 = ALIGN(height0, 2) * 2;
197 break;
198 default:
199 /* num_samples should already have been quantized to 0, 1, 4, or
200 * 8.
201 */
202 assert(false);
203 }
204 } else {
205 /* Non-interleaved */
206 depth0 *= num_samples;
207 }
208 }
209
210 /* array_spacing_lod0 is only used for non-IMS MSAA surfaces. TODO: can we
211 * use it elsewhere?
212 */
213 switch (mt->msaa_layout) {
214 case INTEL_MSAA_LAYOUT_NONE:
215 case INTEL_MSAA_LAYOUT_IMS:
216 mt->array_spacing_lod0 = false;
217 break;
218 case INTEL_MSAA_LAYOUT_UMS:
219 case INTEL_MSAA_LAYOUT_CMS:
220 mt->array_spacing_lod0 = true;
221 break;
222 }
223
224 if (target == GL_TEXTURE_CUBE_MAP) {
225 assert(depth0 == 1);
226 depth0 = 6;
227 }
228
229 mt->physical_width0 = width0;
230 mt->physical_height0 = height0;
231 mt->physical_depth0 = depth0;
232
233 if (!for_region &&
234 _mesa_is_depthstencil_format(_mesa_get_format_base_format(format)) &&
235 (intel->must_use_separate_stencil ||
236 (intel->has_separate_stencil &&
237 intel->vtbl.is_hiz_depth_format(intel, format)))) {
238 mt->stencil_mt = intel_miptree_create(intel,
239 mt->target,
240 MESA_FORMAT_S8,
241 mt->first_level,
242 mt->last_level,
243 mt->logical_width0,
244 mt->logical_height0,
245 mt->logical_depth0,
246 true,
247 num_samples,
248 false /* force_y_tiling */);
249 if (!mt->stencil_mt) {
250 intel_miptree_release(&mt);
251 return NULL;
252 }
253
254 /* Fix up the Z miptree format for how we're splitting out separate
255 * stencil. Gen7 expects there to be no stencil bits in its depth buffer.
256 */
257 if (mt->format == MESA_FORMAT_S8_Z24) {
258 mt->format = MESA_FORMAT_X8_Z24;
259 } else if (mt->format == MESA_FORMAT_Z32_FLOAT_X24S8) {
260 mt->format = MESA_FORMAT_Z32_FLOAT;
261 mt->cpp = 4;
262 } else {
263 _mesa_problem(NULL, "Unknown format %s in separate stencil mt\n",
264 _mesa_get_format_name(mt->format));
265 }
266 }
267
268 intel_get_texture_alignment_unit(intel, mt->format,
269 &mt->align_w, &mt->align_h);
270
271 #ifdef I915
272 (void) intel;
273 if (intel->is_945)
274 i945_miptree_layout(mt);
275 else
276 i915_miptree_layout(mt);
277 #else
278 brw_miptree_layout(intel, mt);
279 #endif
280
281 return mt;
282 }
283
284
285 struct intel_mipmap_tree *
286 intel_miptree_create(struct intel_context *intel,
287 GLenum target,
288 gl_format format,
289 GLuint first_level,
290 GLuint last_level,
291 GLuint width0,
292 GLuint height0,
293 GLuint depth0,
294 bool expect_accelerated_upload,
295 GLuint num_samples,
296 bool force_y_tiling)
297 {
298 struct intel_mipmap_tree *mt;
299 uint32_t tiling = I915_TILING_NONE;
300 GLenum base_format;
301 gl_format tex_format = format;
302 gl_format etc_format = MESA_FORMAT_NONE;
303 GLuint total_width, total_height;
304
305 switch (format) {
306 case MESA_FORMAT_ETC1_RGB8:
307 format = MESA_FORMAT_RGBX8888_REV;
308 break;
309 case MESA_FORMAT_ETC2_RGB8:
310 format = MESA_FORMAT_RGBX8888_REV;
311 break;
312 case MESA_FORMAT_ETC2_SRGB8:
313 case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
314 case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
315 format = MESA_FORMAT_SARGB8;
316 break;
317 case MESA_FORMAT_ETC2_RGBA8_EAC:
318 case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
319 format = MESA_FORMAT_RGBA8888_REV;
320 break;
321 case MESA_FORMAT_ETC2_R11_EAC:
322 format = MESA_FORMAT_R16;
323 break;
324 case MESA_FORMAT_ETC2_SIGNED_R11_EAC:
325 format = MESA_FORMAT_SIGNED_R16;
326 break;
327 case MESA_FORMAT_ETC2_RG11_EAC:
328 format = MESA_FORMAT_RG1616;
329 break;
330 case MESA_FORMAT_ETC2_SIGNED_RG11_EAC:
331 format = MESA_FORMAT_SIGNED_GR1616;
332 break;
333 default:
334 /* Non ETC1 / ETC2 format */
335 break;
336 }
337
338 etc_format = (format != tex_format) ? tex_format : MESA_FORMAT_NONE;
339 base_format = _mesa_get_format_base_format(format);
340
341 if (num_samples > 1) {
342 /* From p82 of the Sandy Bridge PRM, dw3[1] of SURFACE_STATE ("Tiled
343 * Surface"):
344 *
345 * [DevSNB+]: For multi-sample render targets, this field must be
346 * 1. MSRTs can only be tiled.
347 *
348 * Our usual reason for preferring X tiling (fast blits using the
349 * blitting engine) doesn't apply to MSAA, since we'll generally be
350 * downsampling or upsampling when blitting between the MSAA buffer
351 * and another buffer, and the blitting engine doesn't support that.
352 * So use Y tiling, since it makes better use of the cache.
353 */
354 force_y_tiling = true;
355 }
356
357 if (intel->use_texture_tiling && !_mesa_is_format_compressed(format)) {
358 if (intel->gen >= 4 &&
359 (base_format == GL_DEPTH_COMPONENT ||
360 base_format == GL_DEPTH_STENCIL_EXT))
361 tiling = I915_TILING_Y;
362 else if (force_y_tiling) {
363 tiling = I915_TILING_Y;
364 } else if (width0 >= 64)
365 tiling = I915_TILING_X;
366 }
367
368 mt = intel_miptree_create_internal(intel, target, format,
369 first_level, last_level, width0,
370 height0, depth0,
371 false, num_samples);
372 /*
373 * pitch == 0 || height == 0 indicates the null texture
374 */
375 if (!mt || !mt->total_width || !mt->total_height) {
376 intel_miptree_release(&mt);
377 return NULL;
378 }
379
380 total_width = mt->total_width;
381 total_height = mt->total_height;
382
383 if (format == MESA_FORMAT_S8) {
384 /* The stencil buffer is W tiled. However, we request from the kernel a
385 * non-tiled buffer because the GTT is incapable of W fencing. So round
386 * up the width and height to match the size of W tiles (64x64).
387 */
388 tiling = I915_TILING_NONE;
389 total_width = ALIGN(total_width, 64);
390 total_height = ALIGN(total_height, 64);
391 }
392
393 mt->wraps_etc = (etc_format != MESA_FORMAT_NONE) ? true : false;
394 mt->etc_format = etc_format;
395 mt->region = intel_region_alloc(intel->intelScreen,
396 tiling,
397 mt->cpp,
398 total_width,
399 total_height,
400 expect_accelerated_upload);
401 mt->offset = 0;
402
403 if (!mt->region) {
404 intel_miptree_release(&mt);
405 return NULL;
406 }
407
408 return mt;
409 }
410
411
412 struct intel_mipmap_tree *
413 intel_miptree_create_for_region(struct intel_context *intel,
414 GLenum target,
415 gl_format format,
416 struct intel_region *region)
417 {
418 struct intel_mipmap_tree *mt;
419
420 mt = intel_miptree_create_internal(intel, target, format,
421 0, 0,
422 region->width, region->height, 1,
423 true, 0 /* num_samples */);
424 if (!mt)
425 return mt;
426
427 intel_region_reference(&mt->region, region);
428
429 return mt;
430 }
431
432
433 /**
434 * For a singlesample DRI2 buffer, this simply wraps the given region with a miptree.
435 *
436 * For a multisample DRI2 buffer, this wraps the given region with
437 * a singlesample miptree, then creates a multisample miptree into which the
438 * singlesample miptree is embedded as a child.
439 */
440 struct intel_mipmap_tree*
441 intel_miptree_create_for_dri2_buffer(struct intel_context *intel,
442 unsigned dri_attachment,
443 gl_format format,
444 uint32_t num_samples,
445 struct intel_region *region)
446 {
447 struct intel_mipmap_tree *singlesample_mt = NULL;
448 struct intel_mipmap_tree *multisample_mt = NULL;
449 GLenum base_format = _mesa_get_format_base_format(format);
450
451 /* Only the front and back buffers, which are color buffers, are shared
452 * through DRI2.
453 */
454 assert(dri_attachment == __DRI_BUFFER_BACK_LEFT ||
455 dri_attachment == __DRI_BUFFER_FRONT_LEFT ||
456 dri_attachment == __DRI_BUFFER_FAKE_FRONT_LEFT);
457 assert(base_format == GL_RGB || base_format == GL_RGBA);
458
459 singlesample_mt = intel_miptree_create_for_region(intel, GL_TEXTURE_2D,
460 format, region);
461 if (!singlesample_mt)
462 return NULL;
463
464 if (num_samples == 0)
465 return singlesample_mt;
466
467 multisample_mt = intel_miptree_create_for_renderbuffer(intel,
468 format,
469 region->width,
470 region->height,
471 num_samples);
472 if (!multisample_mt) {
473 intel_miptree_release(&singlesample_mt);
474 return NULL;
475 }
476
477 multisample_mt->singlesample_mt = singlesample_mt;
478 multisample_mt->need_downsample = false;
479
480 if (intel->is_front_buffer_rendering &&
481 (dri_attachment == __DRI_BUFFER_FRONT_LEFT ||
482 dri_attachment == __DRI_BUFFER_FAKE_FRONT_LEFT)) {
483 intel_miptree_upsample(intel, multisample_mt);
484 }
485
486 return multisample_mt;
487 }
488
489 struct intel_mipmap_tree*
490 intel_miptree_create_for_renderbuffer(struct intel_context *intel,
491 gl_format format,
492 uint32_t width,
493 uint32_t height,
494 uint32_t num_samples)
495 {
496 struct intel_mipmap_tree *mt;
497 uint32_t depth = 1;
498 bool ok;
499
500 mt = intel_miptree_create(intel, GL_TEXTURE_2D, format, 0, 0,
501 width, height, depth, true, num_samples,
502 false /* force_y_tiling */);
503 if (!mt)
504 goto fail;
505
506 if (intel->vtbl.is_hiz_depth_format(intel, format)) {
507 ok = intel_miptree_alloc_hiz(intel, mt, num_samples);
508 if (!ok)
509 goto fail;
510 }
511
512 if (mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) {
513 ok = intel_miptree_alloc_mcs(intel, mt, num_samples);
514 if (!ok)
515 goto fail;
516 }
517
518 return mt;
519
520 fail:
521 intel_miptree_release(&mt);
522 return NULL;
523 }
524
525 void
526 intel_miptree_reference(struct intel_mipmap_tree **dst,
527 struct intel_mipmap_tree *src)
528 {
529 if (*dst == src)
530 return;
531
532 intel_miptree_release(dst);
533
534 if (src) {
535 src->refcount++;
536 DBG("%s %p refcount now %d\n", __FUNCTION__, src, src->refcount);
537 }
538
539 *dst = src;
540 }
541
542
543 void
544 intel_miptree_release(struct intel_mipmap_tree **mt)
545 {
546 if (!*mt)
547 return;
548
549 DBG("%s %p refcount will be %d\n", __FUNCTION__, *mt, (*mt)->refcount - 1);
550 if (--(*mt)->refcount <= 0) {
551 GLuint i;
552
553 DBG("%s deleting %p\n", __FUNCTION__, *mt);
554
555 intel_region_release(&((*mt)->region));
556 intel_miptree_release(&(*mt)->stencil_mt);
557 intel_miptree_release(&(*mt)->hiz_mt);
558 intel_miptree_release(&(*mt)->mcs_mt);
559 intel_miptree_release(&(*mt)->singlesample_mt);
560 intel_resolve_map_clear(&(*mt)->hiz_map);
561
562 for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
563 free((*mt)->level[i].slice);
564 }
565
566 free(*mt);
567 }
568 *mt = NULL;
569 }
570
571 void
572 intel_miptree_get_dimensions_for_image(struct gl_texture_image *image,
573 int *width, int *height, int *depth)
574 {
575 switch (image->TexObject->Target) {
576 case GL_TEXTURE_1D_ARRAY:
577 *width = image->Width;
578 *height = 1;
579 *depth = image->Height;
580 break;
581 default:
582 *width = image->Width;
583 *height = image->Height;
584 *depth = image->Depth;
585 break;
586 }
587 }
588
589 /**
590 * Can the image be pulled into a unified mipmap tree? This mirrors
591 * the completeness test in a lot of ways.
592 *
593 * Not sure whether I want to pass gl_texture_image here.
594 */
595 bool
596 intel_miptree_match_image(struct intel_mipmap_tree *mt,
597 struct gl_texture_image *image)
598 {
599 struct intel_texture_image *intelImage = intel_texture_image(image);
600 GLuint level = intelImage->base.Base.Level;
601 int width, height, depth;
602
603 /* glTexImage* choose the texture object based on the target passed in, and
604 * objects can't change targets over their lifetimes, so this should be
605 * true.
606 */
607 assert(target_to_target(image->TexObject->Target) == mt->target);
608
609 gl_format mt_format = mt->format;
610 if (mt->format == MESA_FORMAT_X8_Z24 && mt->stencil_mt)
611 mt_format = MESA_FORMAT_S8_Z24;
612 if (mt->format == MESA_FORMAT_Z32_FLOAT && mt->stencil_mt)
613 mt_format = MESA_FORMAT_Z32_FLOAT_X24S8;
614 if (mt->etc_format != MESA_FORMAT_NONE)
615 mt_format = mt->etc_format;
616
617 if (image->TexFormat != mt_format)
618 return false;
619
620 intel_miptree_get_dimensions_for_image(image, &width, &height, &depth);
621
622 if (mt->target == GL_TEXTURE_CUBE_MAP)
623 depth = 6;
624
625 /* Test image dimensions against the base level image adjusted for
626 * minification. This will also catch images not present in the
627 * tree, changed targets, etc.
628 */
629 if (width != mt->level[level].width ||
630 height != mt->level[level].height ||
631 depth != mt->level[level].depth)
632 return false;
633
634 return true;
635 }
636
637
638 void
639 intel_miptree_set_level_info(struct intel_mipmap_tree *mt,
640 GLuint level,
641 GLuint x, GLuint y,
642 GLuint w, GLuint h, GLuint d)
643 {
644 mt->level[level].width = w;
645 mt->level[level].height = h;
646 mt->level[level].depth = d;
647 mt->level[level].level_x = x;
648 mt->level[level].level_y = y;
649
650 DBG("%s level %d size: %d,%d,%d offset %d,%d\n", __FUNCTION__,
651 level, w, h, d, x, y);
652
653 assert(mt->level[level].slice == NULL);
654
655 mt->level[level].slice = calloc(d, sizeof(*mt->level[0].slice));
656 mt->level[level].slice[0].x_offset = mt->level[level].level_x;
657 mt->level[level].slice[0].y_offset = mt->level[level].level_y;
658 }
659
660
661 void
662 intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
663 GLuint level, GLuint img,
664 GLuint x, GLuint y)
665 {
666 if (img == 0 && level == 0)
667 assert(x == 0 && y == 0);
668
669 assert(img < mt->level[level].depth);
670
671 mt->level[level].slice[img].x_offset = mt->level[level].level_x + x;
672 mt->level[level].slice[img].y_offset = mt->level[level].level_y + y;
673
674 DBG("%s level %d img %d pos %d,%d\n",
675 __FUNCTION__, level, img,
676 mt->level[level].slice[img].x_offset,
677 mt->level[level].slice[img].y_offset);
678 }
679
680 void
681 intel_miptree_get_image_offset(struct intel_mipmap_tree *mt,
682 GLuint level, GLuint slice,
683 GLuint *x, GLuint *y)
684 {
685 assert(slice < mt->level[level].depth);
686
687 *x = mt->level[level].slice[slice].x_offset;
688 *y = mt->level[level].slice[slice].y_offset;
689 }
690
691 static void
692 intel_miptree_copy_slice(struct intel_context *intel,
693 struct intel_mipmap_tree *dst_mt,
694 struct intel_mipmap_tree *src_mt,
695 int level,
696 int face,
697 int depth)
698
699 {
700 gl_format format = src_mt->format;
701 uint32_t width = src_mt->level[level].width;
702 uint32_t height = src_mt->level[level].height;
703 int slice;
704
705 if (face > 0)
706 slice = face;
707 else
708 slice = depth;
709
710 assert(depth < src_mt->level[level].depth);
711
712 if (dst_mt->compressed) {
713 height = ALIGN(height, dst_mt->align_h) / dst_mt->align_h;
714 width = ALIGN(width, dst_mt->align_w);
715 }
716
717 uint32_t dst_x, dst_y, src_x, src_y;
718 intel_miptree_get_image_offset(dst_mt, level, slice, &dst_x, &dst_y);
719 intel_miptree_get_image_offset(src_mt, level, slice, &src_x, &src_y);
720
721 DBG("validate blit mt %s %p %d,%d/%d -> mt %s %p %d,%d/%d (%dx%d)\n",
722 _mesa_get_format_name(src_mt->format),
723 src_mt, src_x, src_y, src_mt->region->pitch * src_mt->region->cpp,
724 _mesa_get_format_name(dst_mt->format),
725 dst_mt, dst_x, dst_y, dst_mt->region->pitch * dst_mt->region->cpp,
726 width, height);
727
728 if (!intelEmitCopyBlit(intel,
729 dst_mt->region->cpp,
730 src_mt->region->pitch, src_mt->region->bo,
731 0, src_mt->region->tiling,
732 dst_mt->region->pitch, dst_mt->region->bo,
733 0, dst_mt->region->tiling,
734 src_x, src_y,
735 dst_x, dst_y,
736 width, height,
737 GL_COPY)) {
738
739 fallback_debug("miptree validate blit for %s failed\n",
740 _mesa_get_format_name(format));
741 void *dst = intel_region_map(intel, dst_mt->region, GL_MAP_WRITE_BIT);
742 void *src = intel_region_map(intel, src_mt->region, GL_MAP_READ_BIT);
743
744 _mesa_copy_rect(dst,
745 dst_mt->cpp,
746 dst_mt->region->pitch,
747 dst_x, dst_y,
748 width, height,
749 src, src_mt->region->pitch,
750 src_x, src_y);
751
752 intel_region_unmap(intel, dst_mt->region);
753 intel_region_unmap(intel, src_mt->region);
754 }
755
756 if (src_mt->stencil_mt) {
757 intel_miptree_copy_slice(intel,
758 dst_mt->stencil_mt, src_mt->stencil_mt,
759 level, face, depth);
760 }
761 }
762
763 /**
764 * Copies the image's current data to the given miptree, and associates that
765 * miptree with the image.
766 */
767 void
768 intel_miptree_copy_teximage(struct intel_context *intel,
769 struct intel_texture_image *intelImage,
770 struct intel_mipmap_tree *dst_mt)
771 {
772 struct intel_mipmap_tree *src_mt = intelImage->mt;
773 struct intel_texture_object *intel_obj =
774 intel_texture_object(intelImage->base.Base.TexObject);
775 int level = intelImage->base.Base.Level;
776 int face = intelImage->base.Base.Face;
777 GLuint depth = intelImage->base.Base.Depth;
778
779 for (int slice = 0; slice < depth; slice++) {
780 intel_miptree_copy_slice(intel, dst_mt, src_mt, level, face, slice);
781 }
782
783 intel_miptree_reference(&intelImage->mt, dst_mt);
784 intel_obj->needs_validate = true;
785 }
786
787 bool
788 intel_miptree_alloc_mcs(struct intel_context *intel,
789 struct intel_mipmap_tree *mt,
790 GLuint num_samples)
791 {
792 assert(mt->mcs_mt == NULL);
793 assert(intel->gen >= 7); /* MCS only used on Gen7+ */
794
795 /* Choose the correct format for the MCS buffer. All that really matters
796 * is that we allocate the right buffer size, since we'll always be
797 * accessing this miptree using MCS-specific hardware mechanisms, which
798 * infer the correct format based on num_samples.
799 */
800 gl_format format;
801 switch (num_samples) {
802 case 4:
803 /* 8 bits/pixel are required for MCS data when using 4x MSAA (2 bits for
804 * each sample).
805 */
806 format = MESA_FORMAT_R8;
807 break;
808 case 8:
809 /* 32 bits/pixel are required for MCS data when using 8x MSAA (3 bits
810 * for each sample, plus 8 padding bits).
811 */
812 format = MESA_FORMAT_R_UINT32;
813 break;
814 default:
815 assert(!"Unrecognized sample count in intel_miptree_alloc_mcs");
816 break;
817 };
818
819 /* From the Ivy Bridge PRM, Vol4 Part1 p76, "MCS Base Address":
820 *
821 * "The MCS surface must be stored as Tile Y."
822 */
823 mt->mcs_mt = intel_miptree_create(intel,
824 mt->target,
825 format,
826 mt->first_level,
827 mt->last_level,
828 mt->logical_width0,
829 mt->logical_height0,
830 mt->logical_depth0,
831 true,
832 0 /* num_samples */,
833 true /* force_y_tiling */);
834
835 /* From the Ivy Bridge PRM, Vol 2 Part 1 p326:
836 *
837 * When MCS buffer is enabled and bound to MSRT, it is required that it
838 * is cleared prior to any rendering.
839 *
840 * Since we don't use the MCS buffer for any purpose other than rendering,
841 * it makes sense to just clear it immediately upon allocation.
842 *
843 * Note: the clear value for MCS buffers is all 1's, so we memset to 0xff.
844 */
845 void *data = intel_region_map(intel, mt->mcs_mt->region, 0);
846 memset(data, 0xff, mt->mcs_mt->region->bo->size);
847 intel_region_unmap(intel, mt->mcs_mt->region);
848
849 return mt->mcs_mt;
850 }
851
852 bool
853 intel_miptree_alloc_hiz(struct intel_context *intel,
854 struct intel_mipmap_tree *mt,
855 GLuint num_samples)
856 {
857 assert(mt->hiz_mt == NULL);
858 mt->hiz_mt = intel_miptree_create(intel,
859 mt->target,
860 mt->format,
861 mt->first_level,
862 mt->last_level,
863 mt->logical_width0,
864 mt->logical_height0,
865 mt->logical_depth0,
866 true,
867 num_samples,
868 false /* force_y_tiling */);
869
870 if (!mt->hiz_mt)
871 return false;
872
873 /* Mark that all slices need a HiZ resolve. */
874 struct intel_resolve_map *head = &mt->hiz_map;
875 for (int level = mt->first_level; level <= mt->last_level; ++level) {
876 for (int layer = 0; layer < mt->level[level].depth; ++layer) {
877 head->next = malloc(sizeof(*head->next));
878 head->next->prev = head;
879 head->next->next = NULL;
880 head = head->next;
881
882 head->level = level;
883 head->layer = layer;
884 head->need = GEN6_HIZ_OP_HIZ_RESOLVE;
885 }
886 }
887
888 return true;
889 }
890
891 void
892 intel_miptree_slice_set_needs_hiz_resolve(struct intel_mipmap_tree *mt,
893 uint32_t level,
894 uint32_t layer)
895 {
896 intel_miptree_check_level_layer(mt, level, layer);
897
898 if (!mt->hiz_mt)
899 return;
900
901 intel_resolve_map_set(&mt->hiz_map,
902 level, layer, GEN6_HIZ_OP_HIZ_RESOLVE);
903 }
904
905
906 void
907 intel_miptree_slice_set_needs_depth_resolve(struct intel_mipmap_tree *mt,
908 uint32_t level,
909 uint32_t layer)
910 {
911 intel_miptree_check_level_layer(mt, level, layer);
912
913 if (!mt->hiz_mt)
914 return;
915
916 intel_resolve_map_set(&mt->hiz_map,
917 level, layer, GEN6_HIZ_OP_DEPTH_RESOLVE);
918 }
919
920 static bool
921 intel_miptree_slice_resolve(struct intel_context *intel,
922 struct intel_mipmap_tree *mt,
923 uint32_t level,
924 uint32_t layer,
925 enum gen6_hiz_op need)
926 {
927 intel_miptree_check_level_layer(mt, level, layer);
928
929 struct intel_resolve_map *item =
930 intel_resolve_map_get(&mt->hiz_map, level, layer);
931
932 if (!item || item->need != need)
933 return false;
934
935 intel_hiz_exec(intel, mt, level, layer, need);
936 intel_resolve_map_remove(item);
937 return true;
938 }
939
940 bool
941 intel_miptree_slice_resolve_hiz(struct intel_context *intel,
942 struct intel_mipmap_tree *mt,
943 uint32_t level,
944 uint32_t layer)
945 {
946 return intel_miptree_slice_resolve(intel, mt, level, layer,
947 GEN6_HIZ_OP_HIZ_RESOLVE);
948 }
949
950 bool
951 intel_miptree_slice_resolve_depth(struct intel_context *intel,
952 struct intel_mipmap_tree *mt,
953 uint32_t level,
954 uint32_t layer)
955 {
956 return intel_miptree_slice_resolve(intel, mt, level, layer,
957 GEN6_HIZ_OP_DEPTH_RESOLVE);
958 }
959
960 static bool
961 intel_miptree_all_slices_resolve(struct intel_context *intel,
962 struct intel_mipmap_tree *mt,
963 enum gen6_hiz_op need)
964 {
965 bool did_resolve = false;
966 struct intel_resolve_map *i, *next;
967
968 for (i = mt->hiz_map.next; i; i = next) {
969 next = i->next;
970 if (i->need != need)
971 continue;
972
973 intel_hiz_exec(intel, mt, i->level, i->layer, need);
974 intel_resolve_map_remove(i);
975 did_resolve = true;
976 }
977
978 return did_resolve;
979 }
980
981 bool
982 intel_miptree_all_slices_resolve_hiz(struct intel_context *intel,
983 struct intel_mipmap_tree *mt)
984 {
985 return intel_miptree_all_slices_resolve(intel, mt,
986 GEN6_HIZ_OP_HIZ_RESOLVE);
987 }
988
989 bool
990 intel_miptree_all_slices_resolve_depth(struct intel_context *intel,
991 struct intel_mipmap_tree *mt)
992 {
993 return intel_miptree_all_slices_resolve(intel, mt,
994 GEN6_HIZ_OP_DEPTH_RESOLVE);
995 }
996
997 static void
998 intel_miptree_updownsample(struct intel_context *intel,
999 struct intel_mipmap_tree *src,
1000 struct intel_mipmap_tree *dst,
1001 unsigned width,
1002 unsigned height)
1003 {
1004 #ifndef I915
1005 int src_x0 = 0;
1006 int src_y0 = 0;
1007 int dst_x0 = 0;
1008 int dst_y0 = 0;
1009
1010 intel_miptree_slice_resolve_depth(intel, src, 0, 0);
1011 intel_miptree_slice_resolve_depth(intel, dst, 0, 0);
1012
1013 brw_blorp_blit_miptrees(intel,
1014 src, 0 /* level */, 0 /* layer */,
1015 dst, 0 /* level */, 0 /* layer */,
1016 src_x0, src_y0,
1017 dst_x0, dst_y0,
1018 width, height,
1019 false, false /*mirror x, y*/);
1020
1021 if (src->stencil_mt) {
1022 brw_blorp_blit_miptrees(intel,
1023 src->stencil_mt, 0 /* level */, 0 /* layer */,
1024 dst->stencil_mt, 0 /* level */, 0 /* layer */,
1025 src_x0, src_y0,
1026 dst_x0, dst_y0,
1027 width, height,
1028 false, false /*mirror x, y*/);
1029 }
1030 #endif /* I915 */
1031 }
1032
1033 static void
1034 assert_is_flat(struct intel_mipmap_tree *mt)
1035 {
1036 assert(mt->target == GL_TEXTURE_2D);
1037 assert(mt->first_level == 0);
1038 assert(mt->last_level == 0);
1039 }
1040
1041 /**
1042 * \brief Downsample from mt to mt->singlesample_mt.
1043 *
1044 * If the miptree needs no downsample, then skip.
1045 */
1046 void
1047 intel_miptree_downsample(struct intel_context *intel,
1048 struct intel_mipmap_tree *mt)
1049 {
1050 /* Only flat, renderbuffer-like miptrees are supported. */
1051 assert_is_flat(mt);
1052
1053 if (!mt->need_downsample)
1054 return;
1055 intel_miptree_updownsample(intel,
1056 mt, mt->singlesample_mt,
1057 mt->logical_width0,
1058 mt->logical_height0);
1059 mt->need_downsample = false;
1060
1061 /* Strictly speaking, after a downsample on a depth miptree, a hiz
1062 * resolve is needed on the singlesample miptree. However, since the
1063 * singlesample miptree is never rendered to, the hiz resolve will never
1064 * occur. Therefore we do not mark the needed hiz resolve after
1065 * downsampling.
1066 */
1067 }
1068
1069 /**
1070 * \brief Upsample from mt->singlesample_mt to mt.
1071 *
1072 * The upsample is done unconditionally.
1073 */
1074 void
1075 intel_miptree_upsample(struct intel_context *intel,
1076 struct intel_mipmap_tree *mt)
1077 {
1078 /* Only flat, renderbuffer-like miptrees are supported. */
1079 assert_is_flat(mt);
1080 assert(!mt->need_downsample);
1081
1082 intel_miptree_updownsample(intel,
1083 mt->singlesample_mt, mt,
1084 mt->logical_width0,
1085 mt->logical_height0);
1086 intel_miptree_slice_set_needs_hiz_resolve(mt, 0, 0);
1087 }
1088
1089 static void
1090 intel_miptree_map_gtt(struct intel_context *intel,
1091 struct intel_mipmap_tree *mt,
1092 struct intel_miptree_map *map,
1093 unsigned int level, unsigned int slice)
1094 {
1095 unsigned int bw, bh;
1096 void *base;
1097 unsigned int image_x, image_y;
1098 int x = map->x;
1099 int y = map->y;
1100
1101 /* For compressed formats, the stride is the number of bytes per
1102 * row of blocks. intel_miptree_get_image_offset() already does
1103 * the divide.
1104 */
1105 _mesa_get_format_block_size(mt->format, &bw, &bh);
1106 assert(y % bh == 0);
1107 y /= bh;
1108
1109 base = intel_region_map(intel, mt->region, map->mode);
1110
1111 if (base == NULL)
1112 map->ptr = NULL;
1113 else {
1114 /* Note that in the case of cube maps, the caller must have passed the
1115 * slice number referencing the face.
1116 */
1117 intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
1118 x += image_x;
1119 y += image_y;
1120
1121 map->stride = mt->region->pitch * mt->cpp;
1122 map->ptr = base + y * map->stride + x * mt->cpp;
1123 }
1124
1125 DBG("%s: %d,%d %dx%d from mt %p (%s) %d,%d = %p/%d\n", __FUNCTION__,
1126 map->x, map->y, map->w, map->h,
1127 mt, _mesa_get_format_name(mt->format),
1128 x, y, map->ptr, map->stride);
1129 }
1130
1131 static void
1132 intel_miptree_unmap_gtt(struct intel_context *intel,
1133 struct intel_mipmap_tree *mt,
1134 struct intel_miptree_map *map,
1135 unsigned int level,
1136 unsigned int slice)
1137 {
1138 intel_region_unmap(intel, mt->region);
1139 }
1140
1141 static void
1142 intel_miptree_map_blit(struct intel_context *intel,
1143 struct intel_mipmap_tree *mt,
1144 struct intel_miptree_map *map,
1145 unsigned int level, unsigned int slice)
1146 {
1147 unsigned int image_x, image_y;
1148 int x = map->x;
1149 int y = map->y;
1150 int ret;
1151
1152 /* The blitter requires the pitch to be aligned to 4. */
1153 map->stride = ALIGN(map->w * mt->region->cpp, 4);
1154
1155 map->bo = drm_intel_bo_alloc(intel->bufmgr, "intel_miptree_map_blit() temp",
1156 map->stride * map->h, 4096);
1157 if (!map->bo) {
1158 fprintf(stderr, "Failed to allocate blit temporary\n");
1159 goto fail;
1160 }
1161
1162 intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
1163 x += image_x;
1164 y += image_y;
1165
1166 if (!intelEmitCopyBlit(intel,
1167 mt->region->cpp,
1168 mt->region->pitch, mt->region->bo,
1169 0, mt->region->tiling,
1170 map->stride / mt->region->cpp, map->bo,
1171 0, I915_TILING_NONE,
1172 x, y,
1173 0, 0,
1174 map->w, map->h,
1175 GL_COPY)) {
1176 fprintf(stderr, "Failed to blit\n");
1177 goto fail;
1178 }
1179
1180 intel_batchbuffer_flush(intel);
1181 ret = drm_intel_bo_map(map->bo, (map->mode & GL_MAP_WRITE_BIT) != 0);
1182 if (ret) {
1183 fprintf(stderr, "Failed to map blit temporary\n");
1184 goto fail;
1185 }
1186
1187 map->ptr = map->bo->virtual;
1188
1189 DBG("%s: %d,%d %dx%d from mt %p (%s) %d,%d = %p/%d\n", __FUNCTION__,
1190 map->x, map->y, map->w, map->h,
1191 mt, _mesa_get_format_name(mt->format),
1192 x, y, map->ptr, map->stride);
1193
1194 return;
1195
1196 fail:
1197 drm_intel_bo_unreference(map->bo);
1198 map->ptr = NULL;
1199 map->stride = 0;
1200 }
1201
1202 static void
1203 intel_miptree_unmap_blit(struct intel_context *intel,
1204 struct intel_mipmap_tree *mt,
1205 struct intel_miptree_map *map,
1206 unsigned int level,
1207 unsigned int slice)
1208 {
1209 assert(!(map->mode & GL_MAP_WRITE_BIT));
1210
1211 drm_intel_bo_unmap(map->bo);
1212 drm_intel_bo_unreference(map->bo);
1213 }
1214
1215 static void
1216 intel_miptree_map_s8(struct intel_context *intel,
1217 struct intel_mipmap_tree *mt,
1218 struct intel_miptree_map *map,
1219 unsigned int level, unsigned int slice)
1220 {
1221 map->stride = map->w;
1222 map->buffer = map->ptr = malloc(map->stride * map->h);
1223 if (!map->buffer)
1224 return;
1225
1226 /* One of either READ_BIT or WRITE_BIT or both is set. READ_BIT implies no
1227 * INVALIDATE_RANGE_BIT. WRITE_BIT needs the original values read in unless
1228 * invalidate is set, since we'll be writing the whole rectangle from our
1229 * temporary buffer back out.
1230 */
1231 if (!(map->mode & GL_MAP_INVALIDATE_RANGE_BIT)) {
1232 uint8_t *untiled_s8_map = map->ptr;
1233 uint8_t *tiled_s8_map = intel_region_map(intel, mt->region,
1234 GL_MAP_READ_BIT);
1235 unsigned int image_x, image_y;
1236
1237 intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
1238
1239 for (uint32_t y = 0; y < map->h; y++) {
1240 for (uint32_t x = 0; x < map->w; x++) {
1241 ptrdiff_t offset = intel_offset_S8(mt->region->pitch,
1242 x + image_x + map->x,
1243 y + image_y + map->y,
1244 intel->has_swizzling);
1245 untiled_s8_map[y * map->w + x] = tiled_s8_map[offset];
1246 }
1247 }
1248
1249 intel_region_unmap(intel, mt->region);
1250
1251 DBG("%s: %d,%d %dx%d from mt %p %d,%d = %p/%d\n", __FUNCTION__,
1252 map->x, map->y, map->w, map->h,
1253 mt, map->x + image_x, map->y + image_y, map->ptr, map->stride);
1254 } else {
1255 DBG("%s: %d,%d %dx%d from mt %p = %p/%d\n", __FUNCTION__,
1256 map->x, map->y, map->w, map->h,
1257 mt, map->ptr, map->stride);
1258 }
1259 }
1260
1261 static void
1262 intel_miptree_unmap_s8(struct intel_context *intel,
1263 struct intel_mipmap_tree *mt,
1264 struct intel_miptree_map *map,
1265 unsigned int level,
1266 unsigned int slice)
1267 {
1268 if (map->mode & GL_MAP_WRITE_BIT) {
1269 unsigned int image_x, image_y;
1270 uint8_t *untiled_s8_map = map->ptr;
1271 uint8_t *tiled_s8_map = intel_region_map(intel, mt->region, map->mode);
1272
1273 intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
1274
1275 for (uint32_t y = 0; y < map->h; y++) {
1276 for (uint32_t x = 0; x < map->w; x++) {
1277 ptrdiff_t offset = intel_offset_S8(mt->region->pitch,
1278 x + map->x,
1279 y + map->y,
1280 intel->has_swizzling);
1281 tiled_s8_map[offset] = untiled_s8_map[y * map->w + x];
1282 }
1283 }
1284
1285 intel_region_unmap(intel, mt->region);
1286 }
1287
1288 free(map->buffer);
1289 }
1290
1291 static void
1292 intel_miptree_map_etc(struct intel_context *intel,
1293 struct intel_mipmap_tree *mt,
1294 struct intel_miptree_map *map,
1295 unsigned int level,
1296 unsigned int slice)
1297 {
1298 /* For justification see intel_mipmap_tree:wraps_etc.
1299 */
1300 assert(mt->wraps_etc);
1301
1302 if (mt->etc_format == MESA_FORMAT_ETC1_RGB8) {
1303 assert(mt->format == MESA_FORMAT_RGBX8888_REV);
1304 }
1305
1306 assert(map->mode & GL_MAP_WRITE_BIT);
1307 assert(map->mode & GL_MAP_INVALIDATE_RANGE_BIT);
1308
1309 map->stride = _mesa_format_row_stride(mt->etc_format, map->w);
1310 map->buffer = malloc(_mesa_format_image_size(mt->etc_format,
1311 map->w, map->h, 1));
1312 map->ptr = map->buffer;
1313 }
1314
1315 static void
1316 intel_miptree_unmap_etc(struct intel_context *intel,
1317 struct intel_mipmap_tree *mt,
1318 struct intel_miptree_map *map,
1319 unsigned int level,
1320 unsigned int slice)
1321 {
1322 uint32_t image_x;
1323 uint32_t image_y;
1324 intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
1325
1326 image_x += map->x;
1327 image_y += map->y;
1328
1329 uint8_t *dst = intel_region_map(intel, mt->region, map->mode)
1330 + image_y * mt->region->pitch * mt->region->cpp
1331 + image_x * mt->region->cpp;
1332
1333 if (mt->etc_format == MESA_FORMAT_ETC1_RGB8)
1334 _mesa_etc1_unpack_rgba8888(dst, mt->region->pitch * mt->region->cpp,
1335 map->ptr, map->stride,
1336 map->w, map->h);
1337 else
1338 _mesa_unpack_etc2_format(dst, mt->region->pitch * mt->region->cpp,
1339 map->ptr, map->stride,
1340 map->w, map->h, mt->etc_format);
1341
1342 intel_region_unmap(intel, mt->region);
1343 free(map->buffer);
1344 }
1345
1346 /**
1347 * Mapping function for packed depth/stencil miptrees backed by real separate
1348 * miptrees for depth and stencil.
1349 *
1350 * On gen7, and to support HiZ pre-gen7, we have to have the stencil buffer
1351 * separate from the depth buffer. Yet at the GL API level, we have to expose
1352 * packed depth/stencil textures and FBO attachments, and Mesa core expects to
1353 * be able to map that memory for texture storage and glReadPixels-type
1354 * operations. We give Mesa core that access by mallocing a temporary and
1355 * copying the data between the actual backing store and the temporary.
1356 */
1357 static void
1358 intel_miptree_map_depthstencil(struct intel_context *intel,
1359 struct intel_mipmap_tree *mt,
1360 struct intel_miptree_map *map,
1361 unsigned int level, unsigned int slice)
1362 {
1363 struct intel_mipmap_tree *z_mt = mt;
1364 struct intel_mipmap_tree *s_mt = mt->stencil_mt;
1365 bool map_z32f_x24s8 = mt->format == MESA_FORMAT_Z32_FLOAT;
1366 int packed_bpp = map_z32f_x24s8 ? 8 : 4;
1367
1368 map->stride = map->w * packed_bpp;
1369 map->buffer = map->ptr = malloc(map->stride * map->h);
1370 if (!map->buffer)
1371 return;
1372
1373 /* One of either READ_BIT or WRITE_BIT or both is set. READ_BIT implies no
1374 * INVALIDATE_RANGE_BIT. WRITE_BIT needs the original values read in unless
1375 * invalidate is set, since we'll be writing the whole rectangle from our
1376 * temporary buffer back out.
1377 */
1378 if (!(map->mode & GL_MAP_INVALIDATE_RANGE_BIT)) {
1379 uint32_t *packed_map = map->ptr;
1380 uint8_t *s_map = intel_region_map(intel, s_mt->region, GL_MAP_READ_BIT);
1381 uint32_t *z_map = intel_region_map(intel, z_mt->region, GL_MAP_READ_BIT);
1382 unsigned int s_image_x, s_image_y;
1383 unsigned int z_image_x, z_image_y;
1384
1385 intel_miptree_get_image_offset(s_mt, level, slice,
1386 &s_image_x, &s_image_y);
1387 intel_miptree_get_image_offset(z_mt, level, slice,
1388 &z_image_x, &z_image_y);
1389
1390 for (uint32_t y = 0; y < map->h; y++) {
1391 for (uint32_t x = 0; x < map->w; x++) {
1392 int map_x = map->x + x, map_y = map->y + y;
1393 ptrdiff_t s_offset = intel_offset_S8(s_mt->region->pitch,
1394 map_x + s_image_x,
1395 map_y + s_image_y,
1396 intel->has_swizzling);
1397 ptrdiff_t z_offset = ((map_y + z_image_y) * z_mt->region->pitch +
1398 (map_x + z_image_x));
1399 uint8_t s = s_map[s_offset];
1400 uint32_t z = z_map[z_offset];
1401
1402 if (map_z32f_x24s8) {
1403 packed_map[(y * map->w + x) * 2 + 0] = z;
1404 packed_map[(y * map->w + x) * 2 + 1] = s;
1405 } else {
1406 packed_map[y * map->w + x] = (s << 24) | (z & 0x00ffffff);
1407 }
1408 }
1409 }
1410
1411 intel_region_unmap(intel, s_mt->region);
1412 intel_region_unmap(intel, z_mt->region);
1413
1414 DBG("%s: %d,%d %dx%d from z mt %p %d,%d, s mt %p %d,%d = %p/%d\n",
1415 __FUNCTION__,
1416 map->x, map->y, map->w, map->h,
1417 z_mt, map->x + z_image_x, map->y + z_image_y,
1418 s_mt, map->x + s_image_x, map->y + s_image_y,
1419 map->ptr, map->stride);
1420 } else {
1421 DBG("%s: %d,%d %dx%d from mt %p = %p/%d\n", __FUNCTION__,
1422 map->x, map->y, map->w, map->h,
1423 mt, map->ptr, map->stride);
1424 }
1425 }
1426
1427 static void
1428 intel_miptree_unmap_depthstencil(struct intel_context *intel,
1429 struct intel_mipmap_tree *mt,
1430 struct intel_miptree_map *map,
1431 unsigned int level,
1432 unsigned int slice)
1433 {
1434 struct intel_mipmap_tree *z_mt = mt;
1435 struct intel_mipmap_tree *s_mt = mt->stencil_mt;
1436 bool map_z32f_x24s8 = mt->format == MESA_FORMAT_Z32_FLOAT;
1437
1438 if (map->mode & GL_MAP_WRITE_BIT) {
1439 uint32_t *packed_map = map->ptr;
1440 uint8_t *s_map = intel_region_map(intel, s_mt->region, map->mode);
1441 uint32_t *z_map = intel_region_map(intel, z_mt->region, map->mode);
1442 unsigned int s_image_x, s_image_y;
1443 unsigned int z_image_x, z_image_y;
1444
1445 intel_miptree_get_image_offset(s_mt, level, slice,
1446 &s_image_x, &s_image_y);
1447 intel_miptree_get_image_offset(z_mt, level, slice,
1448 &z_image_x, &z_image_y);
1449
1450 for (uint32_t y = 0; y < map->h; y++) {
1451 for (uint32_t x = 0; x < map->w; x++) {
1452 ptrdiff_t s_offset = intel_offset_S8(s_mt->region->pitch,
1453 x + s_image_x + map->x,
1454 y + s_image_y + map->y,
1455 intel->has_swizzling);
1456 ptrdiff_t z_offset = ((y + z_image_y) * z_mt->region->pitch +
1457 (x + z_image_x));
1458
1459 if (map_z32f_x24s8) {
1460 z_map[z_offset] = packed_map[(y * map->w + x) * 2 + 0];
1461 s_map[s_offset] = packed_map[(y * map->w + x) * 2 + 1];
1462 } else {
1463 uint32_t packed = packed_map[y * map->w + x];
1464 s_map[s_offset] = packed >> 24;
1465 z_map[z_offset] = packed;
1466 }
1467 }
1468 }
1469
1470 intel_region_unmap(intel, s_mt->region);
1471 intel_region_unmap(intel, z_mt->region);
1472
1473 DBG("%s: %d,%d %dx%d from z mt %p (%s) %d,%d, s mt %p %d,%d = %p/%d\n",
1474 __FUNCTION__,
1475 map->x, map->y, map->w, map->h,
1476 z_mt, _mesa_get_format_name(z_mt->format),
1477 map->x + z_image_x, map->y + z_image_y,
1478 s_mt, map->x + s_image_x, map->y + s_image_y,
1479 map->ptr, map->stride);
1480 }
1481
1482 free(map->buffer);
1483 }
1484
1485 /**
1486 * Create and attach a map to the miptree at (level, slice). Return the
1487 * attached map.
1488 */
1489 static struct intel_miptree_map*
1490 intel_miptree_attach_map(struct intel_mipmap_tree *mt,
1491 unsigned int level,
1492 unsigned int slice,
1493 unsigned int x,
1494 unsigned int y,
1495 unsigned int w,
1496 unsigned int h,
1497 GLbitfield mode)
1498 {
1499 struct intel_miptree_map *map = calloc(1, sizeof(*map));
1500
1501 if (!map)
1502 return NULL;
1503
1504 assert(mt->level[level].slice[slice].map == NULL);
1505 mt->level[level].slice[slice].map = map;
1506
1507 map->mode = mode;
1508 map->x = x;
1509 map->y = y;
1510 map->w = w;
1511 map->h = h;
1512
1513 return map;
1514 }
1515
1516 /**
1517 * Release the map at (level, slice).
1518 */
1519 static void
1520 intel_miptree_release_map(struct intel_mipmap_tree *mt,
1521 unsigned int level,
1522 unsigned int slice)
1523 {
1524 struct intel_miptree_map **map;
1525
1526 map = &mt->level[level].slice[slice].map;
1527 free(*map);
1528 *map = NULL;
1529 }
1530
1531 static void
1532 intel_miptree_map_singlesample(struct intel_context *intel,
1533 struct intel_mipmap_tree *mt,
1534 unsigned int level,
1535 unsigned int slice,
1536 unsigned int x,
1537 unsigned int y,
1538 unsigned int w,
1539 unsigned int h,
1540 GLbitfield mode,
1541 void **out_ptr,
1542 int *out_stride)
1543 {
1544 struct intel_miptree_map *map;
1545
1546 assert(mt->num_samples <= 1);
1547
1548 map = intel_miptree_attach_map(mt, level, slice, x, y, w, h, mode);
1549 if (!map){
1550 *out_ptr = NULL;
1551 *out_stride = 0;
1552 return;
1553 }
1554
1555 intel_miptree_slice_resolve_depth(intel, mt, level, slice);
1556 if (map->mode & GL_MAP_WRITE_BIT) {
1557 intel_miptree_slice_set_needs_hiz_resolve(mt, level, slice);
1558 }
1559
1560 if (mt->format == MESA_FORMAT_S8) {
1561 intel_miptree_map_s8(intel, mt, map, level, slice);
1562 } else if (mt->wraps_etc) {
1563 intel_miptree_map_etc(intel, mt, map, level, slice);
1564 } else if (mt->stencil_mt) {
1565 intel_miptree_map_depthstencil(intel, mt, map, level, slice);
1566 } else if (intel->has_llc &&
1567 !(mode & GL_MAP_WRITE_BIT) &&
1568 !mt->compressed &&
1569 mt->region->tiling == I915_TILING_X) {
1570 intel_miptree_map_blit(intel, mt, map, level, slice);
1571 } else {
1572 intel_miptree_map_gtt(intel, mt, map, level, slice);
1573 }
1574
1575 *out_ptr = map->ptr;
1576 *out_stride = map->stride;
1577
1578 if (map->ptr == NULL)
1579 intel_miptree_release_map(mt, level, slice);
1580 }
1581
1582 static void
1583 intel_miptree_unmap_singlesample(struct intel_context *intel,
1584 struct intel_mipmap_tree *mt,
1585 unsigned int level,
1586 unsigned int slice)
1587 {
1588 struct intel_miptree_map *map = mt->level[level].slice[slice].map;
1589
1590 assert(mt->num_samples <= 1);
1591
1592 if (!map)
1593 return;
1594
1595 DBG("%s: mt %p (%s) level %d slice %d\n", __FUNCTION__,
1596 mt, _mesa_get_format_name(mt->format), level, slice);
1597
1598 if (mt->format == MESA_FORMAT_S8) {
1599 intel_miptree_unmap_s8(intel, mt, map, level, slice);
1600 } else if (mt->wraps_etc) {
1601 intel_miptree_unmap_etc(intel, mt, map, level, slice);
1602 } else if (mt->stencil_mt) {
1603 intel_miptree_unmap_depthstencil(intel, mt, map, level, slice);
1604 } else if (map->bo) {
1605 intel_miptree_unmap_blit(intel, mt, map, level, slice);
1606 } else {
1607 intel_miptree_unmap_gtt(intel, mt, map, level, slice);
1608 }
1609
1610 intel_miptree_release_map(mt, level, slice);
1611 }
1612
1613 static void
1614 intel_miptree_map_multisample(struct intel_context *intel,
1615 struct intel_mipmap_tree *mt,
1616 unsigned int level,
1617 unsigned int slice,
1618 unsigned int x,
1619 unsigned int y,
1620 unsigned int w,
1621 unsigned int h,
1622 GLbitfield mode,
1623 void **out_ptr,
1624 int *out_stride)
1625 {
1626 struct intel_miptree_map *map;
1627
1628 assert(mt->num_samples > 1);
1629
1630 /* Only flat, renderbuffer-like miptrees are supported. */
1631 if (mt->target != GL_TEXTURE_2D ||
1632 mt->first_level != 0 ||
1633 mt->last_level != 0) {
1634 _mesa_problem(&intel->ctx, "attempt to map a multisample miptree for "
1635 "which (target, first_level, last_level != "
1636 "(GL_TEXTURE_2D, 0, 0)");
1637 goto fail;
1638 }
1639
1640 map = intel_miptree_attach_map(mt, level, slice, x, y, w, h, mode);
1641 if (!map)
1642 goto fail;
1643
1644 if (!mt->singlesample_mt) {
1645 mt->singlesample_mt =
1646 intel_miptree_create_for_renderbuffer(intel,
1647 mt->format,
1648 mt->logical_width0,
1649 mt->logical_height0,
1650 0 /*num_samples*/);
1651 if (!mt->singlesample_mt)
1652 goto fail;
1653
1654 map->singlesample_mt_is_tmp = true;
1655 mt->need_downsample = true;
1656 }
1657
1658 intel_miptree_downsample(intel, mt);
1659 intel_miptree_map_singlesample(intel, mt->singlesample_mt,
1660 level, slice,
1661 x, y, w, h,
1662 mode,
1663 out_ptr, out_stride);
1664 return;
1665
1666 fail:
1667 intel_miptree_release_map(mt, level, slice);
1668 *out_ptr = NULL;
1669 *out_stride = 0;
1670 }
1671
1672 static void
1673 intel_miptree_unmap_multisample(struct intel_context *intel,
1674 struct intel_mipmap_tree *mt,
1675 unsigned int level,
1676 unsigned int slice)
1677 {
1678 struct intel_miptree_map *map = mt->level[level].slice[slice].map;
1679
1680 assert(mt->num_samples > 1);
1681
1682 if (!map)
1683 return;
1684
1685 intel_miptree_unmap_singlesample(intel, mt->singlesample_mt, level, slice);
1686
1687 mt->need_downsample = false;
1688 if (map->mode & GL_MAP_WRITE_BIT)
1689 intel_miptree_upsample(intel, mt);
1690
1691 if (map->singlesample_mt_is_tmp)
1692 intel_miptree_release(&mt->singlesample_mt);
1693
1694 intel_miptree_release_map(mt, level, slice);
1695 }
1696
1697 void
1698 intel_miptree_map(struct intel_context *intel,
1699 struct intel_mipmap_tree *mt,
1700 unsigned int level,
1701 unsigned int slice,
1702 unsigned int x,
1703 unsigned int y,
1704 unsigned int w,
1705 unsigned int h,
1706 GLbitfield mode,
1707 void **out_ptr,
1708 int *out_stride)
1709 {
1710 if (mt->num_samples <= 1)
1711 intel_miptree_map_singlesample(intel, mt,
1712 level, slice,
1713 x, y, w, h,
1714 mode,
1715 out_ptr, out_stride);
1716 else
1717 intel_miptree_map_multisample(intel, mt,
1718 level, slice,
1719 x, y, w, h,
1720 mode,
1721 out_ptr, out_stride);
1722 }
1723
1724 void
1725 intel_miptree_unmap(struct intel_context *intel,
1726 struct intel_mipmap_tree *mt,
1727 unsigned int level,
1728 unsigned int slice)
1729 {
1730 if (mt->num_samples <= 1)
1731 intel_miptree_unmap_singlesample(intel, mt, level, slice);
1732 else
1733 intel_miptree_unmap_multisample(intel, mt, level, slice);
1734 }