// Format capabilities
static VkFormatFeatureFlags
-get_image_format_properties(const struct gen_device_info *devinfo,
- VkFormat vk_format,
- enum isl_format base,
- struct anv_format_plane plane_format,
- VkImageTiling vk_tiling)
+get_image_format_features(const struct gen_device_info *devinfo,
+ VkFormat vk_format,
+ const struct anv_format *anv_format,
+ VkImageTiling vk_tiling)
{
VkFormatFeatureFlags flags = 0;
- if (plane_format.isl_format == ISL_FORMAT_UNSUPPORTED)
+ if (anv_format == NULL)
return 0;
const VkImageAspectFlags aspects = vk_format_aspects(vk_format);
return flags;
}
+ const struct anv_format_plane plane_format =
+ anv_get_format_plane(devinfo, vk_format, VK_IMAGE_ASPECT_COLOR_BIT,
+ vk_tiling);
+
+ if (plane_format.isl_format == ISL_FORMAT_UNSUPPORTED)
+ return 0;
+
+ struct anv_format_plane base_plane_format = plane_format;
+ if (vk_tiling == VK_IMAGE_TILING_OPTIMAL) {
+ base_plane_format = anv_get_format_plane(devinfo, vk_format,
+ VK_IMAGE_ASPECT_COLOR_BIT,
+ VK_IMAGE_TILING_LINEAR);
+ }
+
+ enum isl_format base_isl_format = base_plane_format.isl_format;
+
/* ASTC textures must be in Y-tiled memory */
if (vk_tiling == VK_IMAGE_TILING_LINEAR &&
isl_format_get_layout(plane_format.isl_format)->txc == ISL_TXC_ASTC)
/* Load/store is determined based on base format. This prevents RGB
* formats from showing up as load/store capable.
*/
- if (isl_is_storage_image_format(base))
+ if (isl_is_storage_image_format(base_isl_format))
flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
- if (base == ISL_FORMAT_R32_SINT || base == ISL_FORMAT_R32_UINT)
+ if (base_isl_format == ISL_FORMAT_R32_SINT ||
+ base_isl_format == ISL_FORMAT_R32_UINT)
flags |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
if (flags) {
VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR;
}
+ /* XXX: We handle 3-channel formats by switching them out for RGBX or
+ * RGBA formats behind-the-scenes. This works fine for textures
+ * because the upload process will fill in the extra channel.
+ * We could also support it for render targets, but it will take
+ * substantially more work and we have enough RGBX formats to handle
+ * what most clients will want.
+ */
+ if (vk_tiling == VK_IMAGE_TILING_OPTIMAL &&
+ base_isl_format != ISL_FORMAT_UNSUPPORTED &&
+ !util_is_power_of_two(isl_format_layouts[base_isl_format].bpb) &&
+ isl_format_rgb_to_rgbx(base_isl_format) == ISL_FORMAT_UNSUPPORTED) {
+ flags &= ~VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
+ flags &= ~VK_FORMAT_FEATURE_BLIT_DST_BIT;
+ }
+
+ if (anv_format->can_ycbcr) {
+ /* The sampler doesn't have support for mid point when it handles YUV on
+ * its own.
+ */
+ if (isl_format_is_yuv(anv_format->planes[0].isl_format)) {
+ /* TODO: We've disabled linear implicit reconstruction with the
+ * sampler. The failures show a slightly out of range values on the
+ * bottom left of the sampled image.
+ */
+ flags |= VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR;
+ } else {
+ flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR |
+ VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR |
+ VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR;
+ }
+
+ /* We can support cosited chroma locations when handle planes with our
+ * own shader snippets.
+ */
+ for (unsigned p = 0; p < anv_format->n_planes; p++) {
+ if (anv_format->planes[p].denominator_scales[0] > 1 ||
+ anv_format->planes[p].denominator_scales[1] > 1) {
+ flags |= VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR;
+ break;
+ }
+ }
+
+ if (anv_format->n_planes > 1)
+ flags |= VK_FORMAT_FEATURE_DISJOINT_BIT_KHR;
+
+ const VkFormatFeatureFlags disallowed_ycbcr_image_features =
+ VK_FORMAT_FEATURE_BLIT_SRC_BIT |
+ VK_FORMAT_FEATURE_BLIT_DST_BIT |
+ VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
+ VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT |
+ VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
+
+ flags &= ~disallowed_ycbcr_image_features;
+ }
+
return flags;
}
static VkFormatFeatureFlags
-get_buffer_format_properties(const struct gen_device_info *devinfo,
- VkFormat vk_format,
- const struct anv_format *anv_format)
+get_buffer_format_features(const struct gen_device_info *devinfo,
+ VkFormat vk_format,
+ const struct anv_format *anv_format)
{
VkFormatFeatureFlags flags = 0;
return flags;
}
-static void
-anv_physical_device_get_format_properties(struct anv_physical_device *physical_device,
- VkFormat vk_format,
- VkFormatProperties *out_properties)
-{
- const struct gen_device_info *devinfo = &physical_device->info;
- const struct anv_format *format = anv_get_format(vk_format);
- VkFormatFeatureFlags linear = 0, tiled = 0;
-
- if (format == NULL) {
- /* Nothing to do here */
- } else {
- struct anv_format_plane linear_fmt, tiled_fmt;
- linear_fmt = anv_get_format_plane(&physical_device->info, vk_format,
- VK_IMAGE_ASPECT_COLOR_BIT,
- VK_IMAGE_TILING_LINEAR);
- tiled_fmt = anv_get_format_plane(&physical_device->info, vk_format,
- VK_IMAGE_ASPECT_COLOR_BIT,
- VK_IMAGE_TILING_OPTIMAL);
-
- linear = get_image_format_properties(&physical_device->info, vk_format,
- linear_fmt.isl_format, linear_fmt,
- VK_IMAGE_TILING_LINEAR);
- tiled = get_image_format_properties(&physical_device->info, vk_format,
- linear_fmt.isl_format, tiled_fmt,
- VK_IMAGE_TILING_OPTIMAL);
-
- /* XXX: We handle 3-channel formats by switching them out for RGBX or
- * RGBA formats behind-the-scenes. This works fine for textures
- * because the upload process will fill in the extra channel.
- * We could also support it for render targets, but it will take
- * substantially more work and we have enough RGBX formats to handle
- * what most clients will want.
- */
- if (linear_fmt.isl_format != ISL_FORMAT_UNSUPPORTED &&
- !util_is_power_of_two(isl_format_layouts[linear_fmt.isl_format].bpb) &&
- isl_format_rgb_to_rgbx(linear_fmt.isl_format) == ISL_FORMAT_UNSUPPORTED) {
- tiled &= ~VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT &
- ~VK_FORMAT_FEATURE_BLIT_DST_BIT;
- }
- }
-
- if (format && format->can_ycbcr) {
- VkFormatFeatureFlags ycbcr_features = 0;
-
- /* The sampler doesn't have support for mid point when it handles YUV on
- * its own.
- */
- if (isl_format_is_yuv(format->planes[0].isl_format)) {
- /* TODO: We've disabled linear implicit reconstruction with the
- * sampler. The failures show a slightly out of range values on the
- * bottom left of the sampled image.
- */
- ycbcr_features |= VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR;
- } else {
- ycbcr_features |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR |
- VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT_KHR |
- VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR;
- }
-
- /* We can support cosited chroma locations when handle planes with our
- * own shader snippets.
- */
- for (unsigned p = 0; p < format->n_planes; p++) {
- if (format->planes[p].denominator_scales[0] > 1 ||
- format->planes[p].denominator_scales[1] > 1) {
- ycbcr_features |= VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT_KHR;
- break;
- }
- }
-
- if (format->n_planes > 1)
- ycbcr_features |= VK_FORMAT_FEATURE_DISJOINT_BIT_KHR;
-
- linear |= ycbcr_features;
- tiled |= ycbcr_features;
-
- const VkFormatFeatureFlags disallowed_ycbcr_image_features =
- VK_FORMAT_FEATURE_BLIT_SRC_BIT |
- VK_FORMAT_FEATURE_BLIT_DST_BIT |
- VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
- VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT |
- VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
-
- linear &= ~disallowed_ycbcr_image_features;
- tiled &= ~disallowed_ycbcr_image_features;
- }
-
- out_properties->linearTilingFeatures = linear;
- out_properties->optimalTilingFeatures = tiled;
- out_properties->bufferFeatures =
- get_buffer_format_properties(devinfo, vk_format, format);
-}
-
-
void anv_GetPhysicalDeviceFormatProperties(
VkPhysicalDevice physicalDevice,
- VkFormat format,
+ VkFormat vk_format,
VkFormatProperties* pFormatProperties)
{
ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
-
- anv_physical_device_get_format_properties(
- physical_device,
- format,
- pFormatProperties);
+ const struct gen_device_info *devinfo = &physical_device->info;
+ const struct anv_format *anv_format = anv_get_format(vk_format);
+
+ *pFormatProperties = (VkFormatProperties) {
+ .linearTilingFeatures =
+ get_image_format_features(devinfo, vk_format, anv_format,
+ VK_IMAGE_TILING_LINEAR),
+ .optimalTilingFeatures =
+ get_image_format_features(devinfo, vk_format, anv_format,
+ VK_IMAGE_TILING_OPTIMAL),
+ .bufferFeatures =
+ get_buffer_format_features(devinfo, vk_format, anv_format),
+ };
}
void anv_GetPhysicalDeviceFormatProperties2KHR(
VkImageFormatProperties *pImageFormatProperties,
VkSamplerYcbcrConversionImageFormatPropertiesKHR *pYcbcrImageFormatProperties)
{
- VkFormatProperties format_props;
VkFormatFeatureFlags format_feature_flags;
VkExtent3D maxExtent;
uint32_t maxMipLevels;
uint32_t maxArraySize;
VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
+ const struct gen_device_info *devinfo = &physical_device->info;
const struct anv_format *format = anv_get_format(info->format);
if (format == NULL)
goto unsupported;
- anv_physical_device_get_format_properties(physical_device, info->format,
- &format_props);
-
- /* Extract the VkFormatFeatureFlags that are relevant for the queried
- * tiling.
- */
- if (info->tiling == VK_IMAGE_TILING_LINEAR) {
- format_feature_flags = format_props.linearTilingFeatures;
- } else if (info->tiling == VK_IMAGE_TILING_OPTIMAL) {
- format_feature_flags = format_props.optimalTilingFeatures;
- } else {
- unreachable("bad VkImageTiling");
- }
+ format_feature_flags = get_image_format_features(devinfo, info->format,
+ format, info->tiling);
switch (info->type) {
default: