summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/ilo
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/ilo')
-rw-r--r--src/gallium/drivers/ilo/ilo_gpe_gen6.c16
-rw-r--r--src/gallium/drivers/ilo/ilo_layout.c35
-rw-r--r--src/gallium/drivers/ilo/ilo_transfer.c24
3 files changed, 44 insertions, 31 deletions
diff --git a/src/gallium/drivers/ilo/ilo_gpe_gen6.c b/src/gallium/drivers/ilo/ilo_gpe_gen6.c
index 9c5c4c8cf34..c3ba9e37147 100644
--- a/src/gallium/drivers/ilo/ilo_gpe_gen6.c
+++ b/src/gallium/drivers/ilo/ilo_gpe_gen6.c
@@ -1075,6 +1075,7 @@ zs_init_info(const struct ilo_dev_info *dev,
info->zs.bo = tex->bo;
info->zs.stride = tex->layout.bo_stride;
info->zs.tiling = tex->layout.tiling;
+ info->zs.offset = 0;
}
if (tex->separate_s8 || format == PIPE_FORMAT_S8_UINT) {
@@ -1095,12 +1096,27 @@ zs_init_info(const struct ilo_dev_info *dev,
info->stencil.stride = s8_tex->layout.bo_stride * 2;
info->stencil.tiling = s8_tex->layout.tiling;
+
+ if (dev->gen == ILO_GEN(6)) {
+ unsigned x, y;
+
+ assert(s8_tex->layout.walk == ILO_LAYOUT_WALK_LOD);
+
+ /* offset to the level */
+ ilo_layout_get_slice_pos(&s8_tex->layout, level, 0, &x, &y);
+ ilo_layout_pos_to_mem(&s8_tex->layout, x, y, &x, &y);
+ info->stencil.offset = ilo_layout_mem_to_raw(&s8_tex->layout, x, y);
+ }
}
if (ilo_texture_can_enable_hiz(tex, level, first_layer, num_layers)) {
info->hiz.bo = tex->aux_bo;
info->hiz.stride = tex->layout.aux_stride;
info->hiz.tiling = INTEL_TILING_Y;
+
+ /* offset to the level */
+ if (dev->gen == ILO_GEN(6))
+ info->hiz.offset = tex->layout.aux_offsets[level];
}
info->width = tex->layout.width0;
diff --git a/src/gallium/drivers/ilo/ilo_layout.c b/src/gallium/drivers/ilo/ilo_layout.c
index b6e958585a5..070ee215107 100644
--- a/src/gallium/drivers/ilo/ilo_layout.c
+++ b/src/gallium/drivers/ilo/ilo_layout.c
@@ -769,7 +769,6 @@ layout_want_hiz(const struct ilo_layout *layout,
const struct pipe_resource *templ = params->templ;
const struct util_format_description *desc =
util_format_description(templ->format);
- bool want_hiz = false;
if (ilo_debug & ILO_DEBUG_NOHIZ)
return false;
@@ -784,29 +783,19 @@ layout_want_hiz(const struct ilo_layout *layout,
if (templ->usage == PIPE_USAGE_STAGING)
return false;
- if (params->dev->gen >= ILO_GEN(7)) {
- want_hiz = true;
- } else {
- /*
- * From the Sandy Bridge PRM, volume 2 part 1, page 312:
- *
- * "The hierarchical depth buffer does not support the LOD field, it
- * is assumed by hardware to be zero. A separate hierarachical
- * depth buffer is required for each LOD used, and the
- * corresponding buffer's state delivered to hardware each time a
- * new depth buffer state with modified LOD is delivered."
- *
- * But we have a stronger requirement. Because of layer offsetting
- * (check out the callers of ilo_layout_get_slice_tile_offset()), we
- * already have to require the texture to be non-mipmapped and
- * non-array.
- */
- if (templ->last_level == 0 && templ->array_size == 1 &&
- templ->depth0 == 1)
- want_hiz = true;
- }
+ /*
+ * As can be seen in layout_calculate_hiz_size(), HiZ may not be enabled
+ * for every level. This is generally fine except on GEN6, where HiZ and
+ * separate stencil are enabled and disabled at the same time. When the
+ * format is PIPE_FORMAT_Z32_FLOAT_S8X24_UINT, enabling and disabling HiZ
+ * can result in incompatible formats.
+ */
+ if (params->dev->gen == ILO_GEN(6) &&
+ templ->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT &&
+ templ->last_level)
+ return false;
- return want_hiz;
+ return true;
}
static void
diff --git a/src/gallium/drivers/ilo/ilo_transfer.c b/src/gallium/drivers/ilo/ilo_transfer.c
index d40dce8c541..a38708d88a6 100644
--- a/src/gallium/drivers/ilo/ilo_transfer.c
+++ b/src/gallium/drivers/ilo/ilo_transfer.c
@@ -77,10 +77,12 @@
* correctly block when the resource is busy.
*/
static bool
-resource_get_transfer_method(struct pipe_resource *res, unsigned usage,
+resource_get_transfer_method(struct pipe_resource *res,
+ const struct pipe_transfer *transfer,
enum ilo_transfer_map_method *method)
{
const struct ilo_screen *is = ilo_screen(res->screen);
+ const unsigned usage = transfer->usage;
enum ilo_transfer_map_method m;
bool tiled;
@@ -89,15 +91,21 @@ resource_get_transfer_method(struct pipe_resource *res, unsigned usage,
}
else {
struct ilo_texture *tex = ilo_texture(res);
- bool need_convert = true;
+ bool need_convert = false;
/* we may need to convert on the fly */
- if (tex->separate_s8 || tex->layout.format == PIPE_FORMAT_S8_UINT)
- m = ILO_TRANSFER_MAP_SW_ZS;
- else if (tex->layout.format != tex->base.format)
+ if (tex->separate_s8 || tex->layout.format == PIPE_FORMAT_S8_UINT) {
+ /* on GEN6, separate stencil is enabled only when HiZ is */
+ if (is->dev.gen >= ILO_GEN(7) ||
+ ilo_texture_can_enable_hiz(tex, transfer->level,
+ transfer->box.z, transfer->box.depth)) {
+ m = ILO_TRANSFER_MAP_SW_ZS;
+ need_convert = true;
+ }
+ } else if (tex->layout.format != tex->base.format) {
m = ILO_TRANSFER_MAP_SW_CONVERT;
- else
- need_convert = false;
+ need_convert = true;
+ }
if (need_convert) {
if (usage & (PIPE_TRANSFER_MAP_DIRECTLY | PIPE_TRANSFER_PERSISTENT))
@@ -1059,7 +1067,7 @@ choose_transfer_method(struct ilo_context *ilo, struct ilo_transfer *xfer)
struct pipe_resource *res = xfer->base.resource;
bool need_flush;
- if (!resource_get_transfer_method(res, xfer->base.usage, &xfer->method))
+ if (!resource_get_transfer_method(res, &xfer->base, &xfer->method))
return false;
/* see if we can avoid blocking */