There are actually two contradicting pieces in the bspec: From the BSpec: 3D-Media-GPGPU Engine - 3D Pipeline Stages - Pixel - Pixel Backend [IVB+] - MCS Buffer for Render Target(s)
BDW: Mip-mapped and arrayed surfaces are supported with MCS buffer layout with these alignments in the RT space: Horizontal Alignment = 256 and Vertical Alignment = 128. SKL+: Mip-mapped and arrayed surfaces are supported with MCS buffer layout with these alignments in the RT space: Horizontal Alignment = 128 and Vertical Alignment = 64. and From the BSpec: GT - Shared Functions - vol5c Shared Functions - RENDER_SURFACE_STATE [BDW+] Issues Info 2: PRE-SKL For non-multisampled render target's auxiliary surface, MCS, QPitch must be computed with Horizontal Alignment = 256 and Surface Vertical Alignment = 128. These alignments are only for MCS buffer and not for associated render target. SKL+ For non-multisampled render target's CCS auxiliary surface, QPitch must be computed with Horizontal Alignment = 128 and Surface Vertical Alignment = 256. These alignments are only for CCS buffer and not for associated render target. The former seems to hold for individual mip-levels and the latter for qpitch. Signed-off-by: Topi Pohjolainen <topi.pohjolai...@intel.com> CC: Jason Ekstrand <ja...@jlekstrand.net> --- src/mesa/drivers/dri/i965/brw_tex_layout.c | 68 +++++++++++++++++++----- src/mesa/drivers/dri/i965/brw_wm_surface_state.c | 2 +- src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 3 +- src/mesa/drivers/dri/i965/intel_mipmap_tree.h | 4 +- 4 files changed, 61 insertions(+), 16 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c index 9e281e3..9fe09a3 100644 --- a/src/mesa/drivers/dri/i965/brw_tex_layout.c +++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c @@ -199,8 +199,24 @@ tr_mode_vertical_texture_alignment(const struct intel_mipmap_tree *mt) static unsigned int intel_vertical_texture_alignment_unit(struct brw_context *brw, - const struct intel_mipmap_tree *mt) + const struct intel_mipmap_tree *mt, + uint32_t layout_flags) { + /* From the BSpec: 3D-Media-GPGPU Engine - 3D Pipeline Stages - Pixel - + * Pixel Backend [IVB+] - MCS Buffer for Render Target(s) + * + * BDW: Mip-mapped and arrayed surfaces are supported with MCS buffer + * layout with these alignments in the RT space: + * Horizontal Alignment = 256 and Vertical Alignment = 128. + * SKL+: Mip-mapped and arrayed surfaces are supported with MCS buffer + * layout with these alignments in the RT space: Horizontal + * Alignment = 128 and Vertical Alignment = 64. + */ + if (brw->gen >= 8 && mt->num_samples <= 1 && + layout_flags & MIPTREE_LAYOUT_FOR_MCS) { + return brw->gen == 8 ? 128 : 64; + } + /** * +----------------------------------------------------------------------+ * | | alignment unit height ("j") | @@ -380,7 +396,7 @@ brw_miptree_get_horizontal_slice_pitch(const struct brw_context *brw, unsigned brw_miptree_get_vertical_slice_pitch(const struct brw_context *brw, const struct intel_mipmap_tree *mt, - unsigned level) + unsigned level, uint32_t layout_flags) { unsigned qpitch; @@ -420,6 +436,26 @@ brw_miptree_get_vertical_slice_pitch(const struct brw_context *brw, qpitch = h0 + h1 + (brw->gen >= 7 ? 12 : 11) * mt->valign; } + /* From the BSpec: GT - Shared Functions - vol5c Shared Functions - + * RENDER_SURFACE_STATE [BDW+] Issues Info 2: + * + * PRE-SKL + * For non-multisampled render target's auxiliary surface, MCS, QPitch + * must be computed with Horizontal Alignment = 256 and Surface Vertical + * Alignment = 128. These alignments are only for MCS buffer and not for + * associated render target. + * + * SKL+ + * For non-multisampled render target's CCS auxiliary surface, QPitch + * must be computed with Horizontal Alignment = 128 and Surface Vertical + * Alignment = 256. These alignments are only for CCS buffer and not for + * associated render target. + */ + if (brw->gen >= 8 && (layout_flags & MIPTREE_LAYOUT_FOR_MCS) && + (mt->last_level || mt->logical_depth0 > 1)) { + qpitch = ALIGN(qpitch, brw->gen == 8 ? 128 : 256); + } + return qpitch; } @@ -459,7 +495,8 @@ gen9_use_linear_1d_layout(const struct brw_context *brw, static void brw_miptree_layout_texture_array(struct brw_context *brw, - struct intel_mipmap_tree *mt) + struct intel_mipmap_tree *mt, + uint32_t layout_flags) { unsigned height = mt->physical_height0; bool layout_1d = gen9_use_linear_1d_layout(brw, mt); @@ -479,7 +516,9 @@ brw_miptree_layout_texture_array(struct brw_context *brw, */ mt->qpitch = mt->total_width; } else { - mt->qpitch = brw_miptree_get_vertical_slice_pitch(brw, mt, 0); + mt->qpitch = brw_miptree_get_vertical_slice_pitch(brw, mt, 0, + layout_flags); + /* Unlike previous generations the qpitch is a multiple of the * compressed block size on Gen9 so physical_qpitch matches mt->qpitch. */ @@ -652,7 +691,8 @@ brw_miptree_choose_tiling(struct brw_context *brw, static void intel_miptree_set_total_width_height(struct brw_context *brw, - struct intel_mipmap_tree *mt) + struct intel_mipmap_tree *mt, + uint32_t layout_flags) { switch (mt->target) { case GL_TEXTURE_CUBE_MAP: @@ -662,29 +702,30 @@ intel_miptree_set_total_width_height(struct brw_context *brw, brw_miptree_layout_texture_3d(brw, mt); } else { /* All other hardware stores cube maps as 2D arrays. */ - brw_miptree_layout_texture_array(brw, mt); + brw_miptree_layout_texture_array(brw, mt, layout_flags); } break; case GL_TEXTURE_3D: - if (brw->gen >= 9) - brw_miptree_layout_texture_array(brw, mt); - else + if (brw->gen >= 9) { + brw_miptree_layout_texture_array(brw, mt, layout_flags); + } else { brw_miptree_layout_texture_3d(brw, mt); + } break; case GL_TEXTURE_1D_ARRAY: case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: case GL_TEXTURE_CUBE_MAP_ARRAY: - brw_miptree_layout_texture_array(brw, mt); + brw_miptree_layout_texture_array(brw, mt, layout_flags); break; default: switch (mt->msaa_layout) { case INTEL_MSAA_LAYOUT_UMS: case INTEL_MSAA_LAYOUT_CMS: - brw_miptree_layout_texture_array(brw, mt); + brw_miptree_layout_texture_array(brw, mt, layout_flags); break; case INTEL_MSAA_LAYOUT_NONE: case INTEL_MSAA_LAYOUT_IMS: @@ -768,7 +809,8 @@ intel_miptree_set_alignment(struct brw_context *brw, } else { mt->halign = intel_horizontal_texture_alignment_unit(brw, mt, layout_flags); - mt->valign = intel_vertical_texture_alignment_unit(brw, mt); + mt->valign = intel_vertical_texture_alignment_unit(brw, mt, + layout_flags); } } @@ -780,7 +822,7 @@ brw_miptree_layout(struct brw_context *brw, mt->tr_mode = INTEL_MIPTREE_TRMODE_NONE; intel_miptree_set_alignment(brw, mt, layout_flags); - intel_miptree_set_total_width_height(brw, mt); + intel_miptree_set_total_width_height(brw, mt, layout_flags); if (!mt->total_width || !mt->total_height) { intel_miptree_release(&mt); diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c index 5487317..6c3273d 100644 --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c @@ -1668,7 +1668,7 @@ update_texture_image_param(struct brw_context *brw, param->stride[2] = brw_miptree_get_horizontal_slice_pitch(brw, mt, u->Level); param->stride[3] = - brw_miptree_get_vertical_slice_pitch(brw, mt, u->Level); + brw_miptree_get_vertical_slice_pitch(brw, mt, u->Level, 0); if (mt->tiling == I915_TILING_X) { /* An X tile is a rectangular block of 512x8 bytes. */ diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index a96f88c..7a03597 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -1610,7 +1610,8 @@ intel_miptree_alloc_non_msrt_mcs(struct brw_context *brw, uint32_t layout_flags = MIPTREE_LAYOUT_TILING_Y; if (brw->gen >= 8) { - layout_flags |= MIPTREE_LAYOUT_FORCE_HALIGN16; + layout_flags |= (MIPTREE_LAYOUT_FORCE_HALIGN16 | + MIPTREE_LAYOUT_FOR_MCS); } /* In case of compression mcs buffer needs to be initialised requiring the diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h index e08efe2..49074bd 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h @@ -667,6 +667,8 @@ enum { MIPTREE_LAYOUT_TILING_NONE, MIPTREE_LAYOUT_FOR_SCANOUT = 1 << 7, + + MIPTREE_LAYOUT_FOR_MCS = 1 << 8, }; struct intel_mipmap_tree *intel_miptree_create(struct brw_context *brw, @@ -965,7 +967,7 @@ brw_miptree_get_horizontal_slice_pitch(const struct brw_context *brw, unsigned brw_miptree_get_vertical_slice_pitch(const struct brw_context *brw, const struct intel_mipmap_tree *mt, - unsigned level); + unsigned level, uint32_t layout_flags); void brw_miptree_layout(struct brw_context *brw, -- 2.5.5 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev