anv: Support swizzled formats.
Some formats require a swizzle in order to map them to actual hardware formats. This allows us to turn on two new Vulkan formats.
This commit is contained in:

committed by
Jason Ekstrand

parent
9bc72a9213
commit
c20f78dc5d
@@ -26,15 +26,22 @@
|
|||||||
|
|
||||||
#include "gen7_pack.h"
|
#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_fmt] = { \
|
||||||
.vk_format = __vk_fmt, \
|
.vk_format = __vk_fmt, \
|
||||||
.name = #__vk_fmt, \
|
.name = #__vk_fmt, \
|
||||||
.surface_format = __hw_fmt, \
|
.surface_format = __hw_fmt, \
|
||||||
.isl_layout = &isl_format_layouts[__hw_fmt], \
|
.isl_layout = &isl_format_layouts[__hw_fmt], \
|
||||||
|
.swizzle = __swizzle, \
|
||||||
__VA_ARGS__ \
|
__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
|
/* 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
|
* 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
|
* other. The reason for this is that, for packed formats, the ISL (and
|
||||||
@@ -44,9 +51,9 @@ static const struct anv_format anv_formats[] = {
|
|||||||
fmt(VK_FORMAT_UNDEFINED, ISL_FORMAT_RAW),
|
fmt(VK_FORMAT_UNDEFINED, ISL_FORMAT_RAW),
|
||||||
fmt(VK_FORMAT_R4G4_UNORM_PACK8, ISL_FORMAT_UNSUPPORTED),
|
fmt(VK_FORMAT_R4G4_UNORM_PACK8, ISL_FORMAT_UNSUPPORTED),
|
||||||
fmt(VK_FORMAT_R4G4B4A4_UNORM_PACK16, ISL_FORMAT_A4B4G4R4_UNORM),
|
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_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_R5G5B5A1_UNORM_PACK16, ISL_FORMAT_A1B5G5R5_UNORM),
|
||||||
fmt(VK_FORMAT_B5G5R5A1_UNORM_PACK16, ISL_FORMAT_UNSUPPORTED),
|
fmt(VK_FORMAT_B5G5R5A1_UNORM_PACK16, ISL_FORMAT_UNSUPPORTED),
|
||||||
fmt(VK_FORMAT_A1R5G5B5_UNORM_PACK16, ISL_FORMAT_B5G5R5A1_UNORM),
|
fmt(VK_FORMAT_A1R5G5B5_UNORM_PACK16, ISL_FORMAT_B5G5R5A1_UNORM),
|
||||||
@@ -243,10 +250,13 @@ anv_format_for_vk_format(VkFormat format)
|
|||||||
*/
|
*/
|
||||||
enum isl_format
|
enum isl_format
|
||||||
anv_get_isl_format(VkFormat format, VkImageAspectFlags aspect,
|
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];
|
const struct anv_format *anv_fmt = &anv_formats[format];
|
||||||
|
|
||||||
|
if (swizzle)
|
||||||
|
*swizzle = anv_fmt->swizzle;
|
||||||
|
|
||||||
switch (aspect) {
|
switch (aspect) {
|
||||||
case VK_IMAGE_ASPECT_COLOR_BIT:
|
case VK_IMAGE_ASPECT_COLOR_BIT:
|
||||||
if (anv_fmt->surface_format == ISL_FORMAT_UNSUPPORTED) {
|
if (anv_fmt->surface_format == ISL_FORMAT_UNSUPPORTED) {
|
||||||
@@ -296,7 +306,8 @@ void anv_validate_GetPhysicalDeviceFormatProperties(
|
|||||||
|
|
||||||
static VkFormatFeatureFlags
|
static VkFormatFeatureFlags
|
||||||
get_image_format_properties(int gen, enum isl_format base,
|
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];
|
const struct brw_surface_format_info *info = &surface_formats[actual];
|
||||||
|
|
||||||
@@ -309,12 +320,16 @@ get_image_format_properties(int gen, enum isl_format base,
|
|||||||
VK_FORMAT_FEATURE_BLIT_SRC_BIT;
|
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 |
|
flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
|
||||||
VK_FORMAT_FEATURE_BLIT_DST_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;
|
flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
|
||||||
|
|
||||||
/* Load/store is determined based on base format. This prevents RGB
|
/* Load/store is determined based on base format. This prevents RGB
|
||||||
@@ -374,13 +389,16 @@ anv_physical_device_get_format_properties(struct anv_physical_device *physical_d
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
enum isl_format linear_fmt, tiled_fmt;
|
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,
|
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,
|
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);
|
linear = get_image_format_properties(gen, linear_fmt, linear_fmt,
|
||||||
tiled = get_image_format_properties(gen, linear_fmt, tiled_fmt);
|
linear_swizzle);
|
||||||
|
tiled = get_image_format_properties(gen, linear_fmt, tiled_fmt,
|
||||||
|
tiled_swizzle);
|
||||||
buffer = get_buffer_format_properties(gen, linear_fmt);
|
buffer = get_buffer_format_properties(gen, linear_fmt);
|
||||||
|
|
||||||
/* XXX: We handle 3-channel formats by switching them out for RGBX or
|
/* XXX: We handle 3-channel formats by switching them out for RGBX or
|
||||||
|
@@ -128,7 +128,8 @@ make_surface(const struct anv_device *dev,
|
|||||||
|
|
||||||
ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl,
|
ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl,
|
||||||
.dim = vk_to_isl_surf_dim[vk_info->imageType],
|
.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,
|
.width = vk_info->extent.width,
|
||||||
.height = vk_info->extent.height,
|
.height = vk_info->extent.height,
|
||||||
.depth = vk_info->extent.depth,
|
.depth = vk_info->extent.depth,
|
||||||
@@ -454,12 +455,28 @@ has_matching_storage_typed_format(const struct anv_device *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static VkComponentSwizzle
|
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)
|
if (swizzle == VK_COMPONENT_SWIZZLE_IDENTITY)
|
||||||
return component;
|
swizzle = component;
|
||||||
else
|
|
||||||
return swizzle;
|
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
|
void
|
||||||
@@ -500,16 +517,18 @@ anv_image_view_init(struct anv_image_view *iview,
|
|||||||
|
|
||||||
iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
|
iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
|
||||||
iview->vk_format = pCreateInfo->format;
|
iview->vk_format = pCreateInfo->format;
|
||||||
|
|
||||||
|
struct anv_format_swizzle swizzle;
|
||||||
iview->format = anv_get_isl_format(pCreateInfo->format, iview->aspect_mask,
|
iview->format = anv_get_isl_format(pCreateInfo->format, iview->aspect_mask,
|
||||||
image->tiling);
|
image->tiling, &swizzle);
|
||||||
iview->swizzle.r = remap_swizzle(pCreateInfo->components.r,
|
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,
|
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,
|
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,
|
iview->swizzle.a = remap_swizzle(pCreateInfo->components.a,
|
||||||
VK_COMPONENT_SWIZZLE_A);
|
VK_COMPONENT_SWIZZLE_A, swizzle);
|
||||||
|
|
||||||
iview->base_layer = range->baseArrayLayer;
|
iview->base_layer = range->baseArrayLayer;
|
||||||
iview->base_mip = range->baseMipLevel;
|
iview->base_mip = range->baseMipLevel;
|
||||||
|
@@ -972,7 +972,8 @@ choose_buffer_format(struct anv_image *image, VkImageAspectFlagBits aspect)
|
|||||||
* work if the buffer is the destination.
|
* work if the buffer is the destination.
|
||||||
*/
|
*/
|
||||||
enum isl_format linear_format = anv_get_isl_format(image->vk_format, aspect,
|
enum isl_format linear_format = anv_get_isl_format(image->vk_format, aspect,
|
||||||
VK_IMAGE_TILING_LINEAR);
|
VK_IMAGE_TILING_LINEAR,
|
||||||
|
NULL);
|
||||||
|
|
||||||
return vk_format_for_size(isl_format_layouts[linear_format].bs);
|
return vk_format_for_size(isl_format_layouts[linear_format].bs);
|
||||||
}
|
}
|
||||||
|
@@ -1472,12 +1472,20 @@ gen9_compute_pipeline_create(VkDevice _device,
|
|||||||
const VkAllocationCallbacks *alloc,
|
const VkAllocationCallbacks *alloc,
|
||||||
VkPipeline *pPipeline);
|
VkPipeline *pPipeline);
|
||||||
|
|
||||||
|
struct anv_format_swizzle {
|
||||||
|
unsigned r:2;
|
||||||
|
unsigned g:2;
|
||||||
|
unsigned b:2;
|
||||||
|
unsigned a:2;
|
||||||
|
};
|
||||||
|
|
||||||
struct anv_format {
|
struct anv_format {
|
||||||
const VkFormat vk_format;
|
const VkFormat vk_format;
|
||||||
const char *name;
|
const char *name;
|
||||||
enum isl_format surface_format; /**< RENDER_SURFACE_STATE.SurfaceFormat */
|
enum isl_format surface_format; /**< RENDER_SURFACE_STATE.SurfaceFormat */
|
||||||
const struct isl_format_layout *isl_layout;
|
const struct isl_format_layout *isl_layout;
|
||||||
uint16_t depth_format; /**< 3DSTATE_DEPTH_BUFFER.SurfaceFormat */
|
uint16_t depth_format; /**< 3DSTATE_DEPTH_BUFFER.SurfaceFormat */
|
||||||
|
struct anv_format_swizzle swizzle;
|
||||||
bool has_stencil;
|
bool has_stencil;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1486,7 +1494,7 @@ anv_format_for_vk_format(VkFormat format);
|
|||||||
|
|
||||||
enum isl_format
|
enum isl_format
|
||||||
anv_get_isl_format(VkFormat format, VkImageAspectFlags aspect,
|
anv_get_isl_format(VkFormat format, VkImageAspectFlags aspect,
|
||||||
VkImageTiling tiling);
|
VkImageTiling tiling, struct anv_format_swizzle *swizzle);
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
anv_format_is_color(const struct anv_format *format)
|
anv_format_is_color(const struct anv_format *format)
|
||||||
|
@@ -99,7 +99,8 @@ emit_vertex_input(struct anv_pipeline *pipeline,
|
|||||||
&info->pVertexAttributeDescriptions[i];
|
&info->pVertexAttributeDescriptions[i];
|
||||||
enum isl_format format = anv_get_isl_format(desc->format,
|
enum isl_format format = anv_get_isl_format(desc->format,
|
||||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
VK_IMAGE_TILING_LINEAR);
|
VK_IMAGE_TILING_LINEAR,
|
||||||
|
NULL);
|
||||||
|
|
||||||
assert(desc->binding < 32);
|
assert(desc->binding < 32);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user