GLuint height0,
GLuint depth0,
GLuint num_samples,
- enum intel_miptree_tiling_mode requested,
uint32_t layout_flags)
{
struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1);
return NULL;
DBG("%s target %s format %s level %d..%d slices %d <-- %p\n", __func__,
- _mesa_lookup_enum_by_nr(target),
+ _mesa_enum_to_string(target),
_mesa_get_format_name(format),
first_level, last_level, depth0, mt);
(brw->has_separate_stencil &&
intel_miptree_wants_hiz_buffer(brw, mt)))) {
uint32_t stencil_flags = MIPTREE_LAYOUT_ACCELERATED_UPLOAD;
- if (brw->gen == 6)
- stencil_flags |= MIPTREE_LAYOUT_FORCE_ALL_SLICE_AT_LOD;
+ if (brw->gen == 6) {
+ stencil_flags |= MIPTREE_LAYOUT_FORCE_ALL_SLICE_AT_LOD |
+ MIPTREE_LAYOUT_TILING_ANY;
+ }
mt->stencil_mt = intel_miptree_create(brw,
mt->target,
mt->logical_height0,
mt->logical_depth0,
num_samples,
- INTEL_MIPTREE_TILING_ANY,
stencil_flags);
if (!mt->stencil_mt) {
* 6 | ? | ?
*/
if (intel_miptree_is_fast_clear_capable(brw, mt)) {
- if (brw->gen >= 9 || (brw->gen == 8 && num_samples == 1))
+ if (brw->gen >= 9 || (brw->gen == 8 && num_samples <= 1))
layout_flags |= MIPTREE_LAYOUT_FORCE_HALIGN16;
} else if (brw->gen >= 9 && num_samples > 1) {
layout_flags |= MIPTREE_LAYOUT_FORCE_HALIGN16;
assert((layout_flags & MIPTREE_LAYOUT_FORCE_HALIGN16) == 0);
}
- brw_miptree_layout(brw, mt, requested, layout_flags);
+ brw_miptree_layout(brw, mt, layout_flags);
if (mt->disable_aux_buffers)
assert(mt->msaa_layout != INTEL_MSAA_LAYOUT_CMS);
}
}
+/* This function computes Yf/Ys tiled bo size, alignment and pitch. */
+static unsigned long
+intel_get_yf_ys_bo_size(struct intel_mipmap_tree *mt, unsigned *alignment,
+ unsigned long *pitch)
+{
+ const uint32_t bpp = mt->cpp * 8;
+ const uint32_t aspect_ratio = (bpp == 16 || bpp == 64) ? 2 : 1;
+ uint32_t tile_width, tile_height;
+ unsigned long stride, size, aligned_y;
+
+ assert(mt->tr_mode != INTEL_MIPTREE_TRMODE_NONE);
+
+ switch (bpp) {
+ case 8:
+ tile_height = 64;
+ break;
+ case 16:
+ case 32:
+ tile_height = 32;
+ break;
+ case 64:
+ case 128:
+ tile_height = 16;
+ break;
+ default:
+ unreachable("not reached");
+ }
+
+ if (mt->tr_mode == INTEL_MIPTREE_TRMODE_YS)
+ tile_height *= 4;
+
+ aligned_y = ALIGN(mt->total_height, tile_height);
+ stride = mt->total_width * mt->cpp;
+ tile_width = tile_height * mt->cpp * aspect_ratio;
+ stride = ALIGN(stride, tile_width);
+ size = stride * aligned_y;
+
+ if (mt->tr_mode == INTEL_MIPTREE_TRMODE_YF) {
+ assert(size % 4096 == 0);
+ *alignment = 4096;
+ } else {
+ assert(size % (64 * 1024) == 0);
+ *alignment = 64 * 1024;
+ }
+ *pitch = stride;
+ return size;
+}
struct intel_mipmap_tree *
intel_miptree_create(struct brw_context *brw,
GLuint height0,
GLuint depth0,
GLuint num_samples,
- enum intel_miptree_tiling_mode requested_tiling,
uint32_t layout_flags)
{
struct intel_mipmap_tree *mt;
mt = intel_miptree_create_layout(brw, target, format,
first_level, last_level, width0,
height0, depth0, num_samples,
- requested_tiling, layout_flags);
+ layout_flags);
/*
* pitch == 0 || height == 0 indicates the null texture
*/
alloc_flags |= BO_ALLOC_FOR_RENDER;
unsigned long pitch;
- mt->bo = drm_intel_bo_alloc_tiled(brw->bufmgr, "miptree", total_width,
- total_height, mt->cpp, &mt->tiling,
- &pitch, alloc_flags);
mt->etc_format = etc_format;
+
+ if (mt->tr_mode != INTEL_MIPTREE_TRMODE_NONE) {
+ unsigned alignment = 0;
+ unsigned long size;
+ size = intel_get_yf_ys_bo_size(mt, &alignment, &pitch);
+ assert(size);
+ mt->bo = drm_intel_bo_alloc_for_render(brw->bufmgr, "miptree",
+ size, alignment);
+ } else {
+ mt->bo = drm_intel_bo_alloc_tiled(brw->bufmgr, "miptree",
+ total_width, total_height, mt->cpp,
+ &mt->tiling, &pitch,
+ alloc_flags);
+ }
+
mt->pitch = pitch;
/* If the BO is too large to fit in the aperture, we need to use the
target = depth > 1 ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
- /* 'requested' parameter of intel_miptree_create_layout() is relevant
- * only for non bo miptree. Tiling for bo is already computed above.
- * So, the tiling requested (INTEL_MIPTREE_TILING_ANY) below is
- * just a place holder and will not make any change to the miptree
- * tiling format.
+ /* The BO already has a tiling format and we shouldn't confuse the lower
+ * layers by making it try to find a tiling format again.
*/
+ assert((layout_flags & MIPTREE_LAYOUT_TILING_ANY) == 0);
+ assert((layout_flags & MIPTREE_LAYOUT_TILING_NONE) == 0);
+
layout_flags |= MIPTREE_LAYOUT_FOR_BO;
mt = intel_miptree_create_layout(brw, target, format,
0, 0,
width, height, depth, 0,
- INTEL_MIPTREE_TILING_ANY,
layout_flags);
if (!mt)
return NULL;
uint32_t depth = 1;
bool ok;
GLenum target = num_samples > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
+ const uint32_t layout_flags = MIPTREE_LAYOUT_ACCELERATED_UPLOAD |
+ MIPTREE_LAYOUT_TILING_ANY;
+
mt = intel_miptree_create(brw, target, format, 0, 0,
width, height, depth, num_samples,
- INTEL_MIPTREE_TILING_ANY,
- MIPTREE_LAYOUT_ACCELERATED_UPLOAD);
+ layout_flags);
if (!mt)
goto fail;
if (dst_mt->compressed) {
unsigned int i, j;
_mesa_get_format_block_size(dst_mt->format, &i, &j);
- height = ALIGN(height, j) / j;
- width = ALIGN(width, i);
+ height = ALIGN_NPOT(height, j) / j;
+ width = ALIGN_NPOT(width, i);
}
/* If it's a packed depth/stencil buffer with separate stencil, the blit
*
* "The MCS surface must be stored as Tile Y."
*/
+ const uint32_t mcs_flags = MIPTREE_LAYOUT_ACCELERATED_UPLOAD |
+ MIPTREE_LAYOUT_TILING_Y;
mt->mcs_mt = intel_miptree_create(brw,
mt->target,
format,
mt->logical_height0,
mt->logical_depth0,
0 /* num_samples */,
- INTEL_MIPTREE_TILING_Y,
- MIPTREE_LAYOUT_ACCELERATED_UPLOAD);
+ mcs_flags);
/* From the Ivy Bridge PRM, Vol 2 Part 1 p326:
*
unsigned mcs_height =
ALIGN(mt->logical_height0, height_divisor) / height_divisor;
assert(mt->logical_depth0 == 1);
- uint32_t layout_flags = MIPTREE_LAYOUT_ACCELERATED_UPLOAD;
- if (brw->gen >= 8)
+ uint32_t layout_flags = MIPTREE_LAYOUT_ACCELERATED_UPLOAD |
+ MIPTREE_LAYOUT_TILING_Y;
+ if (brw->gen >= 8) {
layout_flags |= MIPTREE_LAYOUT_FORCE_HALIGN16;
+ }
mt->mcs_mt = intel_miptree_create(brw,
mt->target,
format,
mcs_height,
mt->logical_depth0,
0 /* num_samples */,
- INTEL_MIPTREE_TILING_Y,
layout_flags);
return mt->mcs_mt;
/* Gen7 PRM Volume 2, Part 1, 11.5.3 "Hierarchical Depth Buffer" documents
* adjustments required for Z_Height and Z_Width based on multisampling.
*/
- switch (mt->num_samples) {
- case 0:
- case 1:
- break;
- case 2:
- case 4:
- z_width *= 2;
- z_height *= 2;
- break;
- case 8:
- z_width *= 4;
- z_height *= 2;
- break;
- default:
- unreachable("unsupported sample count");
+ if (brw->gen < 9) {
+ switch (mt->num_samples) {
+ case 0:
+ case 1:
+ break;
+ case 2:
+ case 4:
+ z_width *= 2;
+ z_height *= 2;
+ break;
+ case 8:
+ z_width *= 4;
+ z_height *= 2;
+ break;
+ default:
+ unreachable("unsupported sample count");
+ }
}
const unsigned vertical_align = 8; /* 'j' in the docs */
if (!buf)
return NULL;
+ layout_flags |= MIPTREE_LAYOUT_TILING_ANY;
buf->mt = intel_miptree_create(brw,
mt->target,
mt->format,
mt->logical_height0,
mt->logical_depth0,
mt->num_samples,
- INTEL_MIPTREE_TILING_ANY,
layout_flags);
if (!buf->mt) {
free(buf);
map->mt = intel_miptree_create(brw, GL_TEXTURE_2D, mt->format,
0, 0,
map->w, map->h, 1,
- 0, INTEL_MIPTREE_TILING_NONE, 0);
+ 0, MIPTREE_LAYOUT_TILING_NONE);
if (!map->mt) {
fprintf(stderr, "Failed to allocate blit temporary\n");