ilo: add image_get_gen6_layout()

It replaces only img_init_walk() right now.  It will replace all img_init_*().
This commit is contained in:
Chia-I Wu
2015-06-29 16:02:52 +08:00
parent 5dcb28c3d2
commit 9e13f5c85f
+107 -82
View File
@@ -49,6 +49,102 @@ struct ilo_image_params {
unsigned max_x, max_y;
};
struct ilo_image_layout {
enum ilo_image_walk_type walk;
bool interleaved_samples;
};
static enum ilo_image_walk_type
image_get_gen6_walk(const struct ilo_dev *dev,
const struct ilo_image_info *info)
{
ILO_DEV_ASSERT(dev, 6, 6);
/* TODO we want LODs to be page-aligned */
if (info->type == GEN6_SURFTYPE_3D)
return ILO_IMAGE_WALK_3D;
/*
* From the Sandy Bridge PRM, volume 1 part 1, page 115:
*
* "The separate stencil buffer does not support mip mapping, thus the
* storage for LODs other than LOD 0 is not needed. The following
* QPitch equation applies only to the separate stencil buffer:
*
* QPitch = h_0"
*
* Use ILO_IMAGE_WALK_LOD and manually offset to the (page-aligned) levels
* when bound.
*/
if (info->bind_zs && info->format == GEN6_FORMAT_R8_UINT)
return ILO_IMAGE_WALK_LOD;
/* compact spacing is not supported otherwise */
return ILO_IMAGE_WALK_LAYER;
}
static enum ilo_image_walk_type
image_get_gen7_walk(const struct ilo_dev *dev,
const struct ilo_image_info *info)
{
ILO_DEV_ASSERT(dev, 7, 8);
if (info->type == GEN6_SURFTYPE_3D)
return ILO_IMAGE_WALK_3D;
/*
* From the Ivy Bridge PRM, volume 1 part 1, page 111:
*
* "note that the depth buffer and stencil buffer have an implied value
* of ARYSPC_FULL"
*
* From the Ivy Bridge PRM, volume 4 part 1, page 66:
*
* "If Multisampled Surface Storage Format is MSFMT_MSS and Number of
* Multisamples is not MULTISAMPLECOUNT_1, this field (Surface Array
* Spacing) must be set to ARYSPC_LOD0."
*/
if (info->sample_count > 1)
assert(info->level_count == 1);
return (info->bind_zs || info->level_count > 1) ?
ILO_IMAGE_WALK_LAYER : ILO_IMAGE_WALK_LOD;
}
static bool
image_get_gen6_interleaved_samples(const struct ilo_dev *dev,
const struct ilo_image_info *info)
{
ILO_DEV_ASSERT(dev, 6, 8);
/*
* Gen6 supports only interleaved samples. It is not explicitly stated,
* but on Gen7+, render targets are expected to be UMS/CMS (samples
* non-interleaved) and depth/stencil buffers are expected to be IMS
* (samples interleaved).
*
* See "Multisampled Surface Storage Format" field of SURFACE_STATE.
*/
return (ilo_dev_gen(dev) == ILO_GEN(6) || info->bind_zs);
}
static bool
image_get_gen6_layout(const struct ilo_dev *dev,
const struct ilo_image_info *info,
struct ilo_image_layout *layout)
{
ILO_DEV_ASSERT(dev, 6, 8);
if (ilo_dev_gen(dev) >= ILO_GEN(7))
layout->walk = image_get_gen7_walk(dev, info);
else
layout->walk = image_get_gen6_walk(dev, info);
layout->interleaved_samples =
image_get_gen6_interleaved_samples(dev, info);
return true;
}
static void
img_get_slice_size(const struct ilo_image *img,
const struct ilo_image_params *params,
@@ -492,87 +588,6 @@ img_init_tiling(struct ilo_image *img,
img->tiling = GEN6_TILING_NONE;
}
static void
img_init_walk_gen7(struct ilo_image *img,
const struct ilo_image_params *params)
{
const struct ilo_image_info *info = params->info;
/*
* It is not explicitly states, but render targets are expected to be
* UMS/CMS (samples non-interleaved) and depth/stencil buffers are expected
* to be IMS (samples interleaved).
*
* See "Multisampled Surface Storage Format" field of SURFACE_STATE.
*/
if (info->bind_zs) {
/*
* From the Ivy Bridge PRM, volume 1 part 1, page 111:
*
* "note that the depth buffer and stencil buffer have an implied
* value of ARYSPC_FULL"
*/
img->walk = (info->type == GEN6_SURFTYPE_3D) ?
ILO_IMAGE_WALK_3D : ILO_IMAGE_WALK_LAYER;
img->interleaved_samples = true;
} else {
/*
* From the Ivy Bridge PRM, volume 4 part 1, page 66:
*
* "If Multisampled Surface Storage Format is MSFMT_MSS and Number
* of Multisamples is not MULTISAMPLECOUNT_1, this field (Surface
* Array Spacing) must be set to ARYSPC_LOD0."
*
* As multisampled resources are not mipmapped, we never use
* ARYSPC_FULL for them.
*/
if (info->sample_count > 1)
assert(info->level_count == 1);
img->walk =
(info->type == GEN6_SURFTYPE_3D) ? ILO_IMAGE_WALK_3D :
(info->level_count > 1) ? ILO_IMAGE_WALK_LAYER :
ILO_IMAGE_WALK_LOD;
img->interleaved_samples = false;
}
}
static void
img_init_walk_gen6(struct ilo_image *img,
const struct ilo_image_params *params)
{
/*
* From the Sandy Bridge PRM, volume 1 part 1, page 115:
*
* "The separate stencil buffer does not support mip mapping, thus the
* storage for LODs other than LOD 0 is not needed. The following
* QPitch equation applies only to the separate stencil buffer:
*
* QPitch = h_0"
*
* GEN6 does not support compact spacing otherwise.
*/
img->walk =
(params->info->type == GEN6_SURFTYPE_3D) ? ILO_IMAGE_WALK_3D :
(img->format == GEN6_FORMAT_R8_UINT) ? ILO_IMAGE_WALK_LOD :
ILO_IMAGE_WALK_LAYER;
/* GEN6 supports only interleaved samples */
img->interleaved_samples = true;
}
static void
img_init_walk(struct ilo_image *img,
const struct ilo_image_params *params)
{
if (ilo_dev_gen(params->dev) >= ILO_GEN(7))
img_init_walk_gen7(img, params);
else
img_init_walk_gen6(img, params);
}
static unsigned
img_get_valid_tilings(const struct ilo_image *img,
const struct ilo_image_params *params)
@@ -1265,11 +1280,21 @@ static bool
img_init(struct ilo_image *img,
struct ilo_image_params *params)
{
struct ilo_image_layout layout;
memset(&layout, 0, sizeof(layout));
if (!image_get_gen6_layout(params->dev, params->info, &layout))
return false;
/* there are hard dependencies between every function here */
img_init_size_and_format(img, params);
img_init_aux(img, params);
img_init_walk(img, params);
img->walk = layout.walk;
img->interleaved_samples = layout.interleaved_samples;
img_init_tiling(img, params);
img_init_alignments(img, params);
img_init_lods(img, params);