示例#1
0
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;
}
示例#2
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;
}
示例#3
0
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;
}