static unsigned
radv_choose_tiling(struct radv_device *device,
- const VkImageCreateInfo *pCreateInfo)
+ const VkImageCreateInfo *pCreateInfo,
+ VkFormat format)
{
if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) {
assert(pCreateInfo->samples <= 1);
return RADEON_SURF_MODE_LINEAR_ALIGNED;
}
- if (!vk_format_is_compressed(pCreateInfo->format) &&
- !vk_format_is_depth_or_stencil(pCreateInfo->format)
+ if (!vk_format_is_compressed(format) &&
+ !vk_format_is_depth_or_stencil(format)
&& device->physical_device->rad_info.chip_class <= GFX8) {
/* this causes hangs in some VK CTS tests on GFX9. */
/* Textures with a very small height are recommended to be linear. */
static bool
radv_use_tc_compat_htile_for_image(struct radv_device *device,
- const VkImageCreateInfo *pCreateInfo)
+ const VkImageCreateInfo *pCreateInfo,
+ VkFormat format)
{
/* TC-compat HTILE is only available for GFX8+. */
if (device->physical_device->rad_info.chip_class < GFX8)
* tests - disable for now. On GFX10 D32_SFLOAT is affected as well.
*/
if (pCreateInfo->samples >= 2 &&
- (pCreateInfo->format == VK_FORMAT_D32_SFLOAT_S8_UINT ||
- (pCreateInfo->format == VK_FORMAT_D32_SFLOAT &&
+ (format == VK_FORMAT_D32_SFLOAT_S8_UINT ||
+ (format == VK_FORMAT_D32_SFLOAT &&
device->physical_device->rad_info.chip_class == GFX10)))
return false;
* supports 32-bit. Though, it's possible to enable TC-compat for
* 16-bit depth surfaces if no Z planes are compressed.
*/
- if (pCreateInfo->format != VK_FORMAT_D32_SFLOAT_S8_UINT &&
- pCreateInfo->format != VK_FORMAT_D32_SFLOAT &&
- pCreateInfo->format != VK_FORMAT_D16_UNORM)
+ if (format != VK_FORMAT_D32_SFLOAT_S8_UINT &&
+ format != VK_FORMAT_D32_SFLOAT &&
+ format != VK_FORMAT_D16_UNORM)
return false;
if (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
if (format_list->pViewFormats[i] == VK_FORMAT_UNDEFINED)
continue;
- if (pCreateInfo->format != format_list->pViewFormats[i])
+ if (format != format_list->pViewFormats[i])
return false;
}
} else {
static bool
radv_use_dcc_for_image(struct radv_device *device,
const struct radv_image *image,
- const VkImageCreateInfo *pCreateInfo)
+ const VkImageCreateInfo *pCreateInfo,
+ VkFormat format)
{
bool dcc_compatible_formats;
bool blendable;
if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR)
return false;
- if (vk_format_is_subsampled(pCreateInfo->format) ||
- vk_format_get_plane_count(pCreateInfo->format) > 1)
+ if (vk_format_is_subsampled(format) ||
+ vk_format_get_plane_count(format) > 1)
return false;
/* TODO: Enable DCC for mipmaps on GFX9+. */
/* Determine if the formats are DCC compatible. */
dcc_compatible_formats =
- radv_is_colorbuffer_format_supported(pCreateInfo->format,
+ radv_is_colorbuffer_format_supported(format,
&blendable);
if (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
if (format_list->pViewFormats[i] == VK_FORMAT_UNDEFINED)
continue;
- if (!radv_dcc_formats_compatible(pCreateInfo->format,
+ if (!radv_dcc_formats_compatible(format,
format_list->pViewFormats[i]))
dcc_compatible_formats = false;
}
const struct radv_image *image,
struct radeon_surf *surface,
unsigned plane_id,
- const VkImageCreateInfo *pCreateInfo)
+ const VkImageCreateInfo *pCreateInfo,
+ VkFormat image_format)
{
- unsigned array_mode = radv_choose_tiling(device, pCreateInfo);
- VkFormat format = vk_format_get_plane_format(pCreateInfo->format, plane_id);
+ unsigned array_mode = radv_choose_tiling(device, pCreateInfo, image_format);
+ VkFormat format = vk_format_get_plane_format(image_format, plane_id);
const struct vk_format_description *desc = vk_format_description(format);
bool is_depth, is_stencil;
if (is_depth) {
surface->flags |= RADEON_SURF_ZBUFFER;
- if (radv_use_tc_compat_htile_for_image(device, pCreateInfo))
+ if (radv_use_tc_compat_htile_for_image(device, pCreateInfo, image_format))
surface->flags |= RADEON_SURF_TC_COMPATIBLE_HTILE;
}
if (device->physical_device->rad_info.chip_class >= GFX9 &&
pCreateInfo->imageType == VK_IMAGE_TYPE_3D &&
- vk_format_get_blocksizebits(pCreateInfo->format) == 128 &&
- vk_format_is_compressed(pCreateInfo->format))
+ vk_format_get_blocksizebits(image_format) == 128 &&
+ vk_format_is_compressed(image_format))
surface->flags |= RADEON_SURF_NO_RENDER_TARGET;
surface->flags |= RADEON_SURF_OPTIMIZE_FOR_SPACE;
- if (!radv_use_dcc_for_image(device, image, pCreateInfo))
+ if (!radv_use_dcc_for_image(device, image, pCreateInfo, image_format))
surface->flags |= RADEON_SURF_DISABLE_DCC;
return 0;
* else: swizzle_address >= NUM_RECORDS
*/
state[3] |= S_008F0C_FORMAT(fmt->img_format) |
- S_008F0C_OOB_SELECT(0) |
+ S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_STRUCTURED_WITH_OFFSET) |
S_008F0C_RESOURCE_LEVEL(1);
} else {
num_format = radv_translate_buffer_numformat(desc, first_non_void);
return bc_swizzle;
}
-static bool vi_alpha_is_on_msb(struct radv_device *device, VkFormat format)
+bool vi_alpha_is_on_msb(struct radv_device *device, VkFormat format)
{
const struct vk_format_description *desc = vk_format_description(format);
*/
state[4] = S_00A010_DEPTH(type == V_008F1C_SQ_RSRC_IMG_3D ? depth - 1 : last_layer) |
S_00A010_BASE_ARRAY(first_layer);
- state[5] = S_00A014_ARRAY_PITCH(!!(type == V_008F1C_SQ_RSRC_IMG_3D)) |
+ state[5] = S_00A014_ARRAY_PITCH(0) |
S_00A014_MAX_MIP(image->info.samples > 1 ?
util_logbase2(image->info.samples) :
image->info.levels - 1) |
image->planes[i].surface.htile_size = 0;
}
-static VkResult
+VkResult
radv_image_create_layout(struct radv_device *device,
- const struct radv_image_create_info *create_info,
+ struct radv_image_create_info create_info,
struct radv_image *image)
{
/* Check that we did not initialize things earlier */
assert(!image->planes[0].surface.surf_size);
+ /* Clear the pCreateInfo pointer so we catch issues in the delayed case when we test in the
+ * common internal case. */
+ create_info.vk_info = NULL;
+
struct ac_surf_info image_info = image->info;
- VkResult result = radv_patch_image_from_extra_info(device, image, create_info, &image_info);
+ VkResult result = radv_patch_image_from_extra_info(device, image, &create_info, &image_info);
if (result != VK_SUCCESS)
return result;
image->planes[plane].format = vk_format_get_plane_format(image->vk_format, plane);
}
- if (!create_info->no_metadata_planes) {
+ if (!create_info.no_metadata_planes) {
/* Try to enable DCC first. */
if (radv_image_can_enable_dcc(device, image)) {
radv_image_alloc_dcc(image);
RADV_FROM_HANDLE(radv_device, device, _device);
const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
struct radv_image *image = NULL;
+ VkFormat format = radv_select_android_external_format(pCreateInfo->pNext,
+ pCreateInfo->format);
assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
- const unsigned plane_count = vk_format_get_plane_count(pCreateInfo->format);
+ const unsigned plane_count = vk_format_get_plane_count(format);
const size_t image_struct_size = sizeof(*image) + sizeof(struct radv_image_plane) * plane_count;
radv_assert(pCreateInfo->mipLevels > 0);
image->info.storage_samples = pCreateInfo->samples;
image->info.array_size = pCreateInfo->arrayLayers;
image->info.levels = pCreateInfo->mipLevels;
- image->info.num_channels = vk_format_get_nr_components(pCreateInfo->format);
+ image->info.num_channels = vk_format_get_nr_components(format);
- image->vk_format = pCreateInfo->format;
+ image->vk_format = format;
image->tiling = pCreateInfo->tiling;
image->usage = pCreateInfo->usage;
image->flags = pCreateInfo->flags;
image->queue_family_mask |= 1u << pCreateInfo->pQueueFamilyIndices[i];
}
- image->shareable = vk_find_struct_const(pCreateInfo->pNext,
- EXTERNAL_MEMORY_IMAGE_CREATE_INFO) != NULL;
- if (!vk_format_is_depth_or_stencil(pCreateInfo->format) && !image->shareable) {
+ const VkExternalMemoryImageCreateInfo *external_info =
+ vk_find_struct_const(pCreateInfo->pNext,
+ EXTERNAL_MEMORY_IMAGE_CREATE_INFO) ;
+
+ image->shareable = external_info;
+ if (!vk_format_is_depth_or_stencil(format) && !image->shareable) {
image->info.surf_index = &device->image_mrt_offset_counter;
}
for (unsigned plane = 0; plane < image->plane_count; ++plane) {
- radv_init_surface(device, image, &image->planes[plane].surface, plane, pCreateInfo);
+ radv_init_surface(device, image, &image->planes[plane].surface, plane, pCreateInfo, format);
+ }
+
+ bool delay_layout = external_info &&
+ (external_info->handleTypes & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID);
+
+ if (delay_layout) {
+ *pImage = radv_image_to_handle(image);
+ assert (!(image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT));
+ return VK_SUCCESS;
}
- ASSERTED VkResult result = radv_image_create_layout(device, create_info, image);
+ ASSERTED VkResult result = radv_image_create_layout(device, *create_info, image);
assert(result == VK_SUCCESS);
if (image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) {
iview->plane_id = radv_plane_from_aspect(pCreateInfo->subresourceRange.aspectMask);
iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
iview->multiple_planes = vk_format_get_plane_count(image->vk_format) > 1 && iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT;
+
iview->vk_format = pCreateInfo->format;
+ /* If the image has an Android external format, pCreateInfo->format will be
+ * VK_FORMAT_UNDEFINED. */
+ if (iview->vk_format == VK_FORMAT_UNDEFINED)
+ iview->vk_format = image->vk_format;
+
if (iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
iview->vk_format = vk_format_stencil_only(iview->vk_format);
} else if (iview->aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) {
return radv_image_has_htile(image) &&
(layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
+ layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR ||
+ layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR ||
(layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
queue_mask == (1u << RADV_QUEUE_GENERAL)));
}
return radv_image_has_htile(image) &&
(layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
+ layout == VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR ||
+ layout == VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR ||
(layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
queue_mask == (1u << RADV_QUEUE_GENERAL)));
}