#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_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
fmt(VK_FORMAT_UNDEFINED, ISL_FORMAT_RAW),
fmt(VK_FORMAT_R4G4_UNORM_PACK8, ISL_FORMAT_UNSUPPORTED),
fmt(VK_FORMAT_R4G4B4A4_UNORM_PACK16, ISL_FORMAT_A4B4G4R4_UNORM),
- fmt(VK_FORMAT_B4G4R4A4_UNORM_PACK16, ISL_FORMAT_UNSUPPORTED),
+ swiz_fmt(VK_FORMAT_B4G4R4A4_UNORM_PACK16, ISL_FORMAT_A4B4G4R4_UNORM, BGRA),
fmt(VK_FORMAT_R5G6B5_UNORM_PACK16, ISL_FORMAT_B5G6R5_UNORM),
- fmt(VK_FORMAT_B5G6R5_UNORM_PACK16, ISL_FORMAT_UNSUPPORTED),
+ 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_B5G5R5A1_UNORM),
*/
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) {
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];
VK_FORMAT_FEATURE_BLIT_SRC_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
}
} 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
ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl,
.dim = vk_to_isl_surf_dim[vk_info->imageType],
- .format = anv_get_isl_format(vk_info->format, aspect, vk_info->tiling),
+ .format = anv_get_isl_format(vk_info->format, aspect,
+ vk_info->tiling, NULL),
.width = vk_info->extent.width,
.height = vk_info->extent.height,
.depth = vk_info->extent.depth,
}
static VkComponentSwizzle
-remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component)
+remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component,
+ struct anv_format_swizzle format_swizzle)
{
if (swizzle == VK_COMPONENT_SWIZZLE_IDENTITY)
- return component;
- else
- return swizzle;
+ swizzle = component;
+
+ switch (swizzle) {
+ case VK_COMPONENT_SWIZZLE_ZERO:
+ return VK_COMPONENT_SWIZZLE_ZERO;
+ case VK_COMPONENT_SWIZZLE_ONE:
+ return VK_COMPONENT_SWIZZLE_ONE;
+ case VK_COMPONENT_SWIZZLE_R:
+ return VK_COMPONENT_SWIZZLE_R + format_swizzle.r;
+ case VK_COMPONENT_SWIZZLE_G:
+ return VK_COMPONENT_SWIZZLE_R + format_swizzle.g;
+ case VK_COMPONENT_SWIZZLE_B:
+ return VK_COMPONENT_SWIZZLE_R + format_swizzle.b;
+ case VK_COMPONENT_SWIZZLE_A:
+ return VK_COMPONENT_SWIZZLE_R + format_swizzle.a;
+ default:
+ unreachable("Invalid swizzle");
+ }
}
void
iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
iview->vk_format = pCreateInfo->format;
+
+ struct anv_format_swizzle swizzle;
iview->format = anv_get_isl_format(pCreateInfo->format, iview->aspect_mask,
- image->tiling);
+ image->tiling, &swizzle);
iview->swizzle.r = remap_swizzle(pCreateInfo->components.r,
- VK_COMPONENT_SWIZZLE_R);
+ VK_COMPONENT_SWIZZLE_R, swizzle);
iview->swizzle.g = remap_swizzle(pCreateInfo->components.g,
- VK_COMPONENT_SWIZZLE_G);
+ VK_COMPONENT_SWIZZLE_G, swizzle);
iview->swizzle.b = remap_swizzle(pCreateInfo->components.b,
- VK_COMPONENT_SWIZZLE_B);
+ VK_COMPONENT_SWIZZLE_B, swizzle);
iview->swizzle.a = remap_swizzle(pCreateInfo->components.a,
- VK_COMPONENT_SWIZZLE_A);
+ VK_COMPONENT_SWIZZLE_A, swizzle);
iview->base_layer = range->baseArrayLayer;
iview->base_mip = range->baseMipLevel;