&image->planes[plane].surface.isl,
&image->planes[plane].aux_surface.isl);
assert(ok);
- image->planes[plane].aux_usage = ISL_AUX_USAGE_HIZ;
+ if (!isl_surf_supports_ccs(&device->isl_dev,
+ &image->planes[plane].surface.isl)) {
+ image->planes[plane].aux_usage = ISL_AUX_USAGE_HIZ;
+ } else if (image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
+ VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) &&
+ image->samples == 1) {
+ /* If it's used as an input attachment or a texture and it's
+ * single-sampled (this is a requirement for HiZ+CCS write-through
+ * mode), use write-through mode so that we don't need to resolve
+ * before texturing. This will make depth testing a bit slower but
+ * texturing faster.
+ *
+ * TODO: This is a heuristic trade-off; we haven't tuned it at all.
+ */
+ assert(device->info.gen >= 12);
+ image->planes[plane].aux_usage = ISL_AUX_USAGE_HIZ_CCS_WT;
+ } else {
+ assert(device->info.gen >= 12);
+ image->planes[plane].aux_usage = ISL_AUX_USAGE_HIZ_CCS;
+ }
add_surface(image, &image->planes[plane].aux_surface, plane);
} else if ((aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) && image->samples == 1) {
if (image->n_planes != 1) {
anv_assert(pCreateInfo->extent.height > 0);
anv_assert(pCreateInfo->extent.depth > 0);
- image = vk_zalloc2(&device->alloc, alloc, sizeof(*image), 8,
+ image = vk_zalloc2(&device->vk.alloc, alloc, sizeof(*image), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!image)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+ vk_object_base_init(&device->vk, &image->base, VK_OBJECT_TYPE_IMAGE);
image->type = pCreateInfo->imageType;
image->extent = pCreateInfo->extent;
image->vk_format = pCreateInfo->format;
fail:
if (image)
- vk_free2(&device->alloc, alloc, image);
+ vk_free2(&device->vk.alloc, alloc, image);
return r;
}
}
}
- vk_free2(&device->alloc, pAllocator, image);
+ vk_object_base_finish(&image->base);
+ vk_free2(&device->vk.alloc, pAllocator, image);
}
static void anv_image_bind_memory_plane(struct anv_device *device,
assert(aspect == VK_IMAGE_ASPECT_COLOR_BIT);
return VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT;
- case VK_IMAGE_LAYOUT_RANGE_SIZE:
case VK_IMAGE_LAYOUT_MAX_ENUM:
unreachable("Invalid image layout.");
}
unreachable("Invalid image layout.");
}
-ASSERTED static bool
+static bool
vk_image_layout_is_read_only(VkImageLayout layout,
VkImageAspectFlagBits aspect)
{
case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
return aspect == VK_IMAGE_ASPECT_STENCIL_BIT;
- case VK_IMAGE_LAYOUT_RANGE_SIZE:
case VK_IMAGE_LAYOUT_MAX_ENUM:
unreachable("Invalid image layout.");
}
uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);
/* If we don't have an aux buffer then aux state makes no sense */
- assert(image->planes[plane].aux_usage != ISL_AUX_USAGE_NONE);
+ const enum isl_aux_usage aux_usage = image->planes[plane].aux_usage;
+ assert(aux_usage != ISL_AUX_USAGE_NONE);
/* All images that use an auxiliary surface are required to be tiled. */
assert(image->planes[plane].surface.isl.tiling != ISL_TILING_LINEAR);
/* Stencil has no aux */
assert(aspect != VK_IMAGE_ASPECT_STENCIL_BIT);
+ /* Handle a few special cases */
switch (layout) {
/* Invalid layouts */
- case VK_IMAGE_LAYOUT_RANGE_SIZE:
case VK_IMAGE_LAYOUT_MAX_ENUM:
unreachable("Invalid image layout.");
case VK_IMAGE_LAYOUT_PREINITIALIZED:
return ISL_AUX_STATE_AUX_INVALID;
- /* General layout */
- case VK_IMAGE_LAYOUT_GENERAL:
- if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
- if (image->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
- /* This buffer could be used as both a depth and input attachment
- * at the same time in which case compression could cause issues.
- */
- return ISL_AUX_STATE_AUX_INVALID;
- } else if (anv_can_sample_with_hiz(devinfo, image)) {
- return ISL_AUX_STATE_COMPRESSED_CLEAR;
- } else {
- return ISL_AUX_STATE_AUX_INVALID;
- }
- } else if (image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_D) {
- return ISL_AUX_STATE_PASS_THROUGH;
- } else {
- return ISL_AUX_STATE_COMPRESSED_CLEAR;
- }
-
- /* Transfer layouts */
- case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
- if (image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_D) {
- return ISL_AUX_STATE_PASS_THROUGH;
- } else {
- return ISL_AUX_STATE_COMPRESSED_CLEAR;
- }
-
- /* Sampling layouts */
- case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL_KHR:
- case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
- case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
- assert((image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) == 0);
- /* Fall-through */
- case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
- case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
- if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
- if (anv_can_sample_with_hiz(devinfo, image))
- return ISL_AUX_STATE_COMPRESSED_CLEAR;
- else
- return ISL_AUX_STATE_RESOLVED;
- } else if (image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_D) {
- return ISL_AUX_STATE_PASS_THROUGH;
- } else {
- return ISL_AUX_STATE_COMPRESSED_CLEAR;
- }
-
- case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL_KHR:
- return ISL_AUX_STATE_RESOLVED;
-
case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: {
assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
}
}
- /* Rendering layouts */
- case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
- assert(aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV);
- /* fall-through */
- case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR:
- if (image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_D) {
- return ISL_AUX_STATE_PARTIAL_CLEAR;
- } else {
- return ISL_AUX_STATE_COMPRESSED_CLEAR;
- }
+ default:
+ break;
+ }
- case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR:
- case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
- case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
- assert(aspect == VK_IMAGE_ASPECT_DEPTH_BIT);
- return ISL_AUX_STATE_COMPRESSED_CLEAR;
+ const bool read_only = vk_image_layout_is_read_only(layout, aspect);
- case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
- unreachable("VK_KHR_shared_presentable_image is unsupported");
+ const VkImageUsageFlags image_aspect_usage =
+ aspect == VK_IMAGE_ASPECT_STENCIL_BIT ? image->stencil_usage :
+ image->usage;
+ const VkImageUsageFlags usage =
+ vk_image_layout_to_usage_flags(layout, aspect) & image_aspect_usage;
- case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
- unreachable("VK_EXT_fragment_density_map is unsupported");
+ bool aux_supported = true;
- case VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV:
- unreachable("VK_NV_shading_rate_image is unsupported");
+ if ((usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) && !read_only) {
+ /* This image could be used as both an input attachment and a render
+ * target (depth, stencil, or color) at the same time and this can cause
+ * corruption.
+ *
+ * We currently only disable aux in this way for depth even though we
+ * disable it for color in GL.
+ *
+ * TODO: Should we be disabling this in more cases?
+ */
+ if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT)
+ aux_supported = false;
+ }
+
+ if (usage & VK_IMAGE_USAGE_STORAGE_BIT)
+ aux_supported = false;
+
+ if (usage & (VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+ VK_IMAGE_USAGE_SAMPLED_BIT |
+ VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {
+ switch (aux_usage) {
+ case ISL_AUX_USAGE_HIZ:
+ if (!anv_can_sample_with_hiz(devinfo, image))
+ aux_supported = false;
+ break;
+
+ case ISL_AUX_USAGE_HIZ_CCS:
+ aux_supported = false;
+ break;
+
+ case ISL_AUX_USAGE_HIZ_CCS_WT:
+ break;
+
+ case ISL_AUX_USAGE_CCS_D:
+ aux_supported = false;
+ break;
+
+ case ISL_AUX_USAGE_CCS_E:
+ case ISL_AUX_USAGE_MCS:
+ break;
+
+ default:
+ unreachable("Unsupported aux usage");
+ }
}
- unreachable("layout is not a VkImageLayout enumeration member.");
+ switch (aux_usage) {
+ case ISL_AUX_USAGE_HIZ:
+ case ISL_AUX_USAGE_HIZ_CCS:
+ case ISL_AUX_USAGE_HIZ_CCS_WT:
+ if (aux_supported) {
+ return ISL_AUX_STATE_COMPRESSED_CLEAR;
+ } else if (read_only) {
+ return ISL_AUX_STATE_RESOLVED;
+ } else {
+ return ISL_AUX_STATE_AUX_INVALID;
+ }
+
+ case ISL_AUX_USAGE_CCS_D:
+ /* We only support clear in exactly one state */
+ if (layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {
+ assert(aux_supported);
+ return ISL_AUX_STATE_PARTIAL_CLEAR;
+ } else {
+ return ISL_AUX_STATE_PASS_THROUGH;
+ }
+
+ case ISL_AUX_USAGE_CCS_E:
+ case ISL_AUX_USAGE_MCS:
+ if (aux_supported) {
+ return ISL_AUX_STATE_COMPRESSED_CLEAR;
+ } else {
+ return ISL_AUX_STATE_PASS_THROUGH;
+ }
+
+ default:
+ unreachable("Unsupported aux usage");
+ }
}
/**
case ISL_AUX_STATE_COMPRESSED_CLEAR:
case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:
- if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
- return ISL_AUX_USAGE_HIZ;
- } else {
- assert(image->planes[plane].aux_usage != ISL_AUX_USAGE_NONE);
- return image->planes[plane].aux_usage;
- }
+ return image->planes[plane].aux_usage;
case ISL_AUX_STATE_RESOLVED:
/* We can only use RESOLVED in read-only layouts because any write will
* depth/stencil attachment, we should enable HiZ so that we can get
* faster depth testing.
*/
- return ISL_AUX_USAGE_HIZ;
+ return image->planes[plane].aux_usage;
} else {
return ISL_AUX_USAGE_NONE;
}
return ANV_FAST_CLEAR_ANY;
} else if (image->planes[plane].aux_usage == ISL_AUX_USAGE_MCS ||
image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E) {
- /* If the image has MCS or CCS_E enabled all the time then we can use
- * fast-clear as long as the clear color is the default value of zero
- * since this is the default value we program into every surface
- * state used for texturing.
- */
- return ANV_FAST_CLEAR_DEFAULT_VALUE;
+ if (devinfo->gen >= 11) {
+ /* On ICL and later, the sampler hardware uses a copy of the clear
+ * value that is encoded as a pixel value. Therefore, we can use
+ * any clear color we like for sampling.
+ */
+ return ANV_FAST_CLEAR_ANY;
+ } else {
+ /* If the image has MCS or CCS_E enabled all the time then we can
+ * use fast-clear as long as the clear color is the default value
+ * of zero since this is the default value we program into every
+ * surface state used for texturing.
+ */
+ return ANV_FAST_CLEAR_DEFAULT_VALUE;
+ }
} else {
return ANV_FAST_CLEAR_NONE;
}
* value (SKL+), define the clear value to the optimal constant.
*/
union isl_color_value default_clear_color = { .u32 = { 0, } };
- if (device->info.gen >= 9 && aux_usage == ISL_AUX_USAGE_HIZ)
+ if (device->info.gen >= 9 && aspect == VK_IMAGE_ASPECT_DEPTH_BIT)
default_clear_color.f32[0] = ANV_HZ_FC_VAL;
if (!clear_color)
clear_color = &default_clear_color;
struct anv_address clear_address = ANV_NULL_ADDRESS;
if (device->info.gen >= 10 && aux_usage != ISL_AUX_USAGE_NONE) {
- if (aux_usage == ISL_AUX_USAGE_HIZ) {
+ if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
clear_address = (struct anv_address) {
.bo = device->hiz_clear_bo,
.offset = 0,
ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
struct anv_image_view *iview;
- iview = vk_zalloc2(&device->alloc, pAllocator, sizeof(*iview), 8,
+ iview = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*iview), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (iview == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
+ vk_object_base_init(&device->vk, &iview->base, VK_OBJECT_TYPE_IMAGE_VIEW);
+
const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
assert(range->layerCount > 0);
}
}
- vk_free2(&device->alloc, pAllocator, iview);
+ vk_object_base_finish(&iview->base);
+ vk_free2(&device->vk.alloc, pAllocator, iview);
}
ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer);
struct anv_buffer_view *view;
- view = vk_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
+ view = vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*view), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (!view)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
/* TODO: Handle the format swizzle? */
+ vk_object_base_init(&device->vk, &view->base, VK_OBJECT_TYPE_BUFFER_VIEW);
view->format = anv_get_isl_format(&device->info, pCreateInfo->format,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_TILING_LINEAR);
anv_state_pool_free(&device->surface_state_pool,
view->writeonly_storage_surface_state);
- vk_free2(&device->alloc, pAllocator, view);
+ vk_object_base_finish(&view->base);
+ vk_free2(&device->vk.alloc, pAllocator, view);
}