anv/formats: Add an anv_get_format helper

This commit removes anv_format_for_vk_format and adds an anv_get_format
helper.  The anv_get_format helper returns the anv_format by-value.  Unlike
anv_format_for_vk_format the format returned by anv_get_format is 100%
accurate and includes any tweaks needed for tiled vs. linear.
anv_get_isl_format is now just a wrapper around anv_get_format that picks
off just the isl_format.
This commit is contained in:
Jason Ekstrand
2016-05-15 21:15:59 -07:00
parent 13f5cee663
commit 8ed429a4f0
5 changed files with 57 additions and 65 deletions

View File

@@ -234,31 +234,22 @@ static const struct anv_format anv_formats[] = {
#undef fmt
const struct anv_format *
anv_format_for_vk_format(VkFormat format)
{
return &anv_formats[format];
}
/**
* Exactly one bit must be set in \a aspect.
*/
enum isl_format
anv_get_isl_format(VkFormat vk_format, VkImageAspectFlags aspect,
VkImageTiling tiling, struct anv_format_swizzle *swizzle)
struct anv_format
anv_get_format(VkFormat vk_format, VkImageAspectFlags aspect,
VkImageTiling tiling)
{
const enum isl_format isl_format = anv_formats[vk_format].isl_format;
if (swizzle)
*swizzle = anv_formats[vk_format].swizzle;
struct anv_format format = anv_formats[vk_format];
const struct isl_format_layout *isl_layout =
isl_format_get_layout(isl_format);
isl_format_get_layout(format.isl_format);
switch (aspect) {
case VK_IMAGE_ASPECT_COLOR_BIT:
if (isl_format == ISL_FORMAT_UNSUPPORTED) {
return ISL_FORMAT_UNSUPPORTED;
if (format.isl_format == ISL_FORMAT_UNSUPPORTED) {
return format;
} else if (tiling == VK_IMAGE_TILING_OPTIMAL &&
!util_is_power_of_two(isl_layout->bs)) {
/* Tiled formats *must* be power-of-two because we need up upload
@@ -266,27 +257,29 @@ anv_get_isl_format(VkFormat vk_format, VkImageAspectFlags aspect,
* this by switching them over to RGBX or RGBA formats under the
* hood.
*/
enum isl_format rgbx = isl_format_rgb_to_rgbx(isl_format);
enum isl_format rgbx = isl_format_rgb_to_rgbx(format.isl_format);
if (rgbx != ISL_FORMAT_UNSUPPORTED)
return rgbx;
format.isl_format = rgbx;
else
return isl_format_rgb_to_rgba(isl_format);
format.isl_format = isl_format_rgb_to_rgba(format.isl_format);
return format;
} else {
return isl_format;
return format;
}
case VK_IMAGE_ASPECT_DEPTH_BIT:
case (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT):
assert(vk_format_aspects(vk_format) & VK_IMAGE_ASPECT_DEPTH_BIT);
return isl_format;
return format;
case VK_IMAGE_ASPECT_STENCIL_BIT:
assert(vk_format_aspects(vk_format) & VK_IMAGE_ASPECT_STENCIL_BIT);
return ISL_FORMAT_R8_UINT;
format.isl_format = ISL_FORMAT_R8_UINT;
return format;
default:
unreachable("bad VkImageAspect");
return ISL_FORMAT_UNSUPPORTED;
return format;
}
}
@@ -294,12 +287,12 @@ anv_get_isl_format(VkFormat vk_format, VkImageAspectFlags aspect,
static VkFormatFeatureFlags
get_image_format_properties(int gen, enum isl_format base,
enum isl_format actual,
struct anv_format_swizzle swizzle)
struct anv_format format)
{
const struct brw_surface_format_info *info = &surface_formats[actual];
const struct brw_surface_format_info *info =
&surface_formats[format.isl_format];
if (actual == ISL_FORMAT_UNSUPPORTED || !info->exists)
if (format.isl_format == ISL_FORMAT_UNSUPPORTED || !info->exists)
return 0;
VkFormatFeatureFlags flags = 0;
@@ -315,12 +308,12 @@ get_image_format_properties(int gen, enum isl_format base,
* 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) {
if (info->render_target <= gen && format.swizzle.a == 3) {
flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_BLIT_DST_BIT;
}
if (info->alpha_blend <= gen && swizzle.a == 3)
if (info->alpha_blend <= gen && format.swizzle.a == 3)
flags |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
/* Load/store is determined based on base format. This prevents RGB
@@ -378,18 +371,17 @@ anv_physical_device_get_format_properties(struct anv_physical_device *physical_d
tiled |= VK_FORMAT_FEATURE_BLIT_SRC_BIT |
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, &linear_swizzle);
tiled_fmt = anv_get_isl_format(format, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_TILING_OPTIMAL, &tiled_swizzle);
struct anv_format linear_fmt, tiled_fmt;
linear_fmt = anv_get_format(format, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_TILING_LINEAR);
tiled_fmt = anv_get_format(format, VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_TILING_OPTIMAL);
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);
linear = get_image_format_properties(gen, linear_fmt.isl_format,
linear_fmt);
tiled = get_image_format_properties(gen, linear_fmt.isl_format,
tiled_fmt);
buffer = get_buffer_format_properties(gen, linear_fmt.isl_format);
/* XXX: We handle 3-channel formats by switching them out for RGBX or
* RGBA formats behind-the-scenes. This works fine for textures
@@ -398,9 +390,9 @@ anv_physical_device_get_format_properties(struct anv_physical_device *physical_d
* substantially more work and we have enough RGBX formats to handle
* what most clients will want.
*/
if (linear_fmt != ISL_FORMAT_UNSUPPORTED &&
!util_is_power_of_two(isl_format_layouts[linear_fmt].bs) &&
isl_format_rgb_to_rgbx(linear_fmt) == ISL_FORMAT_UNSUPPORTED) {
if (linear_fmt.isl_format != ISL_FORMAT_UNSUPPORTED &&
!util_is_power_of_two(isl_format_layouts[linear_fmt.isl_format].bs) &&
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;
}