Compare commits

...

12 Commits

Author SHA1 Message Date
Chad Versace
3678509c33 FINISHME: anv: Fix VkPhysicalDeviceExternalImageFormatInfo for VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT 2019-07-26 13:24:41 -07:00
Chad Versace
90a334630e RFC: anv: Advertise VK_EXT_image_drm_format_modifier 2019-07-26 12:53:26 -07:00
Chad Versace
2f79a872ba FINISHME: anv: vkGetImageSubresourceLayout for VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT 2019-07-26 12:50:49 -07:00
Chad Versace
8f0b7a5ac0 FINISHME: anv: Support VkImageDrmFormatModifierExplicitCreateInfoEXT 2019-07-26 12:50:49 -07:00
Chad Versace
267478be79 RFC: anv: Support VkImageDrmFormatModifierListCreateInfoEXT 2019-07-26 12:50:49 -07:00
Chad Versace
fb323b1832 RFC: anv: Implement VkPhysicalDeviceImageDrmFormatModifierInfoEXT 2019-07-26 12:50:48 -07:00
Chad Versace
d83cf1dbbc anv: Rename param anv_get_image_format_properties()::info
Rename it to 'base_info', to distinguish it from 'drm_info' introduced
in upcoming commit.
2019-07-26 12:50:48 -07:00
Chad Versace
f9d9a8908c RFC: anv: Implement VkDrmFormatModifierPropertiesListEXT 2019-07-26 12:50:43 -07:00
Chad Versace
bfe70c24e6 anv: Reject linear depth/stencil in anv_get_format_plane()
anv_get_image_format_features() already reports that we do not support
linear images with depth/stencil formats. For consistency, teach
anv_get_format_plane() to do the same.
2019-07-26 12:49:46 -07:00
Chad Versace
291d4ba283 anv: Refactor struct anv_image_create_info
Replace field 'isl_tiling_flags' with 'drm_format_mod'. This cleanup
makes the override features of anv_image_create_info behave more
similarly to VkImageDrmFormatModifierExplicitCreateInfoEXT.

The field 'isl_tiling_flags' offered more flexibility than needed. The
driver set at most one flag, and when set the driver translated the sole
flag into a DRM format modifier.
2019-07-26 12:49:46 -07:00
Chad Versace
38690c43b8 anv: Define struct anv_tiling
Refactor only. No intended behavioral change.

Much of the existing code assumes, with good justification, that tiling
is either VK_IMAGE_TILING_LINEAR or VK_IMAGE_TILING_OPTIMAL. But
VK_EXT_image_drm_format_modifier will void that assumption.

Some examples where currently valid assumptions become invalid:

    - Code written as
          if (tiling != VK_IMAGE_TILING_OPTIMAL)
      but whose true intent is
          if (tiling == VK_IMAGE_TILING_LINEAR)
      will break when tiling is VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT.

    - Some code written as
          if (tilng == VK_IMAGE_TILING_LINEAR)
      will need updating to
          if (tiling == VK_IMAGE_TILING_LINEAR ||
              (tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
               drm_format_mod == DRM_FORMAT_MOD_LINEAR))

    - Many query functions with a VkImageTiling parameter will require
      an additional parameter for the DRM format modifier.

The invalidity of many of the above cases become clearer if we generally abandon
using VkImageTiling to indicate tiling, and instead use a new type that
includes an optional DRM format modifier:

    struct anv_tiling {
        VkImageTiling vk;
        uint64_t drm_format_mod;
    };

This patch does not attempt to fix code with soon-to-be invalid
assumptions. Instead, it restricts itself to the following changes:

- Replace type of:
    - anv_get_format_features()::tiling
    - anv_get_format_plane()::tiling
    - anv_get_isl_format()::tiling
    - anv_image::tiling
- Fold anv_image::drm_format_mod into anv_image::tiling.
- Replace variables 'vk_tiling' with 'tiling.vk'.
2019-07-26 12:49:46 -07:00
Chad Versace
235b3ba48e anv: Include drm_fourcc.h in anv_private.h
To allow use of DRM_FORMAT_MOD_INVALID in future inline functions for
struct anv_tiling.
2019-07-26 09:40:19 -07:00
11 changed files with 334 additions and 114 deletions

View File

@@ -134,10 +134,10 @@ get_ahw_buffer_format_properties(
/* Default to OPTIMAL tiling but set to linear in case
* of AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER usage.
*/
VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL;
struct anv_tiling tiling = anv_tiling_optimal();
if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER)
tiling = VK_IMAGE_TILING_LINEAR;
tiling = anv_tiling_linear();
p->formatFeatures =
anv_get_image_format_features(&device->info, p->format, anv_format,
@@ -472,13 +472,13 @@ anv_image_from_gralloc(VkDevice device_h,
int i915_tiling = anv_gem_get_tiling(device, bo->gem_handle);
switch (i915_tiling) {
case I915_TILING_NONE:
anv_info.isl_tiling_flags = ISL_TILING_LINEAR_BIT;
anv_info.drm_format_mod = DRM_FORMAT_MOD_LINEAR;
break;
case I915_TILING_X:
anv_info.isl_tiling_flags = ISL_TILING_X_BIT;
anv_info.drm_format_mod = I915_FORMAT_MOD_X_TILED;
break;
case I915_TILING_Y:
anv_info.isl_tiling_flags = ISL_TILING_Y0_BIT;
anv_info.drm_format_mod = I915_FORMAT_MOD_Y_TILED;
break;
case -1:
result = vk_errorf(device->instance, device,

View File

@@ -449,7 +449,7 @@ copy_buffer_to_image(struct anv_cmd_buffer *cmd_buffer,
const enum isl_format buffer_format =
anv_get_isl_format(&cmd_buffer->device->info, anv_image->vk_format,
aspect, VK_IMAGE_TILING_LINEAR);
aspect, anv_tiling_linear());
const VkExtent3D bufferImageExtent = {
.width = pRegions[r].bufferRowLength ?
@@ -1174,7 +1174,7 @@ clear_depth_stencil_attachment(struct anv_cmd_buffer *cmd_buffer,
depth_format = anv_get_isl_format(&cmd_buffer->device->info,
pass_att->format,
VK_IMAGE_ASPECT_DEPTH_BIT,
VK_IMAGE_TILING_OPTIMAL);
anv_tiling_optimal());
}
uint32_t binding_table;

View File

@@ -29,7 +29,6 @@
#include <unistd.h>
#include <fcntl.h>
#include <xf86drm.h>
#include "drm-uapi/drm_fourcc.h"
#include "anv_private.h"
#include "util/strtod.h"

View File

@@ -135,6 +135,7 @@ EXTENSIONS = [
Extension('VK_EXT_global_priority', 1,
'device->has_context_priority'),
Extension('VK_EXT_host_query_reset', 1, True),
Extension('VK_EXT_image_drm_format_modifier', 1, True),
Extension('VK_EXT_inline_uniform_block', 1, True),
Extension('VK_EXT_memory_budget', 1, 'device->has_mem_available'),
Extension('VK_EXT_pci_bus_info', 2, True),

View File

@@ -22,7 +22,6 @@
*/
#include "anv_private.h"
#include "drm-uapi/drm_fourcc.h"
#include "vk_enum_to_str.h"
#include "vk_format_info.h"
#include "vk_util.h"
@@ -436,13 +435,29 @@ anv_get_format(VkFormat vk_format)
return format;
}
static bool
anv_format_has_npot_plane(const struct anv_format *anv_format) {
for (uint32_t i = 0; i < anv_format->n_planes; ++i) {
const struct isl_format_layout *isl_layout =
isl_format_get_layout(anv_format->planes[i].isl_format);
if (!util_is_power_of_two_or_zero(isl_layout->bpb))
return true;
}
return false;
}
/**
* Exactly one bit must be set in \a aspect.
*/
struct anv_format_plane
anv_get_format_plane(const struct gen_device_info *devinfo, VkFormat vk_format,
VkImageAspectFlagBits aspect, VkImageTiling tiling)
VkImageAspectFlagBits aspect, struct anv_tiling tiling)
{
assert((tiling.vk != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) ==
(tiling.drm_format_mod == DRM_FORMAT_MOD_INVALID));
const struct anv_format *format = anv_get_format(vk_format);
const struct anv_format_plane unsupported = {
.isl_format = ISL_FORMAT_UNSUPPORTED,
@@ -459,6 +474,15 @@ anv_get_format_plane(const struct gen_device_info *devinfo, VkFormat vk_format,
if (aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
assert(vk_format_aspects(vk_format) &
(VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
if (tiling.vk != VK_IMAGE_TILING_OPTIMAL) {
/* We could support depth and stencil images with explicit
* user-selected tiling (linear or modifier) if we wanted, but there
* is no justification for the maintenance burden.
*/
return unsupported;
}
return plane_format;
}
@@ -467,13 +491,17 @@ anv_get_format_plane(const struct gen_device_info *devinfo, VkFormat vk_format,
const struct isl_format_layout *isl_layout =
isl_format_get_layout(plane_format.isl_format);
if (tiling == VK_IMAGE_TILING_OPTIMAL &&
bool rewrite_layout = false;
if (!anv_tiling_is_linear(tiling) &&
!util_is_power_of_two_or_zero(isl_layout->bpb)) {
/* Tiled formats *must* be power-of-two because we need up upload
* them with the render pipeline. For 3-channel formats, we fix
* this by switching them over to RGBX or RGBA formats under the
* hood.
*/
rewrite_layout = true;
enum isl_format rgbx = isl_format_rgb_to_rgbx(plane_format.isl_format);
if (rgbx != ISL_FORMAT_UNSUPPORTED &&
isl_format_supports_rendering(devinfo, rgbx)) {
@@ -489,10 +517,19 @@ anv_get_format_plane(const struct gen_device_info *devinfo, VkFormat vk_format,
* back to a format with a more complex swizzle.
*/
if (vk_format == VK_FORMAT_B4G4R4A4_UNORM_PACK16 && devinfo->gen < 8) {
rewrite_layout = true;
plane_format.isl_format = ISL_FORMAT_B4G4R4A4_UNORM;
plane_format.swizzle = ISL_SWIZZLE(GREEN, RED, ALPHA, BLUE);
}
/* For VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, the image's physical layout
* must not differ from its nominal layout in the Vulkan API.
*/
if (tiling.vk == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
rewrite_layout) {
return unsupported;
}
return plane_format;
}
@@ -502,18 +539,26 @@ VkFormatFeatureFlags
anv_get_image_format_features(const struct gen_device_info *devinfo,
VkFormat vk_format,
const struct anv_format *anv_format,
VkImageTiling vk_tiling)
struct anv_tiling tiling)
{
VkFormatFeatureFlags flags = 0;
if (anv_format == NULL)
return 0;
assert((tiling.vk != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) ==
(tiling.drm_format_mod == DRM_FORMAT_MOD_INVALID));
const VkImageAspectFlags aspects = vk_format_aspects(vk_format);
if (aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) {
if (vk_tiling == VK_IMAGE_TILING_LINEAR)
if (tiling.vk != VK_IMAGE_TILING_OPTIMAL) {
/* We could support depth and stencil images with explicit
* user-selected tiling (linear or modifier) if we wanted, but there
* is no justification for the maintenance burden.
*/
return 0;
}
flags |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
@@ -530,32 +575,35 @@ anv_get_image_format_features(const struct gen_device_info *devinfo,
const struct anv_format_plane plane_format =
anv_get_format_plane(devinfo, vk_format, VK_IMAGE_ASPECT_COLOR_BIT,
vk_tiling);
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) {
if (tiling.vk == VK_IMAGE_TILING_OPTIMAL) {
base_plane_format = anv_get_format_plane(devinfo, vk_format,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_TILING_LINEAR);
anv_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)
return 0;
if (isl_format_get_layout(plane_format.isl_format)->txc == ISL_TXC_ASTC) {
/* ASTC requires nasty workarounds on BSW so we just disable it for now.
*
* TODO: Figure out the ASTC workarounds and re-enable on BSW.
*/
if (devinfo->gen < 9)
return 0;
/* ASTC requires nasty workarounds on BSW so we just disable it for now.
*
* TODO: Figure out the ASTC workarounds and re-enable on BSW.
*/
if (devinfo->gen < 9 &&
isl_format_get_layout(plane_format.isl_format)->txc == ISL_TXC_ASTC)
return 0;
/* ASTC must be Y-tiled without CCS. */
if (!(tiling.vk == VK_IMAGE_TILING_OPTIMAL ||
(tiling.vk == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
tiling.drm_format_mod == I915_FORMAT_MOD_Y_TILED))) {
return 0;
}
}
if (isl_format_supports_sampling(devinfo, plane_format.isl_format)) {
flags |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
@@ -603,7 +651,7 @@ anv_get_image_format_features(const struct gen_device_info *devinfo,
* substantially more work and we have enough RGBX formats to handle
* what most clients will want.
*/
if (vk_tiling == VK_IMAGE_TILING_OPTIMAL &&
if (!anv_tiling_is_linear(tiling) &&
base_isl_format != ISL_FORMAT_UNSUPPORTED &&
!util_is_power_of_two_or_zero(isl_format_layouts[base_isl_format].bpb) &&
isl_format_rgb_to_rgbx(base_isl_format) == ISL_FORMAT_UNSUPPORTED) {
@@ -651,6 +699,16 @@ anv_get_image_format_features(const struct gen_device_info *devinfo,
flags &= ~disallowed_ycbcr_image_features;
}
if (tiling.vk == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
isl_drm_modifier_has_aux(tiling.drm_format_mod)) {
/* Defensively reject DISJOINT because the placement of the aux surface
* might be constrained by hardware. For example, on gen9 the display
* engine requires the CCS, if it exists, to reside at a higher physical
* address than the primary surface.
*/
flags &= ~VK_FORMAT_FEATURE_DISJOINT_BIT;
}
return flags;
}
@@ -695,46 +753,109 @@ get_buffer_format_features(const struct gen_device_info *devinfo,
}
static void
get_wsi_format_modifier_properties_list(const struct anv_physical_device *physical_device,
get_drm_format_modifier_properties_list(const struct anv_physical_device *physical_device,
VkFormat vk_format,
struct wsi_format_modifier_properties_list *list)
VkDrmFormatModifierPropertiesListEXT *list)
{
const struct gen_device_info *devinfo = &physical_device->info;
const struct anv_format *anv_format = anv_get_format(vk_format);
bool has_npot_plane = anv_format_has_npot_plane(anv_format);
VK_OUTARRAY_MAKE(out, list->modifier_properties, &list->modifier_count);
VK_OUTARRAY_MAKE(out, list->pDrmFormatModifierProperties,
&list->drmFormatModifierCount);
/* This is a simplified list where all the modifiers are available */
assert(vk_format == VK_FORMAT_B8G8R8_SRGB ||
vk_format == VK_FORMAT_B8G8R8_UNORM ||
vk_format == VK_FORMAT_B8G8R8A8_SRGB ||
vk_format == VK_FORMAT_B8G8R8A8_UNORM);
uint64_t modifiers[] = {
const uint64_t mods[] = {
DRM_FORMAT_MOD_LINEAR,
I915_FORMAT_MOD_X_TILED,
I915_FORMAT_MOD_Y_TILED,
I915_FORMAT_MOD_Y_TILED_CCS,
};
for (uint32_t i = 0; i < ARRAY_SIZE(modifiers); i++) {
for (uint32_t i = 0; i < ARRAY_SIZE(mods); i++) {
uint64_t mod = mods[i];
const struct isl_drm_modifier_info *mod_info =
isl_drm_modifier_get_info(modifiers[i]);
isl_drm_modifier_get_info(mod);
/* Tiled formats must be power-of-two because we implement transfers
* with the render pipeline.
*
* Maybe we could support tiled non-power-of-two formats if we limited
* drmFormatModifierTilingFeatures to VK_FORMAT_FEATURE_SAMPLED_*, but
* it's not worth the maintenance and testing burden.
*/
if (has_npot_plane && mod != DRM_FORMAT_MOD_LINEAR )
continue;
if (mod_info->aux_usage == ISL_AUX_USAGE_CCS_E &&
!isl_format_supports_ccs_e(&physical_device->info,
anv_format->planes[0].isl_format))
continue;
VkFormatFeatureFlags format_features =
anv_get_image_format_features(devinfo, vk_format, anv_format,
anv_tiling_drm(mod));
if (!format_features)
continue;
vk_outarray_append(&out, mod_props) {
mod_props->modifier = modifiers[i];
if (isl_drm_modifier_has_aux(modifiers[i]))
mod_props->modifier_plane_count = 2;
else
mod_props->modifier_plane_count = anv_format->n_planes;
mod_props->drmFormatModifier = mod;
mod_props->drmFormatModifierPlaneCount = anv_format->n_planes;
mod_props->drmFormatModifierTilingFeatures = format_features;
if (mod_info->aux_usage != ISL_AUX_USAGE_NONE) {
mod_props->drmFormatModifierPlaneCount += 1;
}
}
}
}
static void
get_wsi_format_modifier_properties_list(const struct anv_physical_device *physical_device,
VkFormat vk_format,
struct wsi_format_modifier_properties_list *wsi_list)
{
/* This is a simplified list where all the modifiers are available */
assert(vk_format == VK_FORMAT_B8G8R8_SRGB ||
vk_format == VK_FORMAT_B8G8R8_UNORM ||
vk_format == VK_FORMAT_B8G8R8A8_SRGB ||
vk_format == VK_FORMAT_B8G8R8A8_UNORM);
/* Implement by proxying to VK_EXT_image_drm_format_modifier. */
VkDrmFormatModifierPropertiesListEXT drm_list = {
.sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
.drmFormatModifierCount = wsi_list->modifier_count,
.pDrmFormatModifierProperties = NULL,
};
if (wsi_list->modifier_properties != NULL &&
wsi_list->modifier_count > 0) {
/* Allocate temporary VkDrmFormatModifierPropertiesEXT array. */
size_t size = sizeof(drm_list.pDrmFormatModifierProperties[0]);
if (__builtin_mul_overflow(size, wsi_list->modifier_count, &size))
abort();
drm_list.pDrmFormatModifierProperties = alloca(size);
}
get_drm_format_modifier_properties_list(physical_device, vk_format,
&drm_list);
/* Copy results from drm_list to wsi_list. */
if (wsi_list->modifier_properties != NULL) {
assert(drm_list.drmFormatModifierCount <= wsi_list->modifier_count);
for (uint32_t i = 0; i < drm_list.drmFormatModifierCount; ++i) {
struct wsi_format_modifier_properties *wsi_props = &wsi_list->modifier_properties[i];
VkDrmFormatModifierPropertiesEXT *drm_props = &drm_list.pDrmFormatModifierProperties[i];
wsi_props->modifier = drm_props->drmFormatModifier;
wsi_props->modifier_plane_count = drm_props->drmFormatModifierPlaneCount;
}
}
wsi_list->modifier_count = drm_list.drmFormatModifierCount;
}
void anv_GetPhysicalDeviceFormatProperties(
VkPhysicalDevice physicalDevice,
VkFormat vk_format,
@@ -747,10 +868,10 @@ void anv_GetPhysicalDeviceFormatProperties(
*pFormatProperties = (VkFormatProperties) {
.linearTilingFeatures =
anv_get_image_format_features(devinfo, vk_format, anv_format,
VK_IMAGE_TILING_LINEAR),
anv_tiling_linear()),
.optimalTilingFeatures =
anv_get_image_format_features(devinfo, vk_format, anv_format,
VK_IMAGE_TILING_OPTIMAL),
anv_tiling_optimal()),
.bufferFeatures =
get_buffer_format_features(devinfo, vk_format, anv_format),
};
@@ -772,6 +893,10 @@ void anv_GetPhysicalDeviceFormatProperties2(
get_wsi_format_modifier_properties_list(physical_device, format,
(void *)ext);
break;
case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT:
get_drm_format_modifier_properties_list(physical_device, format,
(void *)ext);
break;
default:
anv_debug_ignored_stype(ext->sType);
break;
@@ -782,7 +907,8 @@ void anv_GetPhysicalDeviceFormatProperties2(
static VkResult
anv_get_image_format_properties(
struct anv_physical_device *physical_device,
const VkPhysicalDeviceImageFormatInfo2 *info,
const VkPhysicalDeviceImageFormatInfo2 *base_info,
const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *drm_info,
VkImageFormatProperties *pImageFormatProperties,
VkSamplerYcbcrConversionImageFormatProperties *pYcbcrImageFormatProperties)
{
@@ -792,19 +918,32 @@ anv_get_image_format_properties(
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);
const struct anv_format *format = anv_get_format(base_info->format);
assert((base_info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) ==
(drm_info != NULL));
assert(!drm_info || drm_info->drmFormatModifier != DRM_FORMAT_MOD_INVALID);
if (format == NULL)
goto unsupported;
assert(format->vk_format == info->format);
format_feature_flags = anv_get_image_format_features(devinfo, info->format,
format, info->tiling);
assert(format->vk_format == base_info->format);
switch (info->type) {
struct anv_tiling tiling = {
.vk = base_info->tiling,
.drm_format_mod = drm_info ?
drm_info->drmFormatModifier : DRM_FORMAT_MOD_INVALID,
};
format_feature_flags = anv_get_image_format_features(devinfo, base_info->format,
format, tiling);
switch (base_info->type) {
default:
unreachable("bad VkImageType");
case VK_IMAGE_TYPE_1D:
if (base_info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
goto unsupported;
maxExtent.width = 16384;
maxExtent.height = 1;
maxExtent.depth = 1;
@@ -819,10 +958,18 @@ anv_get_image_format_properties(
maxExtent.width = 16384;
maxExtent.height = 16384;
maxExtent.depth = 1;
maxMipLevels = 15; /* log2(maxWidth) + 1 */
maxArraySize = 2048;
if (base_info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
maxMipLevels = 1;
maxArraySize = 1;
} else {
maxMipLevels = 15; /* log2(maxWidth) + 1 */
maxArraySize = 2048;
}
break;
case VK_IMAGE_TYPE_3D:
if (base_info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
goto unsupported;
maxExtent.width = 2048;
maxExtent.height = 2048;
maxExtent.depth = 2048;
@@ -837,21 +984,21 @@ anv_get_image_format_properties(
* if the Surface Type is SURFTYPE_1D.
* * This field cannot be ASTC format if the Surface Type is SURFTYPE_1D.
*/
if (info->type == VK_IMAGE_TYPE_1D &&
if (base_info->type == VK_IMAGE_TYPE_1D &&
isl_format_is_compressed(format->planes[0].isl_format)) {
goto unsupported;
}
if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&
info->type == VK_IMAGE_TYPE_2D &&
if (base_info->tiling == VK_IMAGE_TILING_OPTIMAL &&
base_info->type == VK_IMAGE_TYPE_2D &&
(format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
!(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
!(info->usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
!(base_info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
!(base_info->usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
sampleCounts = isl_device_get_sample_counts(&physical_device->isl_dev);
}
if (info->usage & (VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
if (base_info->usage & (VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
VK_IMAGE_USAGE_TRANSFER_DST_BIT)) {
/* Accept transfers on anything we can sample from or renderer to. */
if (!(format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
@@ -861,35 +1008,35 @@ anv_get_image_format_properties(
}
}
if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
if (base_info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
goto unsupported;
}
}
if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
if (base_info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
goto unsupported;
}
}
if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
if (base_info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
goto unsupported;
}
}
if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
if (base_info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
if (!(format_feature_flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
goto unsupported;
}
}
if (info->usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) {
if (base_info->usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) {
/* Nothing to check. */
}
if (info->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
if (base_info->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
/* Ignore this flag because it was removed from the
* provisional_I_20150910 header.
*/
@@ -960,7 +1107,7 @@ VkResult anv_GetPhysicalDeviceImageFormatProperties(
.flags = createFlags,
};
return anv_get_image_format_properties(physical_device, &info,
return anv_get_image_format_properties(physical_device, &info, NULL,
pImageFormatProperties, NULL);
}
@@ -1011,6 +1158,7 @@ VkResult anv_GetPhysicalDeviceImageFormatProperties2(
{
ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *drm_info = NULL;
VkExternalImageFormatProperties *external_props = NULL;
VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
struct VkAndroidHardwareBufferUsageANDROID *android_usage = NULL;
@@ -1022,6 +1170,9 @@ VkResult anv_GetPhysicalDeviceImageFormatProperties2(
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
external_info = (const void *) s;
break;
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT:
drm_info = (const void *) s;
break;
case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT:
/* Ignore but don't warn */
break;
@@ -1049,7 +1200,7 @@ VkResult anv_GetPhysicalDeviceImageFormatProperties2(
}
}
result = anv_get_image_format_properties(physical_device, base_info,
result = anv_get_image_format_properties(physical_device, base_info, drm_info,
&base_props->imageFormatProperties, ycbcr_props);
if (result != VK_SUCCESS)
goto fail;
@@ -1071,6 +1222,9 @@ VkResult anv_GetPhysicalDeviceImageFormatProperties2(
* If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2 will
* behave as if VkPhysicalDeviceExternalImageFormatInfo was not
* present and VkExternalImageFormatProperties will be ignored.
*
* FINISHME(VK_EXT_image_drm_format_modifier): Consider impact of
* VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT on external handles.
*/
if (external_info && external_info->handleType != 0) {
switch (external_info->handleType) {

View File

@@ -27,7 +27,6 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include "drm-uapi/drm_fourcc.h"
#include "anv_private.h"
#include "util/debug.h"
@@ -93,11 +92,10 @@ choose_isl_surf_usage(VkImageCreateFlags vk_create_flags,
}
static isl_tiling_flags_t
choose_isl_tiling_flags(const struct anv_image_create_info *anv_info,
choose_isl_tiling_flags(const struct VkImageCreateInfo *base_info,
const struct isl_drm_modifier_info *isl_mod_info,
bool legacy_scanout)
{
const VkImageCreateInfo *base_info = anv_info->vk_info;
isl_tiling_flags_t flags = 0;
switch (base_info->tiling) {
@@ -111,9 +109,6 @@ choose_isl_tiling_flags(const struct anv_image_create_info *anv_info,
break;
}
if (anv_info->isl_tiling_flags)
flags &= anv_info->isl_tiling_flags;
if (legacy_scanout)
flags &= ISL_TILING_LINEAR_BIT | ISL_TILING_X_BIT;
@@ -331,7 +326,7 @@ make_surface(const struct anv_device *dev,
isl_surf_usage_flags_t shadow_usage = 0;
if (dev->info.gen <= 8 &&
(image->create_flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT) &&
image->tiling == VK_IMAGE_TILING_OPTIMAL) {
image->tiling.vk == VK_IMAGE_TILING_OPTIMAL) {
assert(isl_format_is_compressed(plane_format.isl_format));
tiling_flags = ISL_TILING_LINEAR_BIT;
needs_shadow = true;
@@ -576,6 +571,28 @@ anv_image_create(VkDevice _device,
assert(isl_mod_info);
}
const VkImageDrmFormatModifierListCreateInfoEXT *drm_list_info =
vk_find_struct_const(pCreateInfo->pNext, IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
if (drm_list_info) {
isl_mod_info = choose_drm_format_mod(&device->instance->physicalDevice,
drm_list_info->drmFormatModifierCount,
drm_list_info->pDrmFormatModifiers);
assert(isl_mod_info);
}
const VkImageDrmFormatModifierExplicitCreateInfoEXT *drm_explicit_info =
vk_find_struct_const(pCreateInfo->pNext, IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT);
if (drm_explicit_info) {
/* FINISHME(VK_EXT_image_drm_format_modifier) */
anv_finishme("VkImageDrmFormatModifierExplicitCreateInfoEXT");
abort();
}
if (create_info->drm_format_mod != DRM_FORMAT_MOD_INVALID) {
isl_mod_info = isl_drm_modifier_get_info(create_info->drm_format_mod);
assert(isl_mod_info);
}
anv_assert(pCreateInfo->mipLevels > 0);
anv_assert(pCreateInfo->arrayLayers > 0);
anv_assert(pCreateInfo->samples > 0);
@@ -598,11 +615,11 @@ anv_image_create(VkDevice _device,
image->samples = pCreateInfo->samples;
image->usage = pCreateInfo->usage;
image->create_flags = pCreateInfo->flags;
image->tiling = pCreateInfo->tiling;
image->disjoint = pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT;
image->needs_set_tiling = wsi_info && wsi_info->scanout;
image->drm_format_mod = isl_mod_info ? isl_mod_info->modifier :
DRM_FORMAT_MOD_INVALID;
image->tiling.vk = pCreateInfo->tiling;
image->tiling.drm_format_mod =
isl_mod_info ? isl_mod_info->modifier : DRM_FORMAT_MOD_INVALID;
if (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
image->stencil_usage = pCreateInfo->usage;
@@ -626,7 +643,7 @@ anv_image_create(VkDevice _device,
assert(format != NULL);
const isl_tiling_flags_t isl_tiling_flags =
choose_isl_tiling_flags(create_info, isl_mod_info,
choose_isl_tiling_flags(pCreateInfo, isl_mod_info,
image->needs_set_tiling);
image->n_planes = format->n_planes;
@@ -707,9 +724,9 @@ anv_image_from_swapchain(VkDevice device,
struct wsi_image_create_info local_wsi_info = {
.sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA,
.modifier_count = 1,
.modifiers = &swapchain_image->drm_format_mod,
.modifiers = &swapchain_image->tiling.drm_format_mod,
};
if (swapchain_image->drm_format_mod != DRM_FORMAT_MOD_INVALID)
if (swapchain_image->tiling.drm_format_mod != DRM_FORMAT_MOD_INVALID)
__vk_append_struct(&local_create_info, &local_wsi_info);
return anv_image_create(device,
@@ -810,20 +827,20 @@ resolve_ahw_image(struct anv_device *device,
/* Check tiling. */
int i915_tiling = anv_gem_get_tiling(device, mem->bo->gem_handle);
VkImageTiling vk_tiling;
struct anv_tiling tiling;
isl_tiling_flags_t isl_tiling_flags = 0;
switch (i915_tiling) {
case I915_TILING_NONE:
vk_tiling = VK_IMAGE_TILING_LINEAR;
tiling = anv_tiling_linear();
isl_tiling_flags = ISL_TILING_LINEAR_BIT;
break;
case I915_TILING_X:
vk_tiling = VK_IMAGE_TILING_OPTIMAL;
tiling = anv_tiling_optimal();
isl_tiling_flags = ISL_TILING_X_BIT;
break;
case I915_TILING_Y:
vk_tiling = VK_IMAGE_TILING_OPTIMAL;
tiling = anv_tiling_optimal();
isl_tiling_flags = ISL_TILING_Y0_BIT;
break;
case -1:
@@ -831,15 +848,15 @@ resolve_ahw_image(struct anv_device *device,
unreachable("Invalid tiling flags.");
}
assert(vk_tiling == VK_IMAGE_TILING_LINEAR ||
vk_tiling == VK_IMAGE_TILING_OPTIMAL);
assert(tiling.vk == VK_IMAGE_TILING_LINEAR ||
tiling.vk == VK_IMAGE_TILING_OPTIMAL);
/* Check format. */
VkFormat vk_format = vk_format_from_android(desc.format, desc.usage);
enum isl_format isl_fmt = anv_get_isl_format(&device->info,
vk_format,
VK_IMAGE_ASPECT_COLOR_BIT,
vk_tiling);
tiling);
assert(isl_fmt != ISL_FORMAT_UNSUPPORTED);
/* Handle RGB(X)->RGBA fallback. */
@@ -976,10 +993,17 @@ void anv_GetImageSubresourceLayout(
{
ANV_FROM_HANDLE(anv_image, image, _image);
if (image->tiling.vk == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
/* FINSIHME(VK_EXT_image_drm_format_modifier) */
anv_finishme("vkGetImageSubresourceLayout for "
"VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT");
abort();
}
const struct anv_surface *surface;
if (subresource->aspectMask == VK_IMAGE_ASPECT_PLANE_1_BIT &&
image->drm_format_mod != DRM_FORMAT_MOD_INVALID &&
isl_drm_modifier_has_aux(image->drm_format_mod))
image->tiling.drm_format_mod != DRM_FORMAT_MOD_INVALID &&
isl_drm_modifier_has_aux(image->tiling.drm_format_mod))
surface = &image->planes[0].aux_surface;
else
surface = get_surface(image, subresource->aspectMask);
@@ -1049,7 +1073,7 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
return ISL_AUX_USAGE_NONE;
/* All images that use an auxiliary surface are required to be tiled. */
assert(image->tiling == VK_IMAGE_TILING_OPTIMAL);
assert(image->tiling.vk == VK_IMAGE_TILING_OPTIMAL);
/* Stencil has no aux */
assert(aspect != VK_IMAGE_ASPECT_STENCIL_BIT);
@@ -1117,7 +1141,7 @@ anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
* the modifier.
*/
const struct isl_drm_modifier_info *mod_info =
isl_drm_modifier_get_info(image->drm_format_mod);
isl_drm_modifier_get_info(image->tiling.drm_format_mod);
return mod_info ? mod_info->aux_usage : ISL_AUX_USAGE_NONE;
}
@@ -1179,7 +1203,7 @@ anv_layout_to_fast_clear_type(const struct gen_device_info * const devinfo,
return ANV_FAST_CLEAR_NONE;
/* All images that use an auxiliary surface are required to be tiled. */
assert(image->tiling == VK_IMAGE_TILING_OPTIMAL);
assert(image->tiling.vk == VK_IMAGE_TILING_OPTIMAL);
/* Stencil has no aux */
assert(aspect != VK_IMAGE_ASPECT_STENCIL_BIT);
@@ -1214,7 +1238,7 @@ anv_layout_to_fast_clear_type(const struct gen_device_info * const devinfo,
* just always return NONE. One day, this will change.
*/
const struct isl_drm_modifier_info *mod_info =
isl_drm_modifier_get_info(image->drm_format_mod);
isl_drm_modifier_get_info(image->tiling.drm_format_mod);
assert(!mod_info || !mod_info->supports_clear_color);
#endif
return ANV_FAST_CLEAR_NONE;
@@ -1765,7 +1789,7 @@ anv_CreateBufferView(VkDevice _device,
view->format = anv_get_isl_format(&device->info, pCreateInfo->format,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_TILING_LINEAR);
anv_tiling_linear());
const uint32_t format_bs = isl_format_get_layout(view->format)->bpb / 8;
view->range = anv_buffer_get_range(buffer, pCreateInfo->offset,
pCreateInfo->range);

View File

@@ -51,7 +51,7 @@ VkResult anv_CreateDmaBufImageINTEL(
result = anv_image_create(_device,
&(struct anv_image_create_info) {
.isl_tiling_flags = ISL_TILING_X_BIT,
.drm_format_mod = I915_FORMAT_MOD_X_TILED,
.stride = pCreateInfo->strideInBytes,
.vk_info = &(VkImageCreateInfo) {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
@@ -61,7 +61,6 @@ VkResult anv_CreateDmaBufImageINTEL(
.mipLevels = 1,
.arrayLayers = 1,
.samples = 1,
/* FIXME: Need a way to use X tiling to allow scanout */
.tiling = VK_IMAGE_TILING_OPTIMAL,
.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
.flags = 0,

View File

@@ -43,6 +43,7 @@
#define VG(x)
#endif
#include "drm-uapi/drm_fourcc.h"
#include "common/gen_clflush.h"
#include "common/gen_decoder.h"
#include "common/gen_gem.h"
@@ -2912,6 +2913,54 @@ anv_plane_to_aspect(VkImageAspectFlags image_aspects,
#define anv_foreach_image_aspect_bit(b, image, aspects) \
for_each_bit(b, anv_image_expand_aspects(image, aspects))
/**
* TODO(chadv-drm): Explain legal values.
*/
struct anv_tiling {
VkImageTiling vk;
uint64_t drm_format_mod;
};
/** Return the equivalent of VK_IMAGE_TILING_LINEAR. */
static inline struct anv_tiling
anv_tiling_linear(void) {
return (struct anv_tiling) {
.vk = VK_IMAGE_TILING_LINEAR,
.drm_format_mod = DRM_FORMAT_MOD_INVALID,
};
}
/** Return the equivalent of VK_IMAGE_TILING_OPTIMAL. */
static inline struct anv_tiling
anv_tiling_optimal(void) {
return (struct anv_tiling) {
.vk = VK_IMAGE_TILING_OPTIMAL,
.drm_format_mod = DRM_FORMAT_MOD_INVALID,
};
}
/** Return tiling with VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT. */
static inline struct anv_tiling
anv_tiling_drm(uint64_t drm_format_mod) {
return (struct anv_tiling) {
.vk = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
.drm_format_mod = drm_format_mod,
};
}
static inline bool
anv_tiling_is_linear(struct anv_tiling tiling) {
if (tiling.vk == VK_IMAGE_TILING_LINEAR)
return true;
if (tiling.vk == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
tiling.drm_format_mod == DRM_FORMAT_MOD_LINEAR)
return true;
return false;
}
const struct anv_format *
anv_get_format(VkFormat format);
@@ -2925,11 +2974,11 @@ anv_get_format_planes(VkFormat vk_format)
struct anv_format_plane
anv_get_format_plane(const struct gen_device_info *devinfo, VkFormat vk_format,
VkImageAspectFlagBits aspect, VkImageTiling tiling);
VkImageAspectFlagBits aspect, struct anv_tiling tiling);
static inline enum isl_format
anv_get_isl_format(const struct gen_device_info *devinfo, VkFormat vk_format,
VkImageAspectFlags aspect, VkImageTiling tiling)
VkImageAspectFlags aspect, struct anv_tiling tiling)
{
return anv_get_format_plane(devinfo, vk_format, aspect, tiling).isl_format;
}
@@ -2982,7 +3031,7 @@ struct anv_image {
VkImageUsageFlags usage; /**< VkImageCreateInfo::usage. */
VkImageUsageFlags stencil_usage;
VkImageCreateFlags create_flags; /* Flags used when creating image. */
VkImageTiling tiling; /** VkImageCreateInfo::tiling */
struct anv_tiling tiling;
/** True if this is needs to be bound to an appropriately tiled BO.
*
@@ -2993,12 +3042,6 @@ struct anv_image {
*/
bool needs_set_tiling;
/**
* Must be DRM_FORMAT_MOD_INVALID unless tiling is
* VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT.
*/
uint64_t drm_format_mod;
VkDeviceSize size;
uint32_t alignment;
@@ -3405,8 +3448,8 @@ void anv_image_fill_surface_state(struct anv_device *device,
struct anv_image_create_info {
const VkImageCreateInfo *vk_info;
/** An opt-in bitmask which filters an ISL-mapping of the Vulkan tiling. */
isl_tiling_flags_t isl_tiling_flags;
/** Force a specific tiling unless DRM_FORMAT_MOD_INVALID. */
uint64_t drm_format_mod;
/** These flags will be added to any derived from VkImageCreateInfo. */
isl_surf_usage_flags_t isl_extra_usage_flags;
@@ -3463,7 +3506,7 @@ VkFormatFeatureFlags
anv_get_image_format_features(const struct gen_device_info *devinfo,
VkFormat vk_format,
const struct anv_format *anv_format,
VkImageTiling vk_tiling);
struct anv_tiling tiling);
void anv_fill_buffer_surface_state(struct anv_device *device,
struct anv_state state,

View File

@@ -37,7 +37,7 @@ static uint64_t
anv_wsi_image_get_modifier(VkImage _image)
{
ANV_FROM_HANDLE(anv_image, image, _image);
return image->drm_format_mod;
return image->tiling.drm_format_mod;
}
VkResult

View File

@@ -1003,7 +1003,7 @@ transition_color_buffer(struct anv_cmd_buffer *cmd_buffer,
if (base_layer >= anv_image_aux_layers(image, aspect, base_level))
return;
assert(image->tiling == VK_IMAGE_TILING_OPTIMAL);
assert(image->tiling.vk == VK_IMAGE_TILING_OPTIMAL);
if (initial_layout == VK_IMAGE_LAYOUT_UNDEFINED ||
initial_layout == VK_IMAGE_LAYOUT_PREINITIALIZED) {

View File

@@ -150,7 +150,7 @@ emit_vertex_input(struct anv_pipeline *pipeline,
enum isl_format format = anv_get_isl_format(&pipeline->device->info,
desc->format,
VK_IMAGE_ASPECT_COLOR_BIT,
VK_IMAGE_TILING_LINEAR);
anv_tiling_linear());
assert(desc->binding < MAX_VBS);
@@ -604,7 +604,7 @@ emit_rs_state(struct anv_pipeline *pipeline,
enum isl_format isl_format =
anv_get_isl_format(&pipeline->device->info, vk_format,
VK_IMAGE_ASPECT_DEPTH_BIT,
VK_IMAGE_TILING_OPTIMAL);
anv_tiling_optimal());
sf.DepthBufferSurfaceFormat =
isl_format_get_depth_format(isl_format, false);
}