intel_mipmap_tree.c revision 455ac562722f60ac9fb0c3d3c697fa339fa011ad
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 "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"
37
38#include "main/enums.h"
39#include "main/formats.h"
40#include "main/image.h"
41#include "main/teximage.h"
42
43#define FILE_DEBUG_FLAG DEBUG_MIPTREE
44
45static GLenum
46target_to_target(GLenum target)
47{
48   switch (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;
56   default:
57      return target;
58   }
59}
60
61/**
62 * @param for_region Indicates that the caller is
63 *        intel_miptree_create_for_region(). If true, then do not create
64 *        \c stencil_mt.
65 */
66static struct intel_mipmap_tree *
67intel_miptree_create_internal(struct intel_context *intel,
68			      GLenum target,
69			      gl_format format,
70			      GLuint first_level,
71			      GLuint last_level,
72			      GLuint width0,
73			      GLuint height0,
74			      GLuint depth0,
75			      bool for_region,
76                              GLuint num_samples,
77                              bool msaa_is_interleaved)
78{
79   struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
80   int compress_byte = 0;
81
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);
86
87   if (_mesa_is_format_compressed(format))
88      compress_byte = intel_compressed_num_bytes(format);
89
90   mt->target = target_to_target(target);
91   mt->format = format;
92   mt->first_level = first_level;
93   mt->last_level = last_level;
94   mt->width0 = width0;
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_is_interleaved = msaa_is_interleaved;
100   mt->refcount = 1;
101
102   /* array_spacing_lod0 is only used for non-interleaved MSAA surfaces.
103    * TODO: can we use it elsewhere?
104    */
105   mt->array_spacing_lod0 = num_samples > 0 && !msaa_is_interleaved;
106
107   if (target == GL_TEXTURE_CUBE_MAP) {
108      assert(depth0 == 1);
109      mt->depth0 = 6;
110   } else {
111      mt->depth0 = depth0;
112   }
113
114   if (!for_region &&
115       _mesa_is_depthstencil_format(_mesa_get_format_base_format(format)) &&
116       (intel->must_use_separate_stencil ||
117	(intel->has_separate_stencil &&
118	 intel->vtbl.is_hiz_depth_format(intel, format)))) {
119      /* MSAA stencil surfaces are always interleaved. */
120      bool msaa_is_interleaved = num_samples > 0;
121      mt->stencil_mt = intel_miptree_create(intel,
122                                            mt->target,
123                                            MESA_FORMAT_S8,
124                                            mt->first_level,
125                                            mt->last_level,
126                                            mt->width0,
127                                            mt->height0,
128                                            mt->depth0,
129                                            true,
130                                            num_samples,
131                                            msaa_is_interleaved);
132      if (!mt->stencil_mt) {
133	 intel_miptree_release(&mt);
134	 return NULL;
135      }
136
137      /* Fix up the Z miptree format for how we're splitting out separate
138       * stencil.  Gen7 expects there to be no stencil bits in its depth buffer.
139       */
140      if (mt->format == MESA_FORMAT_S8_Z24) {
141	 mt->format = MESA_FORMAT_X8_Z24;
142      } else if (mt->format == MESA_FORMAT_Z32_FLOAT_X24S8) {
143	 mt->format = MESA_FORMAT_Z32_FLOAT;
144	 mt->cpp = 4;
145      } else {
146	 _mesa_problem(NULL, "Unknown format %s in separate stencil mt\n",
147		       _mesa_get_format_name(mt->format));
148      }
149   }
150
151   intel_get_texture_alignment_unit(intel, mt->format,
152				    &mt->align_w, &mt->align_h);
153
154#ifdef I915
155   (void) intel;
156   if (intel->is_945)
157      i945_miptree_layout(mt);
158   else
159      i915_miptree_layout(mt);
160#else
161   brw_miptree_layout(intel, mt);
162#endif
163
164   return mt;
165}
166
167
168struct intel_mipmap_tree *
169intel_miptree_create(struct intel_context *intel,
170		     GLenum target,
171		     gl_format format,
172		     GLuint first_level,
173		     GLuint last_level,
174		     GLuint width0,
175		     GLuint height0,
176		     GLuint depth0,
177		     bool expect_accelerated_upload,
178                     GLuint num_samples,
179                     bool msaa_is_interleaved)
180{
181   struct intel_mipmap_tree *mt;
182   uint32_t tiling = I915_TILING_NONE;
183   GLenum base_format = _mesa_get_format_base_format(format);
184
185   if (intel->use_texture_tiling && !_mesa_is_format_compressed(format)) {
186      if (intel->gen >= 4 &&
187	  (base_format == GL_DEPTH_COMPONENT ||
188	   base_format == GL_DEPTH_STENCIL_EXT))
189	 tiling = I915_TILING_Y;
190      else if (num_samples > 0) {
191         /* From p82 of the Sandy Bridge PRM, dw3[1] of SURFACE_STATE ("Tiled
192          * Surface"):
193          *
194          *   [DevSNB+]: For multi-sample render targets, this field must be
195          *   1. MSRTs can only be tiled.
196          *
197          * Our usual reason for preferring X tiling (fast blits using the
198          * blitting engine) doesn't apply to MSAA, since we'll generally be
199          * downsampling or upsampling when blitting between the MSAA buffer
200          * and another buffer, and the blitting engine doesn't support that.
201          * So use Y tiling, since it makes better use of the cache.
202          */
203         tiling = I915_TILING_Y;
204      } else if (width0 >= 64)
205	 tiling = I915_TILING_X;
206   }
207
208   if (format == MESA_FORMAT_S8) {
209      /* The stencil buffer is W tiled. However, we request from the kernel a
210       * non-tiled buffer because the GTT is incapable of W fencing.  So round
211       * up the width and height to match the size of W tiles (64x64).
212       */
213      tiling = I915_TILING_NONE;
214      width0 = ALIGN(width0, 64);
215      height0 = ALIGN(height0, 64);
216   }
217
218   mt = intel_miptree_create_internal(intel, target, format,
219				      first_level, last_level, width0,
220				      height0, depth0,
221				      false, num_samples, msaa_is_interleaved);
222   /*
223    * pitch == 0 || height == 0  indicates the null texture
224    */
225   if (!mt || !mt->total_width || !mt->total_height) {
226      intel_miptree_release(&mt);
227      return NULL;
228   }
229
230   mt->region = intel_region_alloc(intel->intelScreen,
231				   tiling,
232				   mt->cpp,
233				   mt->total_width,
234				   mt->total_height,
235				   expect_accelerated_upload);
236
237   if (!mt->region) {
238       intel_miptree_release(&mt);
239       return NULL;
240   }
241
242   return mt;
243}
244
245
246struct intel_mipmap_tree *
247intel_miptree_create_for_region(struct intel_context *intel,
248				GLenum target,
249				gl_format format,
250				struct intel_region *region)
251{
252   struct intel_mipmap_tree *mt;
253
254   mt = intel_miptree_create_internal(intel, target, format,
255				      0, 0,
256				      region->width, region->height, 1,
257				      true, 0 /* num_samples */,
258                                      false /* msaa_is_interleaved */);
259   if (!mt)
260      return mt;
261
262   intel_region_reference(&mt->region, region);
263
264   return mt;
265}
266
267/**
268 * Determine whether the MSAA surface being created should use an interleaved
269 * layout or a sliced layout, based on the chip generation and the surface
270 * type.
271 */
272static bool
273msaa_format_is_interleaved(struct intel_context *intel, gl_format format)
274{
275   /* Prior to Gen7, all surfaces used interleaved layout. */
276   if (intel->gen < 7)
277      return true;
278
279   /* In Gen7, interleaved layout is only used for depth and stencil
280    * buffers.
281    */
282   switch (_mesa_get_format_base_format(format)) {
283   case GL_DEPTH_COMPONENT:
284   case GL_STENCIL_INDEX:
285   case GL_DEPTH_STENCIL:
286      return true;
287   default:
288      return false;
289   }
290}
291
292struct intel_mipmap_tree*
293intel_miptree_create_for_renderbuffer(struct intel_context *intel,
294                                      gl_format format,
295                                      uint32_t width,
296                                      uint32_t height,
297                                      uint32_t num_samples)
298{
299   struct intel_mipmap_tree *mt;
300   uint32_t depth = 1;
301   bool msaa_is_interleaved = false;
302
303   if (num_samples > 0) {
304      /* Adjust width/height/depth for MSAA */
305      msaa_is_interleaved = msaa_format_is_interleaved(intel, format);
306      if (msaa_is_interleaved) {
307         /* In the Sandy Bridge PRM, volume 4, part 1, page 31, it says:
308          *
309          *     "Any of the other messages (sample*, LOD, load4) used with a
310          *      (4x) multisampled surface will in-effect sample a surface with
311          *      double the height and width as that indicated in the surface
312          *      state. Each pixel position on the original-sized surface is
313          *      replaced with a 2x2 of samples with the following arrangement:
314          *
315          *         sample 0 sample 2
316          *         sample 1 sample 3"
317          *
318          * Thus, when sampling from a multisampled texture, it behaves as
319          * though the layout in memory for (x,y,sample) is:
320          *
321          *      (0,0,0) (0,0,2)   (1,0,0) (1,0,2)
322          *      (0,0,1) (0,0,3)   (1,0,1) (1,0,3)
323          *
324          *      (0,1,0) (0,1,2)   (1,1,0) (1,1,2)
325          *      (0,1,1) (0,1,3)   (1,1,1) (1,1,3)
326          *
327          * However, the actual layout of multisampled data in memory is:
328          *
329          *      (0,0,0) (1,0,0)   (0,0,1) (1,0,1)
330          *      (0,1,0) (1,1,0)   (0,1,1) (1,1,1)
331          *
332          *      (0,0,2) (1,0,2)   (0,0,3) (1,0,3)
333          *      (0,1,2) (1,1,2)   (0,1,3) (1,1,3)
334          *
335          * This pattern repeats for each 2x2 pixel block.
336          *
337          * As a result, when calculating the size of our 4-sample buffer for
338          * an odd width or height, we have to align before scaling up because
339          * sample 3 is in that bottom right 2x2 block.
340          */
341         switch (num_samples) {
342         case 4:
343            width = ALIGN(width, 2) * 2;
344            height = ALIGN(height, 2) * 2;
345            break;
346         case 8:
347            width = ALIGN(width, 2) * 4;
348            height = ALIGN(height, 2) * 2;
349            break;
350         default:
351            /* num_samples should already have been quantized to 0, 4, or
352             * 8.
353             */
354            assert(false);
355         }
356      } else {
357         /* Non-interleaved */
358         depth = num_samples;
359      }
360   }
361
362   mt = intel_miptree_create(intel, GL_TEXTURE_2D, format, 0, 0,
363			     width, height, depth, true, num_samples,
364                             msaa_is_interleaved);
365
366   return mt;
367}
368
369void
370intel_miptree_reference(struct intel_mipmap_tree **dst,
371                        struct intel_mipmap_tree *src)
372{
373   if (*dst == src)
374      return;
375
376   intel_miptree_release(dst);
377
378   if (src) {
379      src->refcount++;
380      DBG("%s %p refcount now %d\n", __FUNCTION__, src, src->refcount);
381   }
382
383   *dst = src;
384}
385
386
387void
388intel_miptree_release(struct intel_mipmap_tree **mt)
389{
390   if (!*mt)
391      return;
392
393   DBG("%s %p refcount will be %d\n", __FUNCTION__, *mt, (*mt)->refcount - 1);
394   if (--(*mt)->refcount <= 0) {
395      GLuint i;
396
397      DBG("%s deleting %p\n", __FUNCTION__, *mt);
398
399      intel_region_release(&((*mt)->region));
400      intel_miptree_release(&(*mt)->stencil_mt);
401      intel_miptree_release(&(*mt)->hiz_mt);
402      intel_resolve_map_clear(&(*mt)->hiz_map);
403
404      for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
405	 free((*mt)->level[i].slice);
406      }
407
408      free(*mt);
409   }
410   *mt = NULL;
411}
412
413void
414intel_miptree_get_dimensions_for_image(struct gl_texture_image *image,
415                                       int *width, int *height, int *depth)
416{
417   switch (image->TexObject->Target) {
418   case GL_TEXTURE_1D_ARRAY:
419      *width = image->Width;
420      *height = 1;
421      *depth = image->Height;
422      break;
423   default:
424      *width = image->Width;
425      *height = image->Height;
426      *depth = image->Depth;
427      break;
428   }
429}
430
431/**
432 * Can the image be pulled into a unified mipmap tree?  This mirrors
433 * the completeness test in a lot of ways.
434 *
435 * Not sure whether I want to pass gl_texture_image here.
436 */
437bool
438intel_miptree_match_image(struct intel_mipmap_tree *mt,
439                          struct gl_texture_image *image)
440{
441   struct intel_texture_image *intelImage = intel_texture_image(image);
442   GLuint level = intelImage->base.Base.Level;
443   int width, height, depth;
444
445   if (target_to_target(image->TexObject->Target) != mt->target)
446      return false;
447
448   if (image->TexFormat != mt->format &&
449       !(image->TexFormat == MESA_FORMAT_S8_Z24 &&
450	 mt->format == MESA_FORMAT_X8_Z24 &&
451	 mt->stencil_mt)) {
452      return false;
453   }
454
455   intel_miptree_get_dimensions_for_image(image, &width, &height, &depth);
456
457   if (mt->target == GL_TEXTURE_CUBE_MAP)
458      depth = 6;
459
460   /* Test image dimensions against the base level image adjusted for
461    * minification.  This will also catch images not present in the
462    * tree, changed targets, etc.
463    */
464   if (width != mt->level[level].width ||
465       height != mt->level[level].height ||
466       depth != mt->level[level].depth)
467      return false;
468
469   return true;
470}
471
472
473void
474intel_miptree_set_level_info(struct intel_mipmap_tree *mt,
475			     GLuint level,
476			     GLuint x, GLuint y,
477			     GLuint w, GLuint h, GLuint d)
478{
479   mt->level[level].width = w;
480   mt->level[level].height = h;
481   mt->level[level].depth = d;
482   mt->level[level].level_x = x;
483   mt->level[level].level_y = y;
484
485   DBG("%s level %d size: %d,%d,%d offset %d,%d\n", __FUNCTION__,
486       level, w, h, d, x, y);
487
488   assert(mt->level[level].slice == NULL);
489
490   mt->level[level].slice = calloc(d, sizeof(*mt->level[0].slice));
491   mt->level[level].slice[0].x_offset = mt->level[level].level_x;
492   mt->level[level].slice[0].y_offset = mt->level[level].level_y;
493}
494
495
496void
497intel_miptree_set_image_offset(struct intel_mipmap_tree *mt,
498			       GLuint level, GLuint img,
499			       GLuint x, GLuint y)
500{
501   if (img == 0 && level == 0)
502      assert(x == 0 && y == 0);
503
504   assert(img < mt->level[level].depth);
505
506   mt->level[level].slice[img].x_offset = mt->level[level].level_x + x;
507   mt->level[level].slice[img].y_offset = mt->level[level].level_y + y;
508
509   DBG("%s level %d img %d pos %d,%d\n",
510       __FUNCTION__, level, img,
511       mt->level[level].slice[img].x_offset,
512       mt->level[level].slice[img].y_offset);
513}
514
515
516/**
517 * For cube map textures, either the \c face parameter can be used, of course,
518 * or the cube face can be interpreted as a depth layer and the \c layer
519 * parameter used.
520 */
521void
522intel_miptree_get_image_offset(struct intel_mipmap_tree *mt,
523			       GLuint level, GLuint face, GLuint layer,
524			       GLuint *x, GLuint *y)
525{
526   int slice;
527
528   if (face > 0) {
529      assert(mt->target == GL_TEXTURE_CUBE_MAP);
530      assert(face < 6);
531      assert(layer == 0);
532      slice = face;
533   } else {
534      /* This branch may be taken even if the texture target is a cube map. In
535       * that case, the caller chose to interpret each cube face as a layer.
536       */
537      assert(face == 0);
538      slice = layer;
539   }
540
541   *x = mt->level[level].slice[slice].x_offset;
542   *y = mt->level[level].slice[slice].y_offset;
543}
544
545static void
546intel_miptree_copy_slice(struct intel_context *intel,
547			 struct intel_mipmap_tree *dst_mt,
548			 struct intel_mipmap_tree *src_mt,
549			 int level,
550			 int face,
551			 int depth)
552
553{
554   gl_format format = src_mt->format;
555   uint32_t width = src_mt->level[level].width;
556   uint32_t height = src_mt->level[level].height;
557
558   assert(depth < src_mt->level[level].depth);
559
560   if (dst_mt->compressed) {
561      height = ALIGN(height, dst_mt->align_h) / dst_mt->align_h;
562      width = ALIGN(width, dst_mt->align_w);
563   }
564
565   uint32_t dst_x, dst_y, src_x, src_y;
566   intel_miptree_get_image_offset(dst_mt, level, face, depth,
567				  &dst_x, &dst_y);
568   intel_miptree_get_image_offset(src_mt, level, face, depth,
569				  &src_x, &src_y);
570
571   DBG("validate blit mt %p %d,%d/%d -> mt %p %d,%d/%d (%dx%d)\n",
572       src_mt, src_x, src_y, src_mt->region->pitch * src_mt->region->cpp,
573       dst_mt, dst_x, dst_y, dst_mt->region->pitch * dst_mt->region->cpp,
574       width, height);
575
576   if (!intelEmitCopyBlit(intel,
577			  dst_mt->region->cpp,
578			  src_mt->region->pitch, src_mt->region->bo,
579			  0, src_mt->region->tiling,
580			  dst_mt->region->pitch, dst_mt->region->bo,
581			  0, dst_mt->region->tiling,
582			  src_x, src_y,
583			  dst_x, dst_y,
584			  width, height,
585			  GL_COPY)) {
586
587      fallback_debug("miptree validate blit for %s failed\n",
588		     _mesa_get_format_name(format));
589      void *dst = intel_region_map(intel, dst_mt->region, GL_MAP_WRITE_BIT);
590      void *src = intel_region_map(intel, src_mt->region, GL_MAP_READ_BIT);
591
592      _mesa_copy_rect(dst,
593		      dst_mt->cpp,
594		      dst_mt->region->pitch,
595		      dst_x, dst_y,
596		      width, height,
597		      src, src_mt->region->pitch,
598		      src_x, src_y);
599
600      intel_region_unmap(intel, dst_mt->region);
601      intel_region_unmap(intel, src_mt->region);
602   }
603
604   if (src_mt->stencil_mt) {
605      intel_miptree_copy_slice(intel,
606                               dst_mt->stencil_mt, src_mt->stencil_mt,
607                               level, face, depth);
608   }
609}
610
611/**
612 * Copies the image's current data to the given miptree, and associates that
613 * miptree with the image.
614 */
615void
616intel_miptree_copy_teximage(struct intel_context *intel,
617			    struct intel_texture_image *intelImage,
618			    struct intel_mipmap_tree *dst_mt)
619{
620   struct intel_mipmap_tree *src_mt = intelImage->mt;
621   int level = intelImage->base.Base.Level;
622   int face = intelImage->base.Base.Face;
623   GLuint depth = intelImage->base.Base.Depth;
624
625   for (int slice = 0; slice < depth; slice++) {
626      intel_miptree_copy_slice(intel, dst_mt, src_mt, level, face, slice);
627   }
628
629   intel_miptree_reference(&intelImage->mt, dst_mt);
630}
631
632bool
633intel_miptree_alloc_hiz(struct intel_context *intel,
634			struct intel_mipmap_tree *mt,
635                        GLuint num_samples)
636{
637   assert(mt->hiz_mt == NULL);
638   /* MSAA HiZ surfaces are always interleaved. */
639   bool msaa_is_interleaved = num_samples > 0;
640   mt->hiz_mt = intel_miptree_create(intel,
641                                     mt->target,
642                                     MESA_FORMAT_X8_Z24,
643                                     mt->first_level,
644                                     mt->last_level,
645                                     mt->width0,
646                                     mt->height0,
647                                     mt->depth0,
648                                     true,
649                                     num_samples,
650                                     msaa_is_interleaved);
651
652   if (!mt->hiz_mt)
653      return false;
654
655   /* Mark that all slices need a HiZ resolve. */
656   struct intel_resolve_map *head = &mt->hiz_map;
657   for (int level = mt->first_level; level <= mt->last_level; ++level) {
658      for (int layer = 0; layer < mt->level[level].depth; ++layer) {
659	 head->next = malloc(sizeof(*head->next));
660	 head->next->prev = head;
661	 head->next->next = NULL;
662	 head = head->next;
663
664	 head->level = level;
665	 head->layer = layer;
666	 head->need = GEN6_HIZ_OP_HIZ_RESOLVE;
667      }
668   }
669
670   return true;
671}
672
673void
674intel_miptree_slice_set_needs_hiz_resolve(struct intel_mipmap_tree *mt,
675					  uint32_t level,
676					  uint32_t layer)
677{
678   intel_miptree_check_level_layer(mt, level, layer);
679
680   if (!mt->hiz_mt)
681      return;
682
683   intel_resolve_map_set(&mt->hiz_map,
684			 level, layer, GEN6_HIZ_OP_HIZ_RESOLVE);
685}
686
687
688void
689intel_miptree_slice_set_needs_depth_resolve(struct intel_mipmap_tree *mt,
690                                            uint32_t level,
691                                            uint32_t layer)
692{
693   intel_miptree_check_level_layer(mt, level, layer);
694
695   if (!mt->hiz_mt)
696      return;
697
698   intel_resolve_map_set(&mt->hiz_map,
699			 level, layer, GEN6_HIZ_OP_DEPTH_RESOLVE);
700}
701
702static bool
703intel_miptree_slice_resolve(struct intel_context *intel,
704			    struct intel_mipmap_tree *mt,
705			    uint32_t level,
706			    uint32_t layer,
707			    enum gen6_hiz_op need)
708{
709   intel_miptree_check_level_layer(mt, level, layer);
710
711   struct intel_resolve_map *item =
712	 intel_resolve_map_get(&mt->hiz_map, level, layer);
713
714   if (!item || item->need != need)
715      return false;
716
717   intel_hiz_exec(intel, mt, level, layer, need);
718   intel_resolve_map_remove(item);
719   return true;
720}
721
722bool
723intel_miptree_slice_resolve_hiz(struct intel_context *intel,
724				struct intel_mipmap_tree *mt,
725				uint32_t level,
726				uint32_t layer)
727{
728   return intel_miptree_slice_resolve(intel, mt, level, layer,
729				      GEN6_HIZ_OP_HIZ_RESOLVE);
730}
731
732bool
733intel_miptree_slice_resolve_depth(struct intel_context *intel,
734				  struct intel_mipmap_tree *mt,
735				  uint32_t level,
736				  uint32_t layer)
737{
738   return intel_miptree_slice_resolve(intel, mt, level, layer,
739				      GEN6_HIZ_OP_DEPTH_RESOLVE);
740}
741
742static bool
743intel_miptree_all_slices_resolve(struct intel_context *intel,
744				 struct intel_mipmap_tree *mt,
745				 enum gen6_hiz_op need)
746{
747   bool did_resolve = false;
748   struct intel_resolve_map *i, *next;
749
750   for (i = mt->hiz_map.next; i; i = next) {
751      next = i->next;
752      if (i->need != need)
753	 continue;
754
755      intel_hiz_exec(intel, mt, i->level, i->layer, need);
756      intel_resolve_map_remove(i);
757      did_resolve = true;
758   }
759
760   return did_resolve;
761}
762
763bool
764intel_miptree_all_slices_resolve_hiz(struct intel_context *intel,
765				     struct intel_mipmap_tree *mt)
766{
767   return intel_miptree_all_slices_resolve(intel, mt,
768					   GEN6_HIZ_OP_HIZ_RESOLVE);
769}
770
771bool
772intel_miptree_all_slices_resolve_depth(struct intel_context *intel,
773				       struct intel_mipmap_tree *mt)
774{
775   return intel_miptree_all_slices_resolve(intel, mt,
776					   GEN6_HIZ_OP_DEPTH_RESOLVE);
777}
778
779static void
780intel_miptree_map_gtt(struct intel_context *intel,
781		      struct intel_mipmap_tree *mt,
782		      struct intel_miptree_map *map,
783		      unsigned int level, unsigned int slice)
784{
785   unsigned int bw, bh;
786   void *base;
787   unsigned int image_x, image_y;
788   int x = map->x;
789   int y = map->y;
790
791   /* For compressed formats, the stride is the number of bytes per
792    * row of blocks.  intel_miptree_get_image_offset() already does
793    * the divide.
794    */
795   _mesa_get_format_block_size(mt->format, &bw, &bh);
796   assert(y % bh == 0);
797   y /= bh;
798
799   base = intel_region_map(intel, mt->region, map->mode);
800
801   if (base == NULL)
802      map->ptr = NULL;
803   else {
804      /* Note that in the case of cube maps, the caller must have passed the
805       * slice number referencing the face.
806      */
807      intel_miptree_get_image_offset(mt, level, 0, slice, &image_x, &image_y);
808      x += image_x;
809      y += image_y;
810
811      map->stride = mt->region->pitch * mt->cpp;
812      map->ptr = base + y * map->stride + x * mt->cpp;
813   }
814
815   DBG("%s: %d,%d %dx%d from mt %p (%s) %d,%d = %p/%d\n", __FUNCTION__,
816       map->x, map->y, map->w, map->h,
817       mt, _mesa_get_format_name(mt->format),
818       x, y, map->ptr, map->stride);
819}
820
821static void
822intel_miptree_unmap_gtt(struct intel_context *intel,
823			struct intel_mipmap_tree *mt,
824			struct intel_miptree_map *map,
825			unsigned int level,
826			unsigned int slice)
827{
828   intel_region_unmap(intel, mt->region);
829}
830
831static void
832intel_miptree_map_blit(struct intel_context *intel,
833		       struct intel_mipmap_tree *mt,
834		       struct intel_miptree_map *map,
835		       unsigned int level, unsigned int slice)
836{
837   unsigned int image_x, image_y;
838   int x = map->x;
839   int y = map->y;
840   int ret;
841
842   /* The blitter requires the pitch to be aligned to 4. */
843   map->stride = ALIGN(map->w * mt->region->cpp, 4);
844
845   map->bo = drm_intel_bo_alloc(intel->bufmgr, "intel_miptree_map_blit() temp",
846				map->stride * map->h, 4096);
847   if (!map->bo) {
848      fprintf(stderr, "Failed to allocate blit temporary\n");
849      goto fail;
850   }
851
852   intel_miptree_get_image_offset(mt, level, 0, slice, &image_x, &image_y);
853   x += image_x;
854   y += image_y;
855
856   if (!intelEmitCopyBlit(intel,
857			  mt->region->cpp,
858			  mt->region->pitch, mt->region->bo,
859			  0, mt->region->tiling,
860			  map->stride / mt->region->cpp, map->bo,
861			  0, I915_TILING_NONE,
862			  x, y,
863			  0, 0,
864			  map->w, map->h,
865			  GL_COPY)) {
866      fprintf(stderr, "Failed to blit\n");
867      goto fail;
868   }
869
870   intel_batchbuffer_flush(intel);
871   ret = drm_intel_bo_map(map->bo, (map->mode & GL_MAP_WRITE_BIT) != 0);
872   if (ret) {
873      fprintf(stderr, "Failed to map blit temporary\n");
874      goto fail;
875   }
876
877   map->ptr = map->bo->virtual;
878
879   DBG("%s: %d,%d %dx%d from mt %p (%s) %d,%d = %p/%d\n", __FUNCTION__,
880       map->x, map->y, map->w, map->h,
881       mt, _mesa_get_format_name(mt->format),
882       x, y, map->ptr, map->stride);
883
884   return;
885
886fail:
887   drm_intel_bo_unreference(map->bo);
888   map->ptr = NULL;
889   map->stride = 0;
890}
891
892static void
893intel_miptree_unmap_blit(struct intel_context *intel,
894			 struct intel_mipmap_tree *mt,
895			 struct intel_miptree_map *map,
896			 unsigned int level,
897			 unsigned int slice)
898{
899   assert(!(map->mode & GL_MAP_WRITE_BIT));
900
901   drm_intel_bo_unmap(map->bo);
902   drm_intel_bo_unreference(map->bo);
903}
904
905static void
906intel_miptree_map_s8(struct intel_context *intel,
907		     struct intel_mipmap_tree *mt,
908		     struct intel_miptree_map *map,
909		     unsigned int level, unsigned int slice)
910{
911   map->stride = map->w;
912   map->buffer = map->ptr = malloc(map->stride * map->h);
913   if (!map->buffer)
914      return;
915
916   /* One of either READ_BIT or WRITE_BIT or both is set.  READ_BIT implies no
917    * INVALIDATE_RANGE_BIT.  WRITE_BIT needs the original values read in unless
918    * invalidate is set, since we'll be writing the whole rectangle from our
919    * temporary buffer back out.
920    */
921   if (!(map->mode & GL_MAP_INVALIDATE_RANGE_BIT)) {
922      uint8_t *untiled_s8_map = map->ptr;
923      uint8_t *tiled_s8_map = intel_region_map(intel, mt->region,
924					       GL_MAP_READ_BIT);
925      unsigned int image_x, image_y;
926
927      intel_miptree_get_image_offset(mt, level, 0, slice, &image_x, &image_y);
928
929      for (uint32_t y = 0; y < map->h; y++) {
930	 for (uint32_t x = 0; x < map->w; x++) {
931	    ptrdiff_t offset = intel_offset_S8(mt->region->pitch,
932	                                       x + image_x + map->x,
933	                                       y + image_y + map->y,
934					       intel->has_swizzling);
935	    untiled_s8_map[y * map->w + x] = tiled_s8_map[offset];
936	 }
937      }
938
939      intel_region_unmap(intel, mt->region);
940
941      DBG("%s: %d,%d %dx%d from mt %p %d,%d = %p/%d\n", __FUNCTION__,
942	  map->x, map->y, map->w, map->h,
943	  mt, map->x + image_x, map->y + image_y, map->ptr, map->stride);
944   } else {
945      DBG("%s: %d,%d %dx%d from mt %p = %p/%d\n", __FUNCTION__,
946	  map->x, map->y, map->w, map->h,
947	  mt, map->ptr, map->stride);
948   }
949}
950
951static void
952intel_miptree_unmap_s8(struct intel_context *intel,
953		       struct intel_mipmap_tree *mt,
954		       struct intel_miptree_map *map,
955		       unsigned int level,
956		       unsigned int slice)
957{
958   if (map->mode & GL_MAP_WRITE_BIT) {
959      unsigned int image_x, image_y;
960      uint8_t *untiled_s8_map = map->ptr;
961      uint8_t *tiled_s8_map = intel_region_map(intel, mt->region, map->mode);
962
963      intel_miptree_get_image_offset(mt, level, 0, slice, &image_x, &image_y);
964
965      for (uint32_t y = 0; y < map->h; y++) {
966	 for (uint32_t x = 0; x < map->w; x++) {
967	    ptrdiff_t offset = intel_offset_S8(mt->region->pitch,
968	                                       x + map->x,
969	                                       y + map->y,
970					       intel->has_swizzling);
971	    tiled_s8_map[offset] = untiled_s8_map[y * map->w + x];
972	 }
973      }
974
975      intel_region_unmap(intel, mt->region);
976   }
977
978   free(map->buffer);
979}
980
981/**
982 * Mapping function for packed depth/stencil miptrees backed by real separate
983 * miptrees for depth and stencil.
984 *
985 * On gen7, and to support HiZ pre-gen7, we have to have the stencil buffer
986 * separate from the depth buffer.  Yet at the GL API level, we have to expose
987 * packed depth/stencil textures and FBO attachments, and Mesa core expects to
988 * be able to map that memory for texture storage and glReadPixels-type
989 * operations.  We give Mesa core that access by mallocing a temporary and
990 * copying the data between the actual backing store and the temporary.
991 */
992static void
993intel_miptree_map_depthstencil(struct intel_context *intel,
994			       struct intel_mipmap_tree *mt,
995			       struct intel_miptree_map *map,
996			       unsigned int level, unsigned int slice)
997{
998   struct intel_mipmap_tree *z_mt = mt;
999   struct intel_mipmap_tree *s_mt = mt->stencil_mt;
1000   bool map_z32f_x24s8 = mt->format == MESA_FORMAT_Z32_FLOAT;
1001   int packed_bpp = map_z32f_x24s8 ? 8 : 4;
1002
1003   map->stride = map->w * packed_bpp;
1004   map->buffer = map->ptr = malloc(map->stride * map->h);
1005   if (!map->buffer)
1006      return;
1007
1008   /* One of either READ_BIT or WRITE_BIT or both is set.  READ_BIT implies no
1009    * INVALIDATE_RANGE_BIT.  WRITE_BIT needs the original values read in unless
1010    * invalidate is set, since we'll be writing the whole rectangle from our
1011    * temporary buffer back out.
1012    */
1013   if (!(map->mode & GL_MAP_INVALIDATE_RANGE_BIT)) {
1014      uint32_t *packed_map = map->ptr;
1015      uint8_t *s_map = intel_region_map(intel, s_mt->region, GL_MAP_READ_BIT);
1016      uint32_t *z_map = intel_region_map(intel, z_mt->region, GL_MAP_READ_BIT);
1017      unsigned int s_image_x, s_image_y;
1018      unsigned int z_image_x, z_image_y;
1019
1020      intel_miptree_get_image_offset(s_mt, level, 0, slice,
1021				     &s_image_x, &s_image_y);
1022      intel_miptree_get_image_offset(z_mt, level, 0, slice,
1023				     &z_image_x, &z_image_y);
1024
1025      for (uint32_t y = 0; y < map->h; y++) {
1026	 for (uint32_t x = 0; x < map->w; x++) {
1027	    int map_x = map->x + x, map_y = map->y + y;
1028	    ptrdiff_t s_offset = intel_offset_S8(s_mt->region->pitch,
1029						 map_x + s_image_x,
1030						 map_y + s_image_y,
1031						 intel->has_swizzling);
1032	    ptrdiff_t z_offset = ((map_y + z_image_y) * z_mt->region->pitch +
1033				  (map_x + z_image_x));
1034	    uint8_t s = s_map[s_offset];
1035	    uint32_t z = z_map[z_offset];
1036
1037	    if (map_z32f_x24s8) {
1038	       packed_map[(y * map->w + x) * 2 + 0] = z;
1039	       packed_map[(y * map->w + x) * 2 + 1] = s;
1040	    } else {
1041	       packed_map[y * map->w + x] = (s << 24) | (z & 0x00ffffff);
1042	    }
1043	 }
1044      }
1045
1046      intel_region_unmap(intel, s_mt->region);
1047      intel_region_unmap(intel, z_mt->region);
1048
1049      DBG("%s: %d,%d %dx%d from z mt %p %d,%d, s mt %p %d,%d = %p/%d\n",
1050	  __FUNCTION__,
1051	  map->x, map->y, map->w, map->h,
1052	  z_mt, map->x + z_image_x, map->y + z_image_y,
1053	  s_mt, map->x + s_image_x, map->y + s_image_y,
1054	  map->ptr, map->stride);
1055   } else {
1056      DBG("%s: %d,%d %dx%d from mt %p = %p/%d\n", __FUNCTION__,
1057	  map->x, map->y, map->w, map->h,
1058	  mt, map->ptr, map->stride);
1059   }
1060}
1061
1062static void
1063intel_miptree_unmap_depthstencil(struct intel_context *intel,
1064				 struct intel_mipmap_tree *mt,
1065				 struct intel_miptree_map *map,
1066				 unsigned int level,
1067				 unsigned int slice)
1068{
1069   struct intel_mipmap_tree *z_mt = mt;
1070   struct intel_mipmap_tree *s_mt = mt->stencil_mt;
1071   bool map_z32f_x24s8 = mt->format == MESA_FORMAT_Z32_FLOAT;
1072
1073   if (map->mode & GL_MAP_WRITE_BIT) {
1074      uint32_t *packed_map = map->ptr;
1075      uint8_t *s_map = intel_region_map(intel, s_mt->region, map->mode);
1076      uint32_t *z_map = intel_region_map(intel, z_mt->region, map->mode);
1077      unsigned int s_image_x, s_image_y;
1078      unsigned int z_image_x, z_image_y;
1079
1080      intel_miptree_get_image_offset(s_mt, level, 0, slice,
1081				     &s_image_x, &s_image_y);
1082      intel_miptree_get_image_offset(z_mt, level, 0, slice,
1083				     &z_image_x, &z_image_y);
1084
1085      for (uint32_t y = 0; y < map->h; y++) {
1086	 for (uint32_t x = 0; x < map->w; x++) {
1087	    ptrdiff_t s_offset = intel_offset_S8(s_mt->region->pitch,
1088						 x + s_image_x + map->x,
1089						 y + s_image_y + map->y,
1090						 intel->has_swizzling);
1091	    ptrdiff_t z_offset = ((y + z_image_y) * z_mt->region->pitch +
1092				  (x + z_image_x));
1093
1094	    if (map_z32f_x24s8) {
1095	       z_map[z_offset] = packed_map[(y * map->w + x) * 2 + 0];
1096	       s_map[s_offset] = packed_map[(y * map->w + x) * 2 + 1];
1097	    } else {
1098	       uint32_t packed = packed_map[y * map->w + x];
1099	       s_map[s_offset] = packed >> 24;
1100	       z_map[z_offset] = packed;
1101	    }
1102	 }
1103      }
1104
1105      intel_region_unmap(intel, s_mt->region);
1106      intel_region_unmap(intel, z_mt->region);
1107
1108      DBG("%s: %d,%d %dx%d from z mt %p (%s) %d,%d, s mt %p %d,%d = %p/%d\n",
1109	  __FUNCTION__,
1110	  map->x, map->y, map->w, map->h,
1111	  z_mt, _mesa_get_format_name(z_mt->format),
1112	  map->x + z_image_x, map->y + z_image_y,
1113	  s_mt, map->x + s_image_x, map->y + s_image_y,
1114	  map->ptr, map->stride);
1115   }
1116
1117   free(map->buffer);
1118}
1119
1120void
1121intel_miptree_map(struct intel_context *intel,
1122		  struct intel_mipmap_tree *mt,
1123		  unsigned int level,
1124		  unsigned int slice,
1125		  unsigned int x,
1126		  unsigned int y,
1127		  unsigned int w,
1128		  unsigned int h,
1129		  GLbitfield mode,
1130		  void **out_ptr,
1131		  int *out_stride)
1132{
1133   struct intel_miptree_map *map;
1134
1135   map = calloc(1, sizeof(struct intel_miptree_map));
1136   if (!map){
1137      *out_ptr = NULL;
1138      *out_stride = 0;
1139      return;
1140   }
1141
1142   assert(!mt->level[level].slice[slice].map);
1143   mt->level[level].slice[slice].map = map;
1144   map->mode = mode;
1145   map->x = x;
1146   map->y = y;
1147   map->w = w;
1148   map->h = h;
1149
1150   intel_miptree_slice_resolve_depth(intel, mt, level, slice);
1151   if (map->mode & GL_MAP_WRITE_BIT) {
1152      intel_miptree_slice_set_needs_hiz_resolve(mt, level, slice);
1153   }
1154
1155   if (mt->format == MESA_FORMAT_S8) {
1156      intel_miptree_map_s8(intel, mt, map, level, slice);
1157   } else if (mt->stencil_mt) {
1158      intel_miptree_map_depthstencil(intel, mt, map, level, slice);
1159   } else if (intel->has_llc &&
1160	      !(mode & GL_MAP_WRITE_BIT) &&
1161	      !mt->compressed &&
1162	      mt->region->tiling == I915_TILING_X) {
1163      intel_miptree_map_blit(intel, mt, map, level, slice);
1164   } else {
1165      intel_miptree_map_gtt(intel, mt, map, level, slice);
1166   }
1167
1168   *out_ptr = map->ptr;
1169   *out_stride = map->stride;
1170
1171   if (map->ptr == NULL) {
1172      mt->level[level].slice[slice].map = NULL;
1173      free(map);
1174   }
1175}
1176
1177void
1178intel_miptree_unmap(struct intel_context *intel,
1179		    struct intel_mipmap_tree *mt,
1180		    unsigned int level,
1181		    unsigned int slice)
1182{
1183   struct intel_miptree_map *map = mt->level[level].slice[slice].map;
1184
1185   if (!map)
1186      return;
1187
1188   DBG("%s: mt %p (%s) level %d slice %d\n", __FUNCTION__,
1189       mt, _mesa_get_format_name(mt->format), level, slice);
1190
1191   if (mt->format == MESA_FORMAT_S8) {
1192      intel_miptree_unmap_s8(intel, mt, map, level, slice);
1193   } else if (mt->stencil_mt) {
1194      intel_miptree_unmap_depthstencil(intel, mt, map, level, slice);
1195   } else if (map->bo) {
1196      intel_miptree_unmap_blit(intel, mt, map, level, slice);
1197   } else {
1198      intel_miptree_unmap_gtt(intel, mt, map, level, slice);
1199   }
1200
1201   mt->level[level].slice[slice].map = NULL;
1202   free(map);
1203}
1204