static int radv_init_surface(struct radv_device *device, struct radeon_surf *surface, const struct radv_image_create_info *create_info) { const VkImageCreateInfo *pCreateInfo = create_info->vk_info; unsigned array_mode = radv_choose_tiling(device, create_info); const struct vk_format_description *desc = vk_format_description(pCreateInfo->format); bool is_depth, is_stencil, blendable; is_depth = vk_format_has_depth(desc); is_stencil = vk_format_has_stencil(desc); surface->npix_x = pCreateInfo->extent.width; surface->npix_y = pCreateInfo->extent.height; surface->npix_z = pCreateInfo->extent.depth; surface->blk_w = vk_format_get_blockwidth(pCreateInfo->format); surface->blk_h = vk_format_get_blockheight(pCreateInfo->format); surface->blk_d = 1; surface->array_size = pCreateInfo->arrayLayers; surface->last_level = pCreateInfo->mipLevels - 1; surface->bpe = vk_format_get_blocksize(pCreateInfo->format); /* align byte per element on dword */ if (surface->bpe == 3) { surface->bpe = 4; } surface->nsamples = pCreateInfo->samples ? pCreateInfo->samples : 1; surface->flags = RADEON_SURF_SET(array_mode, MODE); switch (pCreateInfo->imageType){ case VK_IMAGE_TYPE_1D: if (pCreateInfo->arrayLayers > 1) surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE); else surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE); break; case VK_IMAGE_TYPE_2D: if (pCreateInfo->arrayLayers > 1) surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE); else surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); break; case VK_IMAGE_TYPE_3D: surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE); break; default: unreachable("unhandled image type"); } if (is_depth) { surface->flags |= RADEON_SURF_ZBUFFER; } if (is_stencil) surface->flags |= RADEON_SURF_SBUFFER | RADEON_SURF_HAS_SBUFFER_MIPTREE; surface->flags |= RADEON_SURF_HAS_TILE_MODE_INDEX; if ((pCreateInfo->usage & (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_STORAGE_BIT)) || (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) || (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) || device->instance->physicalDevice.rad_info.chip_class < VI || create_info->scanout || !device->allow_dcc || !radv_is_colorbuffer_format_supported(pCreateInfo->format, &blendable)) surface->flags |= RADEON_SURF_DISABLE_DCC; if (create_info->scanout) surface->flags |= RADEON_SURF_SCANOUT; return 0; }
static bool radv_use_dcc_for_image(struct radv_device *device, const struct radv_image_create_info *create_info, const VkImageCreateInfo *pCreateInfo) { bool dcc_compatible_formats; bool blendable; bool shareable = vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR) != NULL; /* DCC (Delta Color Compression) is only available for GFX8+. */ if (device->physical_device->rad_info.chip_class < VI) return false; if (device->instance->debug_flags & RADV_DEBUG_NO_DCC) return false; /* FIXME: DCC is broken for shareable images starting with GFX9 */ if (device->physical_device->rad_info.chip_class >= GFX9 && shareable) return false; /* TODO: Enable DCC for storage images. */ if ((pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT) || (pCreateInfo->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT_KHR)) return false; if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) return false; /* TODO: Enable DCC for mipmaps and array layers. */ if (pCreateInfo->mipLevels > 1 || pCreateInfo->arrayLayers > 1) return false; if (create_info->scanout) return false; /* FIXME: DCC for MSAA with 4x and 8x samples doesn't work yet, while * 2x can be enabled with an option. */ if (pCreateInfo->samples > 2 || (pCreateInfo->samples == 2 && !device->physical_device->dcc_msaa_allowed)) return false; /* Determine if the formats are DCC compatible. */ dcc_compatible_formats = radv_is_colorbuffer_format_supported(pCreateInfo->format, &blendable); if (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) { const struct VkImageFormatListCreateInfoKHR *format_list = (const struct VkImageFormatListCreateInfoKHR *) vk_find_struct_const(pCreateInfo->pNext, IMAGE_FORMAT_LIST_CREATE_INFO_KHR); /* We have to ignore the existence of the list if viewFormatCount = 0 */ if (format_list && format_list->viewFormatCount) { /* compatibility is transitive, so we only need to check * one format with everything else. */ for (unsigned i = 0; i < format_list->viewFormatCount; ++i) { if (!radv_dcc_formats_compatible(pCreateInfo->format, format_list->pViewFormats[i])) dcc_compatible_formats = false; } } else { dcc_compatible_formats = false; } } if (!dcc_compatible_formats) return false; return true; }
static void radv_physical_device_get_format_properties(struct radv_physical_device *physical_device, VkFormat format, VkFormatProperties *out_properties) { VkFormatFeatureFlags linear = 0, tiled = 0, buffer = 0; const struct vk_format_description *desc = vk_format_description(format); bool blendable; if (!desc) { out_properties->linearTilingFeatures = linear; out_properties->optimalTilingFeatures = tiled; out_properties->bufferFeatures = buffer; return; } if (radv_is_storage_image_format_supported(physical_device, format)) { tiled |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; linear |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; } if (radv_is_buffer_format_supported(format)) { buffer |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT | VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT; } if (vk_format_is_depth_or_stencil(format)) { if (radv_is_zs_format_supported(format)) tiled |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; tiled |= VK_FORMAT_FEATURE_BLIT_SRC_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; } else { bool linear_sampling; if (radv_is_sampler_format_supported(format, &linear_sampling)) { linear |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT; tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_BLIT_SRC_BIT; if (linear_sampling) { linear |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; } } if (radv_is_colorbuffer_format_supported(format, &blendable)) { linear |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; tiled |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; if (blendable) { linear |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT; tiled |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT; } } } if (format == VK_FORMAT_R32_UINT || format == VK_FORMAT_R32_SINT) { buffer |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT; linear |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT; tiled |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT; } out_properties->linearTilingFeatures = linear; out_properties->optimalTilingFeatures = tiled; out_properties->bufferFeatures = buffer; }