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