Resolve Image Usage Validation Error (#296)
Some checks are pending
Canary release job / Create tag (push) Waiting to run
Canary release job / Release for linux-arm64 (push) Waiting to run
Canary release job / Release for linux-x64 (push) Waiting to run
Canary release job / Release for win-x64 (push) Waiting to run
Canary release job / Release MacOS universal (push) Waiting to run

This was a missed change that would resolve Image Usage validation error
that is created fairly frequently.

``VUID-VkImageViewCreateInfo-pNext-02662(ERROR / SPEC): msgNum:
-55646969 - Validation Error: [ VUID-VkImageViewCreateInfo-pNext-02662 ]
Object 0: handle = 0x260b9d1f6b8, type = VK_OBJECT_TYPE_IMAGE; |
MessageID = 0xfcaee507 | vkCreateImageView():
pCreateInfo->pNext<VkImageViewUsageCreateInfo>.usage
(VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_STORAGE_BIT) must not include
any bits that were not set in VkImageCreateInfo::usage
(VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
of the image. The Vulkan spec states: If the pNext chain includes a
VkImageViewUsageCreateInfo structure, and image was not created with a
VkImageStencilUsageCreateInfo structure included in the pNext chain of
VkImageCreateInfo, its usage member must not include any bits that were
not set in the usage member of the VkImageCreateInfo structure used to
create image
(https://vulkan.lunarg.com/doc/view/1.3.290.0/windows/1.3-extensions/vkspec.html#VUID-VkImageViewCreateInfo-pNext-02662)
    Objects: 1
        [0] 0x260b9d1f6b8, type: 10, name: NULL
``
This commit is contained in:
sunshineinabox 2024-12-20 14:31:05 -08:00 committed by GitHub
parent d68295e57d
commit c77c1acd08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 29 additions and 14 deletions

View file

@ -148,7 +148,7 @@ namespace Ryujinx.Graphics.Vulkan
return (formatFeatureFlags & flags) == flags;
}
public VkFormat ConvertToVkFormat(Format srcFormat)
public VkFormat ConvertToVkFormat(Format srcFormat, bool storageFeatureFlagRequired)
{
var format = FormatTable.GetFormat(srcFormat);
@ -165,7 +165,7 @@ namespace Ryujinx.Graphics.Vulkan
requiredFeatures |= FormatFeatureFlags.ColorAttachmentBit;
}
if (srcFormat.IsImageCompatible())
if (srcFormat.IsImageCompatible() && storageFeatureFlagRequired)
{
requiredFeatures |= FormatFeatureFlags.StorageImageBit;
}

View file

@ -29,11 +29,17 @@ namespace Ryujinx.Graphics.Vulkan
int colorCount = 0;
int maxColorAttachmentIndex = -1;
bool isNotMsOrSupportsStorage = gd.Capabilities.SupportsShaderStorageImageMultisample ||
!state.DepthStencilFormat.IsImageCompatible();
for (int i = 0; i < state.AttachmentEnable.Length; i++)
{
if (state.AttachmentEnable[i])
{
attachmentFormats[attachmentCount] = gd.FormatCapabilities.ConvertToVkFormat(state.AttachmentFormats[i]);
bool isNotMsOrSupportsStorageAttachments = gd.Capabilities.SupportsShaderStorageImageMultisample ||
!state.AttachmentFormats[i].IsImageCompatible();
attachmentFormats[attachmentCount] = gd.FormatCapabilities.ConvertToVkFormat(state.AttachmentFormats[i], isNotMsOrSupportsStorageAttachments);
attachmentIndices[attachmentCount++] = i;
colorCount++;
@ -43,7 +49,7 @@ namespace Ryujinx.Graphics.Vulkan
if (state.DepthStencilEnable)
{
attachmentFormats[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(state.DepthStencilFormat);
attachmentFormats[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(state.DepthStencilFormat, isNotMsOrSupportsStorage);
}
if (attachmentCount != 0)
@ -296,7 +302,10 @@ namespace Ryujinx.Graphics.Vulkan
{
if (state.AttachmentEnable[i])
{
pipeline.Internal.AttachmentFormats[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(state.AttachmentFormats[i]);
bool isNotMsOrSupportsStorage = gd.Capabilities.SupportsShaderStorageImageMultisample ||
!state.AttachmentFormats[i].IsImageCompatible();
pipeline.Internal.AttachmentFormats[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(state.AttachmentFormats[i], isNotMsOrSupportsStorage);
maxColorAttachmentIndex = i;
if (state.AttachmentFormats[i].IsInteger())
@ -310,7 +319,10 @@ namespace Ryujinx.Graphics.Vulkan
if (state.DepthStencilEnable)
{
pipeline.Internal.AttachmentFormats[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(state.DepthStencilFormat);
bool isNotMsOrSupportsStorage = !state.DepthStencilFormat.IsImageCompatible() ||
gd.Capabilities.SupportsShaderStorageImageMultisample;
pipeline.Internal.AttachmentFormats[attachmentCount++] = gd.FormatCapabilities.ConvertToVkFormat(state.DepthStencilFormat, isNotMsOrSupportsStorage);
}
pipeline.ColorBlendAttachmentStateCount = (uint)(maxColorAttachmentIndex + 1);

View file

@ -77,7 +77,9 @@ namespace Ryujinx.Graphics.Vulkan
_device = device;
_info = info;
var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format);
bool isMsImageStorageSupported = gd.Capabilities.SupportsShaderStorageImageMultisample || !info.Target.IsMultisample();
var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format, isMsImageStorageSupported);
var levels = (uint)info.Levels;
var layers = (uint)info.GetLayers();
var depth = (uint)(info.Target == Target.Texture3D ? info.Depth : 1);
@ -91,7 +93,7 @@ namespace Ryujinx.Graphics.Vulkan
var sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples);
var usage = GetImageUsage(info.Format, info.Target, gd.Capabilities);
var usage = GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported, true);
var flags = ImageCreateFlags.CreateMutableFormatBit | ImageCreateFlags.CreateExtendedUsageBit;
@ -305,7 +307,7 @@ namespace Ryujinx.Graphics.Vulkan
}
}
public static ImageUsageFlags GetImageUsage(Format format, Target target, in HardwareCapabilities capabilities)
public static ImageUsageFlags GetImageUsage(Format format, in HardwareCapabilities capabilities, bool isMsImageStorageSupported, bool extendedUsage)
{
var usage = DefaultUsageFlags;
@ -318,9 +320,7 @@ namespace Ryujinx.Graphics.Vulkan
usage |= ImageUsageFlags.ColorAttachmentBit;
}
bool supportsMsStorage = capabilities.SupportsShaderStorageImageMultisample;
if (format.IsImageCompatible() && (supportsMsStorage || !target.IsMultisample()))
if ((format.IsImageCompatible() && isMsImageStorageSupported) || extendedUsage)
{
usage |= ImageUsageFlags.StorageBit;
}

View file

@ -61,8 +61,11 @@ namespace Ryujinx.Graphics.Vulkan
gd.Textures.Add(this);
var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format);
var usage = TextureStorage.GetImageUsage(info.Format, info.Target, gd.Capabilities);
bool isMsImageStorageSupported = gd.Capabilities.SupportsShaderStorageImageMultisample || !info.Target.IsMultisample();
var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format, isMsImageStorageSupported);
var usage = TextureStorage.GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported, false);
var levels = (uint)info.Levels;
var layers = (uint)info.GetLayers();