Resolve Image Usage Validation Error

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 KeatonTheBot
parent 78093a1d0c
commit e7a3400b9a
4 changed files with 29 additions and 12 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

@ -67,7 +67,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);
@ -80,7 +82,7 @@ namespace Ryujinx.Graphics.Vulkan
var sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples);
var usage = GetImageUsage(info.Format, info.Target, gd.Capabilities.SupportsShaderStorageImageMultisample);
var usage = GetImageUsage(info.Format, gd.Capabilities, isMsImageStorageSupported, true);
var flags = ImageCreateFlags.CreateMutableFormatBit | ImageCreateFlags.CreateExtendedUsageBit;
@ -292,7 +294,7 @@ namespace Ryujinx.Graphics.Vulkan
}
}
public static ImageUsageFlags GetImageUsage(Format format, Target target, bool supportsMsStorage)
public static ImageUsageFlags GetImageUsage(Format format, in HardwareCapabilities capabilities, bool isMsImageStorageSupported, bool extendedUsage)
{
var usage = DefaultUsageFlags;
@ -305,7 +307,7 @@ namespace Ryujinx.Graphics.Vulkan
usage |= ImageUsageFlags.ColorAttachmentBit;
}
if (format.IsImageCompatible() && (supportsMsStorage || !target.IsMultisample()))
if ((format.IsImageCompatible() && isMsImageStorageSupported) || extendedUsage)
{
usage |= ImageUsageFlags.StorageBit;
}

View file

@ -59,8 +59,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.SupportsShaderStorageImageMultisample);
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();