[Mesa-dev] [v2 22/26] i965: Apply non-msrt mcs array/mipmap vertical alignment rules
Topi Pohjolainen
topi.pohjolainen at gmail.com
Wed Nov 2 19:45:31 UTC 2016
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.pohjolainen at intel.com>
CC: Jason Ekstrand <jason at 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
More information about the mesa-dev
mailing list