diff options
Diffstat (limited to 'src/gallium/drivers/ilo')
-rw-r--r-- | src/gallium/drivers/ilo/ilo_gpe_gen6.c | 16 | ||||
-rw-r--r-- | src/gallium/drivers/ilo/ilo_layout.c | 35 | ||||
-rw-r--r-- | src/gallium/drivers/ilo/ilo_transfer.c | 24 |
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 */ |