#include "gen7_pack.h"
-#define fmt(__vk_fmt, __hw_fmt, ...) \
+#define RGBA ((struct anv_format_swizzle) { 0, 1, 2, 3 })
+#define BGRA ((struct anv_format_swizzle) { 2, 1, 0, 3 })
+
+#define swiz_fmt(__vk_fmt, __hw_fmt, __swizzle, ...) \
[__vk_fmt] = { \
.vk_format = __vk_fmt, \
.name = #__vk_fmt, \
- .surface_format = __hw_fmt, \
+ .isl_format = __hw_fmt, \
.isl_layout = &isl_format_layouts[__hw_fmt], \
+ .swizzle = __swizzle, \
__VA_ARGS__ \
}
+#define fmt(__vk_fmt, __hw_fmt, ...) \
+ swiz_fmt(__vk_fmt, __hw_fmt, RGBA, __VA_ARGS__)
+
+/* HINT: For array formats, the ISL name should match the VK name. For
+ * packed formats, they should have the channels in reverse order from each
+ * other. The reason for this is that, for packed formats, the ISL (and
+ * bspec) names are in LSB -> MSB order while VK formats are MSB -> LSB.
+ */
static const struct anv_format anv_formats[] = {
fmt(VK_FORMAT_UNDEFINED, ISL_FORMAT_RAW),
fmt(VK_FORMAT_R4G4_UNORM_PACK8, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_R4G4B4A4_UNORM_PACK16, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_B4G4R4A4_UNORM_PACK16, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_R5G6B5_UNORM_PACK16, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_B5G6R5_UNORM_PACK16, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_R5G5B5A1_UNORM_PACK16, ISL_FORMAT_UNSUPPORTED),
+ fmt(VK_FORMAT_R4G4B4A4_UNORM_PACK16, ISL_FORMAT_A4B4G4R4_UNORM),
+ swiz_fmt(VK_FORMAT_B4G4R4A4_UNORM_PACK16, ISL_FORMAT_A4B4G4R4_UNORM, BGRA),
+ fmt(VK_FORMAT_R5G6B5_UNORM_PACK16, ISL_FORMAT_B5G6R5_UNORM),
+ swiz_fmt(VK_FORMAT_B5G6R5_UNORM_PACK16, ISL_FORMAT_B5G6R5_UNORM, BGRA),
+ fmt(VK_FORMAT_R5G5B5A1_UNORM_PACK16, ISL_FORMAT_A1B5G5R5_UNORM),
fmt(VK_FORMAT_B5G5R5A1_UNORM_PACK16, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_A1R5G5B5_UNORM_PACK16, ISL_FORMAT_UNSUPPORTED),
+ fmt(VK_FORMAT_A1R5G5B5_UNORM_PACK16, ISL_FORMAT_B5G5R5A1_UNORM),
fmt(VK_FORMAT_R8_UNORM, ISL_FORMAT_R8_UNORM),
fmt(VK_FORMAT_R8_SNORM, ISL_FORMAT_R8_SNORM),
fmt(VK_FORMAT_R8_USCALED, ISL_FORMAT_R8_USCALED),
fmt(VK_FORMAT_B10G11R11_UFLOAT_PACK32, ISL_FORMAT_R11G11B10_FLOAT),
fmt(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, ISL_FORMAT_R9G9B9E5_SHAREDEXP),
- fmt(VK_FORMAT_D16_UNORM, ISL_FORMAT_R16_UNORM, .depth_format = D16_UNORM),
- fmt(VK_FORMAT_X8_D24_UNORM_PACK32, ISL_FORMAT_R24_UNORM_X8_TYPELESS, .depth_format = D24_UNORM_X8_UINT),
- fmt(VK_FORMAT_D32_SFLOAT, ISL_FORMAT_R32_FLOAT, .depth_format = D32_FLOAT),
- fmt(VK_FORMAT_S8_UINT, ISL_FORMAT_R8_UINT, .has_stencil = true),
- fmt(VK_FORMAT_D16_UNORM_S8_UINT, ISL_FORMAT_R16_UNORM, .depth_format = D16_UNORM, .has_stencil = true),
- fmt(VK_FORMAT_D24_UNORM_S8_UINT, ISL_FORMAT_R24_UNORM_X8_TYPELESS, .depth_format = D24_UNORM_X8_UINT, .has_stencil = true),
- fmt(VK_FORMAT_D32_SFLOAT_S8_UINT, ISL_FORMAT_R32_FLOAT, .depth_format = D32_FLOAT, .has_stencil = true),
-
- fmt(VK_FORMAT_BC1_RGB_UNORM_BLOCK, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_BC1_RGB_SRGB_BLOCK, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_BC1_RGBA_UNORM_BLOCK, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_BC1_RGBA_SRGB_BLOCK, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_BC2_UNORM_BLOCK, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_BC2_SRGB_BLOCK, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_BC3_UNORM_BLOCK, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_BC3_SRGB_BLOCK, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_BC4_UNORM_BLOCK, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_BC4_SNORM_BLOCK, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_BC5_UNORM_BLOCK, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_BC5_SNORM_BLOCK, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_BC6H_UFLOAT_BLOCK, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_BC6H_SFLOAT_BLOCK, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_BC7_UNORM_BLOCK, ISL_FORMAT_UNSUPPORTED),
- fmt(VK_FORMAT_BC7_SRGB_BLOCK, ISL_FORMAT_UNSUPPORTED),
+ fmt(VK_FORMAT_D16_UNORM, ISL_FORMAT_R16_UNORM, .has_depth = true),
+ fmt(VK_FORMAT_X8_D24_UNORM_PACK32, ISL_FORMAT_R24_UNORM_X8_TYPELESS, .has_depth = true),
+ fmt(VK_FORMAT_D32_SFLOAT, ISL_FORMAT_R32_FLOAT, .has_depth = true),
+ fmt(VK_FORMAT_S8_UINT, ISL_FORMAT_R8_UINT, .has_stencil = true),
+ fmt(VK_FORMAT_D16_UNORM_S8_UINT, ISL_FORMAT_R16_UNORM, .has_depth = true, .has_stencil = true),
+ fmt(VK_FORMAT_D24_UNORM_S8_UINT, ISL_FORMAT_R24_UNORM_X8_TYPELESS, .has_depth = true, .has_stencil = true),
+ fmt(VK_FORMAT_D32_SFLOAT_S8_UINT, ISL_FORMAT_R32_FLOAT, .has_depth = true, .has_stencil = true),
+
+ fmt(VK_FORMAT_BC1_RGB_UNORM_BLOCK, ISL_FORMAT_DXT1_RGB),
+ fmt(VK_FORMAT_BC1_RGB_SRGB_BLOCK, ISL_FORMAT_DXT1_RGB_SRGB),
+ fmt(VK_FORMAT_BC1_RGBA_UNORM_BLOCK, ISL_FORMAT_BC1_UNORM),
+ fmt(VK_FORMAT_BC1_RGBA_SRGB_BLOCK, ISL_FORMAT_BC1_UNORM_SRGB),
+ fmt(VK_FORMAT_BC2_UNORM_BLOCK, ISL_FORMAT_BC2_UNORM),
+ fmt(VK_FORMAT_BC2_SRGB_BLOCK, ISL_FORMAT_BC2_UNORM_SRGB),
+ fmt(VK_FORMAT_BC3_UNORM_BLOCK, ISL_FORMAT_BC3_UNORM),
+ fmt(VK_FORMAT_BC3_SRGB_BLOCK, ISL_FORMAT_BC3_UNORM_SRGB),
+ fmt(VK_FORMAT_BC4_UNORM_BLOCK, ISL_FORMAT_BC4_UNORM),
+ fmt(VK_FORMAT_BC4_SNORM_BLOCK, ISL_FORMAT_BC4_SNORM),
+ fmt(VK_FORMAT_BC5_UNORM_BLOCK, ISL_FORMAT_BC5_UNORM),
+ fmt(VK_FORMAT_BC5_SNORM_BLOCK, ISL_FORMAT_BC5_SNORM),
+ fmt(VK_FORMAT_BC6H_UFLOAT_BLOCK, ISL_FORMAT_BC6H_UF16),
+ fmt(VK_FORMAT_BC6H_SFLOAT_BLOCK, ISL_FORMAT_BC6H_SF16),
+ fmt(VK_FORMAT_BC7_UNORM_BLOCK, ISL_FORMAT_BC7_UNORM),
+ fmt(VK_FORMAT_BC7_SRGB_BLOCK, ISL_FORMAT_BC7_UNORM_SRGB),
fmt(VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, ISL_FORMAT_ETC2_RGB8),
fmt(VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, ISL_FORMAT_ETC2_SRGB8),
fmt(VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, ISL_FORMAT_ETC2_RGB8_PTA),
*/
enum isl_format
anv_get_isl_format(VkFormat format, VkImageAspectFlags aspect,
- VkImageTiling tiling)
+ VkImageTiling tiling, struct anv_format_swizzle *swizzle)
{
const struct anv_format *anv_fmt = &anv_formats[format];
+ if (swizzle)
+ *swizzle = anv_fmt->swizzle;
+
switch (aspect) {
case VK_IMAGE_ASPECT_COLOR_BIT:
- if (anv_fmt->surface_format == ISL_FORMAT_UNSUPPORTED) {
+ if (anv_fmt->isl_format == ISL_FORMAT_UNSUPPORTED) {
return ISL_FORMAT_UNSUPPORTED;
} else if (tiling == VK_IMAGE_TILING_OPTIMAL &&
!util_is_power_of_two(anv_fmt->isl_layout->bs)) {
* this by switching them over to RGBX or RGBA formats under the
* hood.
*/
- enum isl_format rgbx = isl_format_rgb_to_rgbx(anv_fmt->surface_format);
+ enum isl_format rgbx = isl_format_rgb_to_rgbx(anv_fmt->isl_format);
if (rgbx != ISL_FORMAT_UNSUPPORTED)
return rgbx;
else
- return isl_format_rgb_to_rgba(anv_fmt->surface_format);
+ return isl_format_rgb_to_rgba(anv_fmt->isl_format);
} else {
- return anv_fmt->surface_format;
+ return anv_fmt->isl_format;
}
case VK_IMAGE_ASPECT_DEPTH_BIT:
case (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT):
- assert(anv_fmt->depth_format != 0);
- return anv_fmt->surface_format;
+ assert(anv_fmt->has_depth);
+ return anv_fmt->isl_format;
case VK_IMAGE_ASPECT_STENCIL_BIT:
assert(anv_fmt->has_stencil);
static VkFormatFeatureFlags
get_image_format_properties(int gen, enum isl_format base,
- enum isl_format actual)
+ enum isl_format actual,
+ struct anv_format_swizzle swizzle)
{
const struct brw_surface_format_info *info = &surface_formats[actual];
if (info->sampling <= gen) {
flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
VK_FORMAT_FEATURE_BLIT_SRC_BIT;
+
+ if (info->filtering <= gen)
+ flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
}
- if (info->render_target <= gen) {
+ /* We can render to swizzled formats. However, if the alpha channel is
+ * moved, then blending won't work correctly. The PRM tells us
+ * straight-up not to render to such a surface.
+ */
+ if (info->render_target <= gen && swizzle.a == 3) {
flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_BLIT_DST_BIT;
}
- if (info->alpha_blend <= gen)
+ if (info->alpha_blend <= gen && swizzle.a == 3)
flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
/* Load/store is determined based on base format. This prevents RGB
tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
tiled |= VK_FORMAT_FEATURE_BLIT_SRC_BIT;
}
- if (anv_formats[format].depth_format) {
+ if (anv_formats[format].has_depth) {
tiled |= VK_FORMAT_FEATURE_BLIT_DST_BIT;
}
} else {
enum isl_format linear_fmt, tiled_fmt;
+ struct anv_format_swizzle linear_swizzle, tiled_swizzle;
linear_fmt = anv_get_isl_format(format, VK_IMAGE_ASPECT_COLOR_BIT,
- VK_IMAGE_TILING_LINEAR);
+ VK_IMAGE_TILING_LINEAR, &linear_swizzle);
tiled_fmt = anv_get_isl_format(format, VK_IMAGE_ASPECT_COLOR_BIT,
- VK_IMAGE_TILING_OPTIMAL);
+ VK_IMAGE_TILING_OPTIMAL, &tiled_swizzle);
- linear = get_image_format_properties(gen, linear_fmt, linear_fmt);
- tiled = get_image_format_properties(gen, linear_fmt, tiled_fmt);
+ linear = get_image_format_properties(gen, linear_fmt, linear_fmt,
+ linear_swizzle);
+ tiled = get_image_format_properties(gen, linear_fmt, tiled_fmt,
+ tiled_swizzle);
buffer = get_buffer_format_properties(gen, linear_fmt);
/* XXX: We handle 3-channel formats by switching them out for RGBX or
* what most clients will want.
*/
if (linear_fmt != ISL_FORMAT_UNSUPPORTED &&
- isl_format_is_rgb(linear_fmt) &&
+ !util_is_power_of_two(isl_format_layouts[linear_fmt].bs) &&
isl_format_rgb_to_rgbx(linear_fmt) == ISL_FORMAT_UNSUPPORTED) {
tiled &= ~VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT &
~VK_FORMAT_FEATURE_BLIT_DST_BIT;
VkImageType type,
VkImageTiling tiling,
VkImageUsageFlags usage,
- VkImageCreateFlags flags,
+ VkImageCreateFlags createFlags,
VkImageFormatProperties* pImageFormatProperties)
{
ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
type == VK_IMAGE_TYPE_2D &&
(format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
- !(flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
+ !(createFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
!(usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
sampleCounts = isl_device_get_sample_counts(&physical_device->isl_dev);
}
}
}
+#if 0
if (usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
if (anv_format_for_vk_format(format)->has_stencil) {
/* Not yet implemented because copying to a W-tiled surface is crazy
goto unsupported;
}
}
+#endif
if (usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {