isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
}
- if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
- /* blorp implements transfers by rendering into the destination image. */
+ if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT &&
+ aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
+ /* blorp implements transfers by rendering into the destination image.
+ * Only request this with color images, as we deal with depth/stencil
+ * formats differently. */
isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
}
/* Add a HiZ surface to a depth buffer that will be used for rendering.
*/
- if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT &&
- (image->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
-
+ if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
/* Allow the user to control HiZ enabling. Disable by default on gen7
* because resolves are not currently implemented pre-BDW.
*/
- if (!env_var_as_boolean("INTEL_VK_HIZ", dev->info.gen >= 8)) {
+ if (!(image->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
+ /* It will never be used as an attachment, HiZ is pointless. */
+ } else if (image->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
+ /* From the 1.0.37 spec:
+ *
+ * "An attachment used as an input attachment and depth/stencil
+ * attachment must be in either VK_IMAGE_LAYOUT_GENERAL or
+ * VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL."
+ *
+ * It will never have a layout of
+ * VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, so HiZ is
+ * currently pointless. If transfer operations learn to use the HiZ
+ * buffer, we can enable HiZ for VK_IMAGE_LAYOUT_GENERAL and support
+ * input attachments.
+ */
+ anv_finishme("Implement HiZ for input attachments");
+ } else if (!env_var_as_boolean("INTEL_VK_HIZ", dev->info.gen >= 8)) {
anv_finishme("Implement gen7 HiZ");
} else if (vk_info->mipLevels > 1) {
anv_finishme("Test multi-LOD HiZ");
+ } else if (vk_info->arrayLayers > 1) {
+ anv_finishme("Implement multi-arrayLayer HiZ clears and resolves");
} else if (dev->info.gen == 8 && vk_info->samples > 1) {
anv_finishme("Test gen8 multisampled HiZ");
} else {
+ assert(image->aux_surface.isl.size == 0);
isl_surf_get_hiz_surf(&dev->isl_dev, &image->depth_surface.isl,
- &image->hiz_surface.isl);
- add_surface(image, &image->hiz_surface);
+ &image->aux_surface.isl);
+ add_surface(image, &image->aux_surface);
+ image->aux_usage = ISL_AUX_USAGE_HIZ;
+ }
+ } else if (aspect == VK_IMAGE_ASPECT_COLOR_BIT && vk_info->samples == 1) {
+ if (!unlikely(INTEL_DEBUG & DEBUG_NO_RBC)) {
+ assert(image->aux_surface.isl.size == 0);
+ ok = isl_surf_get_ccs_surf(&dev->isl_dev, &anv_surf->isl,
+ &image->aux_surface.isl);
+ if (ok) {
+ add_surface(image, &image->aux_surface);
+
+ /* For images created without MUTABLE_FORMAT_BIT set, we know that
+ * they will always be used with the original format. In
+ * particular, they will always be used with a format that
+ * supports color compression. If it's never used as a storage
+ * image, then it will only be used through the sampler or the as
+ * a render target. This means that it's safe to just leave
+ * compression on at all times for these formats.
+ */
+ if (!(vk_info->usage & VK_IMAGE_USAGE_STORAGE_BIT) &&
+ !(vk_info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) &&
+ isl_format_supports_ccs_e(&dev->info, format)) {
+ image->aux_usage = ISL_AUX_USAGE_CCS_E;
+ }
+ }
}
}
image->samples = pCreateInfo->samples;
image->usage = pCreateInfo->usage;
image->tiling = pCreateInfo->tiling;
+ image->aux_usage = ISL_AUX_USAGE_NONE;
uint32_t b;
for_each_bit(b, image->aspects) {
image->offset = 0;
}
- if (anv_image_has_hiz(image)) {
+ if (image->aux_surface.isl.size > 0) {
/* The offset and size must be a multiple of 4K or else the
* anv_gem_mmap call below will return NULL.
*/
- assert((image->offset + image->hiz_surface.offset) % 4096 == 0);
- assert(image->hiz_surface.isl.size % 4096 == 0);
-
- /* HiZ surfaces need to have their memory cleared to 0 before they
- * can be used. If we let it have garbage data, it can cause GPU
- * hangs on some hardware.
+ assert((image->offset + image->aux_surface.offset) % 4096 == 0);
+ assert(image->aux_surface.isl.size % 4096 == 0);
+
+ /* Auxiliary surfaces need to have their memory cleared to 0 before they
+ * can be used. For CCS surfaces, this puts them in the "resolved"
+ * state so they can be used with CCS enabled before we ever touch it
+ * from the GPU. For HiZ, we need something valid or else we may get
+ * GPU hangs on some hardware and 0 works fine.
*/
void *map = anv_gem_mmap(device, image->bo->gem_handle,
- image->offset + image->hiz_surface.offset,
- image->hiz_surface.isl.size,
+ image->offset + image->aux_surface.offset,
+ image->aux_surface.isl.size,
device->info.has_llc ? 0 : I915_MMAP_WC);
/* If anv_gem_mmap returns NULL, it's likely that the kernel was
if (map == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
- memset(map, 0, image->hiz_surface.isl.size);
+ memset(map, 0, image->aux_surface.isl.size);
- anv_gem_munmap(map, image->hiz_surface.isl.size);
+ anv_gem_munmap(map, image->aux_surface.isl.size);
}
return VK_SUCCESS;
.depth = anv_minify(image->extent.depth , range->baseMipLevel),
};
- if (image->type == VK_IMAGE_TYPE_3D) {
+ if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D) {
iview->isl.base_array_layer = 0;
iview->isl.array_len = iview->extent.depth;
}
iview->isl.usage = 0;
}
- if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
+ /* If the HiZ buffer can be sampled from, set the constant clear color.
+ * If it cannot, disable the isl aux usage flag.
+ */
+ float red_clear_color = 0.0f;
+ enum isl_aux_usage surf_usage = image->aux_usage;
+ if (image->aux_usage == ISL_AUX_USAGE_HIZ) {
+ if (iview->aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT &&
+ anv_can_sample_with_hiz(device->info.gen, image->samples)) {
+ /* When a HiZ buffer is sampled on gen9+, ensure that
+ * the constant fast clear value is set in the surface state.
+ */
+ if (device->info.gen >= 9)
+ red_clear_color = ANV_HZ_FC_VAL;
+ } else {
+ surf_usage = ISL_AUX_USAGE_NONE;
+ }
+ }
+
+ /* Input attachment surfaces for color are allocated and filled
+ * out at BeginRenderPass time because they need compression information.
+ * Compression is not yet enabled for depth textures and stencil doesn't
+ * allow compression so we can just use the texture surface state from the
+ * view.
+ */
+ if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT ||
+ (image->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT &&
+ !(iview->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT))) {
iview->sampler_surface_state = alloc_surface_state(device);
struct isl_view view = iview->isl;
iview->sampler_surface_state.map,
.surf = &surface->isl,
.view = &view,
+ .clear_color.f32 = { red_clear_color,},
+ .aux_surf = &image->aux_surface.isl,
+ .aux_usage = surf_usage,
.mocs = device->default_mocs);
if (!device->info.has_llc)
iview->storage_surface_state.map,
.surf = &surface->isl,
.view = &view,
+ .aux_surf = &image->aux_surface.isl,
+ .aux_usage = surf_usage,
.mocs = device->default_mocs);
} else {
anv_fill_buffer_surface_state(device, iview->storage_surface_state,