*/
static enum intel_msaa_layout
compute_msaa_layout(struct brw_context *brw, mesa_format format,
- enum intel_aux_disable aux_disable)
+ uint32_t layout_flags)
{
/* Prior to Gen7, all MSAA surfaces used IMS layout. */
if (brw->gen < 7)
*/
if (brw->gen == 7 && _mesa_get_format_datatype(format) == GL_INT) {
return INTEL_MSAA_LAYOUT_UMS;
- } else if (aux_disable & INTEL_AUX_DISABLE_MCS) {
+ } else if (layout_flags & MIPTREE_LAYOUT_DISABLE_AUX) {
/* We can't use the CMS layout because it uses an aux buffer, the MCS
* buffer. So fallback to UMS, which is identical to CMS without the
* MCS. */
if (brw->gen < 7)
return false;
- if (mt->aux_disable & INTEL_AUX_DISABLE_MCS)
- return false;
-
/* This function applies only to non-multisampled render targets. */
if (mt->num_samples > 1)
return false;
return true;
}
+static bool
+intel_miptree_supports_hiz(struct brw_context *brw,
+ struct intel_mipmap_tree *mt)
+{
+ if (!brw->has_hiz)
+ return false;
+
+ switch (mt->format) {
+ case MESA_FORMAT_Z_FLOAT32:
+ case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
+ case MESA_FORMAT_Z24_UNORM_X8_UINT:
+ case MESA_FORMAT_Z24_UNORM_S8_UINT:
+ case MESA_FORMAT_Z_UNORM16:
+ return true;
+ default:
+ return false;
+ }
+}
+
+
/* On Gen9 support for color buffer compression was extended to single
* sampled surfaces. This is a helper considering both auxiliary buffer
* type and number of samples telling if the given miptree represents
mt->logical_width0 = width0;
mt->logical_height0 = height0;
mt->logical_depth0 = depth0;
- mt->aux_disable = (layout_flags & MIPTREE_LAYOUT_DISABLE_AUX) != 0 ?
- INTEL_AUX_DISABLE_ALL : INTEL_AUX_DISABLE_NONE;
- mt->aux_disable |= INTEL_AUX_DISABLE_CCS;
mt->is_scanout = (layout_flags & MIPTREE_LAYOUT_FOR_SCANOUT) != 0;
+ mt->aux_usage = ISL_AUX_USAGE_NONE;
+ mt->supports_fast_clear = false;
mt->aux_state = NULL;
mt->cpp = _mesa_get_format_bytes(format);
mt->num_samples = num_samples;
int depth_multiply = 1;
if (num_samples > 1) {
/* Adjust width/height/depth for MSAA */
- mt->msaa_layout = compute_msaa_layout(brw, format, mt->aux_disable);
+ mt->msaa_layout = compute_msaa_layout(brw, format, layout_flags);
if (mt->msaa_layout == INTEL_MSAA_LAYOUT_IMS) {
/* From the Ivybridge PRM, Volume 1, Part 1, page 108:
* "If the surface is multisampled and it is a depth or stencil
if (!(layout_flags & MIPTREE_LAYOUT_FOR_BO) &&
_mesa_get_format_base_format(format) == GL_DEPTH_STENCIL &&
(brw->must_use_separate_stencil ||
- (brw->has_separate_stencil &&
- intel_miptree_wants_hiz_buffer(brw, mt)))) {
+ (brw->has_separate_stencil && intel_miptree_supports_hiz(brw, mt)))) {
uint32_t stencil_flags = MIPTREE_LAYOUT_ACCELERATED_UPLOAD;
if (brw->gen == 6) {
stencil_flags |= MIPTREE_LAYOUT_TILING_ANY;
return NULL;
}
- if (mt->aux_disable & INTEL_AUX_DISABLE_MCS)
- assert(mt->msaa_layout != INTEL_MSAA_LAYOUT_CMS);
-
return mt;
}
+/**
+ * Choose the aux usage for this miptree. This function must be called fairly
+ * late in the miptree create process after we have a tiling.
+ */
+static void
+intel_miptree_choose_aux_usage(struct brw_context *brw,
+ struct intel_mipmap_tree *mt)
+{
+ assert(mt->aux_usage == ISL_AUX_USAGE_NONE);
+
+ if (mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) {
+ mt->aux_usage = ISL_AUX_USAGE_MCS;
+ } else if (intel_tiling_supports_ccs(brw, mt->tiling) &&
+ intel_miptree_supports_ccs(brw, mt)) {
+ if (!unlikely(INTEL_DEBUG & DEBUG_NO_RBC) &&
+ brw->gen >= 9 && !mt->is_scanout &&
+ intel_miptree_supports_ccs_e(brw, mt)) {
+ mt->aux_usage = ISL_AUX_USAGE_CCS_E;
+ } else {
+ mt->aux_usage = ISL_AUX_USAGE_CCS_D;
+ }
+ } else if (intel_miptree_supports_hiz(brw, mt)) {
+ mt->aux_usage = ISL_AUX_USAGE_HIZ;
+ }
+
+ /* We can do fast-clear on all auxiliary surface types that are
+ * allocated through the normal texture creation paths.
+ */
+ if (mt->aux_usage != ISL_AUX_USAGE_NONE)
+ mt->supports_fast_clear = true;
+}
+
+
/**
* Choose an appropriate uncompressed format for a requested
* compressed format, if unsupported.
if (layout_flags & MIPTREE_LAYOUT_FOR_SCANOUT)
mt->bo->cache_coherent = false;
+ if (!(layout_flags & MIPTREE_LAYOUT_DISABLE_AUX))
+ intel_miptree_choose_aux_usage(brw, mt);
+
return mt;
}
}
}
- /* If this miptree is capable of supporting fast color clears, set
- * fast_clear_state appropriately to ensure that fast clears will occur.
- * Allocation of the MCS miptree will be deferred until the first fast
- * clear actually occurs or when compressed single sampled buffer is
- * written by the GPU for the first time.
+ /* Since CCS_E can compress more than just clear color, we create the CCS
+ * for it up-front. For CCS_D which only compresses clears, we create the
+ * CCS on-demand when a clear occurs that wants one.
*/
- if (intel_tiling_supports_ccs(brw, mt->tiling) &&
- intel_miptree_supports_ccs(brw, mt)) {
- mt->aux_disable &= ~INTEL_AUX_DISABLE_CCS;
- assert(brw->gen < 8 || mt->halign == 16 || num_samples <= 1);
-
- /* On Gen9+ clients are not currently capable of consuming compressed
- * single-sampled buffers. Disabling compression allows us to skip
- * resolves.
- */
- const bool lossless_compression_disabled = INTEL_DEBUG & DEBUG_NO_RBC;
- const bool is_lossless_compressed =
- unlikely(!lossless_compression_disabled) &&
- brw->gen >= 9 && !mt->is_scanout &&
- intel_miptree_supports_ccs_e(brw, mt);
-
- if (is_lossless_compressed) {
- intel_miptree_alloc_ccs(brw, mt, is_lossless_compressed);
+ if (mt->aux_usage == ISL_AUX_USAGE_CCS_E) {
+ if (!intel_miptree_alloc_ccs(brw, mt)) {
+ intel_miptree_release(&mt);
+ return NULL;
}
}
mt->offset = offset;
mt->tiling = tiling;
+ if (!(layout_flags & MIPTREE_LAYOUT_DISABLE_AUX)) {
+ intel_miptree_choose_aux_usage(brw, mt);
+
+ /* Since CCS_E can compress more than just clear color, we create the
+ * CCS for it up-front. For CCS_D which only compresses clears, we
+ * create the CCS on-demand when a clear occurs that wants one.
+ */
+ if (mt->aux_usage == ISL_AUX_USAGE_CCS_E) {
+ if (!intel_miptree_alloc_ccs(brw, mt)) {
+ intel_miptree_release(&mt);
+ return NULL;
+ }
+ }
+ }
+
return mt;
}
if (!singlesample_mt)
goto fail;
- /* If this miptree is capable of supporting fast color clears, set
- * mcs_state appropriately to ensure that fast clears will occur.
- * Allocation of the MCS miptree will be deferred until the first fast
- * clear actually occurs.
- */
- if (intel_tiling_supports_ccs(intel, singlesample_mt->tiling) &&
- intel_miptree_supports_ccs(intel, singlesample_mt)) {
- singlesample_mt->aux_disable &= ~INTEL_AUX_DISABLE_CCS;
- }
-
if (num_samples == 0) {
intel_miptree_release(&irb->mt);
irb->mt = singlesample_mt;
if (!mt)
goto fail;
- if (intel_miptree_wants_hiz_buffer(brw, mt)) {
+ if (mt->aux_usage == ISL_AUX_USAGE_HIZ) {
ok = intel_miptree_alloc_hiz(brw, mt);
if (!ok)
goto fail;
{
assert(brw->gen >= 7); /* MCS only used on Gen7+ */
assert(mt->mcs_buf == NULL);
- assert((mt->aux_disable & INTEL_AUX_DISABLE_MCS) == 0);
+ assert(mt->aux_usage == ISL_AUX_USAGE_MCS);
/* Multisampled miptrees are only supported for single level. */
assert(mt->first_level == 0);
bool
intel_miptree_alloc_ccs(struct brw_context *brw,
- struct intel_mipmap_tree *mt,
- bool is_ccs_e)
+ struct intel_mipmap_tree *mt)
{
assert(mt->mcs_buf == NULL);
- assert(!(mt->aux_disable & (INTEL_AUX_DISABLE_MCS | INTEL_AUX_DISABLE_CCS)));
+ assert(mt->aux_usage == ISL_AUX_USAGE_CCS_E ||
+ mt->aux_usage == ISL_AUX_USAGE_CCS_D);
struct isl_surf temp_main_surf;
struct isl_surf temp_ccs_surf;
* not use the gpu access flag which can cause an unnecessary delay if the
* backing pages happened to be just used by the GPU.
*/
- const uint32_t alloc_flags = is_ccs_e ? 0 : BO_ALLOC_FOR_RENDER;
+ const uint32_t alloc_flags =
+ mt->aux_usage == ISL_AUX_USAGE_CCS_E ? 0 : BO_ALLOC_FOR_RENDER;
mt->mcs_buf = intel_alloc_aux_buffer(brw, "ccs-miptree",
&temp_ccs_surf, alloc_flags, mt);
if (!mt->mcs_buf) {
* used for lossless compression which requires similar initialisation
* as multi-sample compression.
*/
- if (is_ccs_e) {
+ if (mt->aux_usage == ISL_AUX_USAGE_CCS_E) {
/* Hardware sets the auxiliary buffer to all zeroes when it does full
* resolve. Initialize it accordingly in case the first renderer is
* cpu (or other none compression aware party).
return true;
}
-bool
-intel_miptree_wants_hiz_buffer(struct brw_context *brw,
- struct intel_mipmap_tree *mt)
-{
- if (!brw->has_hiz)
- return false;
-
- if (mt->hiz_buf != NULL)
- return false;
-
- if (mt->aux_disable & INTEL_AUX_DISABLE_HIZ)
- return false;
-
- switch (mt->format) {
- case MESA_FORMAT_Z_FLOAT32:
- case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
- case MESA_FORMAT_Z24_UNORM_X8_UINT:
- case MESA_FORMAT_Z24_UNORM_S8_UINT:
- case MESA_FORMAT_Z_UNORM16:
- return true;
- default:
- return false;
- }
-}
-
bool
intel_miptree_alloc_hiz(struct brw_context *brw,
struct intel_mipmap_tree *mt)
{
assert(mt->hiz_buf == NULL);
- assert((mt->aux_disable & INTEL_AUX_DISABLE_HIZ) == 0);
+ assert(mt->aux_usage == ISL_AUX_USAGE_HIZ);
enum isl_aux_state **aux_state =
create_aux_state_map(mt, ISL_AUX_STATE_AUX_INVALID);
unsigned level, unsigned layer)
{
- if ((mt->aux_disable & INTEL_AUX_DISABLE_CCS) || !mt->mcs_buf)
+ if (!mt->mcs_buf)
return;
/* Fast color clear is supported for mipmapped surfaces only on Gen8+. */
0, INTEL_REMAINING_LAYERS, false, false);
if (mt->mcs_buf) {
- mt->aux_disable |= (INTEL_AUX_DISABLE_CCS | INTEL_AUX_DISABLE_MCS);
brw_bo_unreference(mt->mcs_buf->bo);
free(mt->mcs_buf);
mt->mcs_buf = NULL;
}
if (mt->hiz_buf) {
- mt->aux_disable |= INTEL_AUX_DISABLE_HIZ;
intel_miptree_aux_buffer_free(mt->hiz_buf);
mt->hiz_buf = NULL;
free(mt->aux_state);
mt->aux_state = NULL;
}
+
+ mt->aux_usage = ISL_AUX_USAGE_NONE;
}
if (!mt->mcs_buf)
return ISL_AUX_USAGE_NONE;
- if (mt->num_samples > 1) {
- assert(mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS);
- return ISL_AUX_USAGE_MCS;
- }
-
- if (intel_miptree_is_lossless_compressed(brw, mt)) {
- assert(brw->gen >= 9);
- return ISL_AUX_USAGE_CCS_E;
- }
-
- if ((mt->aux_disable & INTEL_AUX_DISABLE_CCS) == 0)
- return ISL_AUX_USAGE_CCS_D;
-
- unreachable("Invalid MCS miptree");
+ return mt->aux_usage;
}
GEN6_HIZ_STENCIL,
};
-enum intel_aux_disable {
- INTEL_AUX_DISABLE_NONE = 0,
- INTEL_AUX_DISABLE_HIZ = 1 << 1,
- INTEL_AUX_DISABLE_MCS = 1 << 2,
- INTEL_AUX_DISABLE_CCS = 1 << 3,
- INTEL_AUX_DISABLE_ALL = INTEL_AUX_DISABLE_HIZ |
- INTEL_AUX_DISABLE_MCS |
- INTEL_AUX_DISABLE_CCS
-};
-
/**
* Miptree aux buffer. These buffers are associated with a miptree, but the
* format is managed by the hardware.
*/
struct intel_miptree_aux_buffer *hiz_buf;
+ /**
+ * \brief The type of auxiliary compression used by this miptree.
+ *
+ * This describes the type of auxiliary compression that is intended to be
+ * used by this miptree. An aux usage of ISL_AUX_USAGE_NONE means that
+ * auxiliary compression is permanently disabled. An aux usage other than
+ * ISL_AUX_USAGE_NONE does not imply that the auxiliary buffer has actually
+ * been allocated nor does it imply that auxiliary compression will always
+ * be enabled for this surface. For instance, with CCS_D, we may allocate
+ * the CCS on-the-fly and it may not be used for texturing if the miptree
+ * is fully resolved.
+ */
+ enum isl_aux_usage aux_usage;
+
+ /**
+ * \brief Whether or not this miptree supports fast clears.
+ */
+ bool supports_fast_clear;
+
/**
* \brief Maps miptree slices to their current aux state
*
*/
union isl_color_value fast_clear_color;
- /**
- * Disable allocation of auxiliary buffers, such as the HiZ buffer and MCS
- * buffer. This is useful for sharing the miptree bo with an external client
- * that doesn't understand auxiliary buffers.
- */
- enum intel_aux_disable aux_disable;
-
/**
* Tells if the underlying buffer is to be also consumed by entities other
* than the driver. This allows logic to turn off features such as lossless
bool
intel_miptree_alloc_ccs(struct brw_context *brw,
- struct intel_mipmap_tree *mt,
- bool is_ccs_e);
+ struct intel_mipmap_tree *mt);
enum {
MIPTREE_LAYOUT_ACCELERATED_UPLOAD = 1 << 0,
* functions on a miptree without HiZ. In that case, each function is a no-op.
*/
-bool
-intel_miptree_wants_hiz_buffer(struct brw_context *brw,
- struct intel_mipmap_tree *mt);
-
/**
* \brief Allocate the miptree's embedded HiZ miptree.
* \see intel_mipmap_tree:hiz_mt