mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2024-12-31 21:13:04 +00:00
492a046335
* Initial implementation of buffer mirrors Generally slower right now, goal is to reduce render passes in games that do inline updates Fix support buffer mirrors Reintroduce vertex buffer mirror Add storage buffer support Optimisation part 1 More optimisation Avoid useless data copies. Remove unused cbIndex stuff Properly set write flag for storage buffers. Fix minor issues Not sure why this was here. Fix BufferRangeList Fix some big issues Align storage buffers rather than getting full buffer as a range Improves mirrorability of read-only storage buffers Increase staging buffer size, as it now contains mirrors Fix some issues with buffers not updating Fix buffer SetDataUnchecked offset for one of the paths when using mirrors Fix buffer mirrors interaction with buffer textures Fix mirror rebinding Move GetBuffer calls on indirect draws before BeginRenderPass to avoid draws without render pass Fix mirrors rebase Fix rebase 2023 * Fix crash when using stale vertex buffer Similar to `Get` with a size that's too large, just treat it as a clamp. * Explicitly set support buffer as mirrorable * Address feedback * Remove unused fragment of MVK workaround * Replace logging for staging buffer OOM * Address format issues * Address more format issues * Mini cleanup * Address more things * Rename BufferRangeList * Support bounding range for ClearMirrors and UploadPendingData * Add maximum size for vertex buffer mirrors * Enable index buffer mirrors Enabled on all platforms for the IbStreamer. * Feedback * Remove mystery BufferCache change Probably macos related? * Fix mirrors not creating when staging buffer is empty. * Change log level to debug
442 lines
22 KiB
C#
442 lines
22 KiB
C#
using Ryujinx.Common.Logging;
|
|
using Ryujinx.Graphics.GAL;
|
|
using Ryujinx.Graphics.Shader;
|
|
using Silk.NET.Vulkan;
|
|
using System;
|
|
using BlendFactor = Silk.NET.Vulkan.BlendFactor;
|
|
using BlendOp = Silk.NET.Vulkan.BlendOp;
|
|
using CompareOp = Silk.NET.Vulkan.CompareOp;
|
|
using Format = Ryujinx.Graphics.GAL.Format;
|
|
using FrontFace = Silk.NET.Vulkan.FrontFace;
|
|
using IndexType = Silk.NET.Vulkan.IndexType;
|
|
using PrimitiveTopology = Silk.NET.Vulkan.PrimitiveTopology;
|
|
using StencilOp = Silk.NET.Vulkan.StencilOp;
|
|
|
|
namespace Ryujinx.Graphics.Vulkan
|
|
{
|
|
static class EnumConversion
|
|
{
|
|
public static ShaderStageFlags Convert(this ShaderStage stage)
|
|
{
|
|
return stage switch
|
|
{
|
|
ShaderStage.Vertex => ShaderStageFlags.VertexBit,
|
|
ShaderStage.Geometry => ShaderStageFlags.GeometryBit,
|
|
ShaderStage.TessellationControl => ShaderStageFlags.TessellationControlBit,
|
|
ShaderStage.TessellationEvaluation => ShaderStageFlags.TessellationEvaluationBit,
|
|
ShaderStage.Fragment => ShaderStageFlags.FragmentBit,
|
|
ShaderStage.Compute => ShaderStageFlags.ComputeBit,
|
|
_ => LogInvalidAndReturn(stage, nameof(ShaderStage), (ShaderStageFlags)0),
|
|
};
|
|
}
|
|
|
|
public static PipelineStageFlags ConvertToPipelineStageFlags(this ShaderStage stage)
|
|
{
|
|
return stage switch
|
|
{
|
|
ShaderStage.Vertex => PipelineStageFlags.VertexShaderBit,
|
|
ShaderStage.Geometry => PipelineStageFlags.GeometryShaderBit,
|
|
ShaderStage.TessellationControl => PipelineStageFlags.TessellationControlShaderBit,
|
|
ShaderStage.TessellationEvaluation => PipelineStageFlags.TessellationEvaluationShaderBit,
|
|
ShaderStage.Fragment => PipelineStageFlags.FragmentShaderBit,
|
|
ShaderStage.Compute => PipelineStageFlags.ComputeShaderBit,
|
|
_ => LogInvalidAndReturn(stage, nameof(ShaderStage), (PipelineStageFlags)0),
|
|
};
|
|
}
|
|
|
|
public static ShaderStageFlags Convert(this ResourceStages stages)
|
|
{
|
|
ShaderStageFlags stageFlags = stages.HasFlag(ResourceStages.Compute)
|
|
? ShaderStageFlags.ComputeBit
|
|
: ShaderStageFlags.None;
|
|
|
|
if (stages.HasFlag(ResourceStages.Vertex))
|
|
{
|
|
stageFlags |= ShaderStageFlags.VertexBit;
|
|
}
|
|
|
|
if (stages.HasFlag(ResourceStages.TessellationControl))
|
|
{
|
|
stageFlags |= ShaderStageFlags.TessellationControlBit;
|
|
}
|
|
|
|
if (stages.HasFlag(ResourceStages.TessellationEvaluation))
|
|
{
|
|
stageFlags |= ShaderStageFlags.TessellationEvaluationBit;
|
|
}
|
|
|
|
if (stages.HasFlag(ResourceStages.Geometry))
|
|
{
|
|
stageFlags |= ShaderStageFlags.GeometryBit;
|
|
}
|
|
|
|
if (stages.HasFlag(ResourceStages.Fragment))
|
|
{
|
|
stageFlags |= ShaderStageFlags.FragmentBit;
|
|
}
|
|
|
|
return stageFlags;
|
|
}
|
|
|
|
public static DescriptorType Convert(this ResourceType type)
|
|
{
|
|
return type switch
|
|
{
|
|
ResourceType.UniformBuffer => DescriptorType.UniformBuffer,
|
|
ResourceType.StorageBuffer => DescriptorType.StorageBuffer,
|
|
ResourceType.Texture => DescriptorType.SampledImage,
|
|
ResourceType.Sampler => DescriptorType.Sampler,
|
|
ResourceType.TextureAndSampler => DescriptorType.CombinedImageSampler,
|
|
ResourceType.Image => DescriptorType.StorageImage,
|
|
ResourceType.BufferTexture => DescriptorType.UniformTexelBuffer,
|
|
ResourceType.BufferImage => DescriptorType.StorageTexelBuffer,
|
|
_ => throw new ArgumentException($"Invalid resource type \"{type}\"."),
|
|
};
|
|
}
|
|
|
|
public static SamplerAddressMode Convert(this AddressMode mode)
|
|
{
|
|
return mode switch
|
|
{
|
|
AddressMode.Clamp => SamplerAddressMode.ClampToEdge, // TODO: Should be clamp.
|
|
AddressMode.Repeat => SamplerAddressMode.Repeat,
|
|
AddressMode.MirrorClamp => SamplerAddressMode.ClampToEdge, // TODO: Should be mirror clamp.
|
|
AddressMode.MirrorClampToEdge => SamplerAddressMode.MirrorClampToEdgeKhr,
|
|
AddressMode.MirrorClampToBorder => SamplerAddressMode.ClampToBorder, // TODO: Should be mirror clamp to border.
|
|
AddressMode.ClampToBorder => SamplerAddressMode.ClampToBorder,
|
|
AddressMode.MirroredRepeat => SamplerAddressMode.MirroredRepeat,
|
|
AddressMode.ClampToEdge => SamplerAddressMode.ClampToEdge,
|
|
_ => LogInvalidAndReturn(mode, nameof(AddressMode), SamplerAddressMode.ClampToEdge), // TODO: Should be clamp.
|
|
};
|
|
}
|
|
|
|
public static BlendFactor Convert(this GAL.BlendFactor factor)
|
|
{
|
|
return factor switch
|
|
{
|
|
GAL.BlendFactor.Zero or GAL.BlendFactor.ZeroGl => BlendFactor.Zero,
|
|
GAL.BlendFactor.One or GAL.BlendFactor.OneGl => BlendFactor.One,
|
|
GAL.BlendFactor.SrcColor or GAL.BlendFactor.SrcColorGl => BlendFactor.SrcColor,
|
|
GAL.BlendFactor.OneMinusSrcColor or GAL.BlendFactor.OneMinusSrcColorGl => BlendFactor.OneMinusSrcColor,
|
|
GAL.BlendFactor.SrcAlpha or GAL.BlendFactor.SrcAlphaGl => BlendFactor.SrcAlpha,
|
|
GAL.BlendFactor.OneMinusSrcAlpha or GAL.BlendFactor.OneMinusSrcAlphaGl => BlendFactor.OneMinusSrcAlpha,
|
|
GAL.BlendFactor.DstAlpha or GAL.BlendFactor.DstAlphaGl => BlendFactor.DstAlpha,
|
|
GAL.BlendFactor.OneMinusDstAlpha or GAL.BlendFactor.OneMinusDstAlphaGl => BlendFactor.OneMinusDstAlpha,
|
|
GAL.BlendFactor.DstColor or GAL.BlendFactor.DstColorGl => BlendFactor.DstColor,
|
|
GAL.BlendFactor.OneMinusDstColor or GAL.BlendFactor.OneMinusDstColorGl => BlendFactor.OneMinusDstColor,
|
|
GAL.BlendFactor.SrcAlphaSaturate or GAL.BlendFactor.SrcAlphaSaturateGl => BlendFactor.SrcAlphaSaturate,
|
|
GAL.BlendFactor.Src1Color or GAL.BlendFactor.Src1ColorGl => BlendFactor.Src1Color,
|
|
GAL.BlendFactor.OneMinusSrc1Color or GAL.BlendFactor.OneMinusSrc1ColorGl => BlendFactor.OneMinusSrc1Color,
|
|
GAL.BlendFactor.Src1Alpha or GAL.BlendFactor.Src1AlphaGl => BlendFactor.Src1Alpha,
|
|
GAL.BlendFactor.OneMinusSrc1Alpha or GAL.BlendFactor.OneMinusSrc1AlphaGl => BlendFactor.OneMinusSrc1Alpha,
|
|
GAL.BlendFactor.ConstantColor => BlendFactor.ConstantColor,
|
|
GAL.BlendFactor.OneMinusConstantColor => BlendFactor.OneMinusConstantColor,
|
|
GAL.BlendFactor.ConstantAlpha => BlendFactor.ConstantAlpha,
|
|
GAL.BlendFactor.OneMinusConstantAlpha => BlendFactor.OneMinusConstantAlpha,
|
|
_ => LogInvalidAndReturn(factor, nameof(GAL.BlendFactor), BlendFactor.Zero),
|
|
};
|
|
}
|
|
|
|
public static BlendOp Convert(this AdvancedBlendOp op)
|
|
{
|
|
return op switch
|
|
{
|
|
AdvancedBlendOp.Zero => BlendOp.ZeroExt,
|
|
AdvancedBlendOp.Src => BlendOp.SrcExt,
|
|
AdvancedBlendOp.Dst => BlendOp.DstExt,
|
|
AdvancedBlendOp.SrcOver => BlendOp.SrcOverExt,
|
|
AdvancedBlendOp.DstOver => BlendOp.DstOverExt,
|
|
AdvancedBlendOp.SrcIn => BlendOp.SrcInExt,
|
|
AdvancedBlendOp.DstIn => BlendOp.DstInExt,
|
|
AdvancedBlendOp.SrcOut => BlendOp.SrcOutExt,
|
|
AdvancedBlendOp.DstOut => BlendOp.DstOutExt,
|
|
AdvancedBlendOp.SrcAtop => BlendOp.SrcAtopExt,
|
|
AdvancedBlendOp.DstAtop => BlendOp.DstAtopExt,
|
|
AdvancedBlendOp.Xor => BlendOp.XorExt,
|
|
AdvancedBlendOp.Plus => BlendOp.PlusExt,
|
|
AdvancedBlendOp.PlusClamped => BlendOp.PlusClampedExt,
|
|
AdvancedBlendOp.PlusClampedAlpha => BlendOp.PlusClampedAlphaExt,
|
|
AdvancedBlendOp.PlusDarker => BlendOp.PlusDarkerExt,
|
|
AdvancedBlendOp.Multiply => BlendOp.MultiplyExt,
|
|
AdvancedBlendOp.Screen => BlendOp.ScreenExt,
|
|
AdvancedBlendOp.Overlay => BlendOp.OverlayExt,
|
|
AdvancedBlendOp.Darken => BlendOp.DarkenExt,
|
|
AdvancedBlendOp.Lighten => BlendOp.LightenExt,
|
|
AdvancedBlendOp.ColorDodge => BlendOp.ColordodgeExt,
|
|
AdvancedBlendOp.ColorBurn => BlendOp.ColorburnExt,
|
|
AdvancedBlendOp.HardLight => BlendOp.HardlightExt,
|
|
AdvancedBlendOp.SoftLight => BlendOp.SoftlightExt,
|
|
AdvancedBlendOp.Difference => BlendOp.DifferenceExt,
|
|
AdvancedBlendOp.Minus => BlendOp.MinusExt,
|
|
AdvancedBlendOp.MinusClamped => BlendOp.MinusClampedExt,
|
|
AdvancedBlendOp.Exclusion => BlendOp.ExclusionExt,
|
|
AdvancedBlendOp.Contrast => BlendOp.ContrastExt,
|
|
AdvancedBlendOp.Invert => BlendOp.InvertExt,
|
|
AdvancedBlendOp.InvertRGB => BlendOp.InvertRgbExt,
|
|
AdvancedBlendOp.InvertOvg => BlendOp.InvertOvgExt,
|
|
AdvancedBlendOp.LinearDodge => BlendOp.LineardodgeExt,
|
|
AdvancedBlendOp.LinearBurn => BlendOp.LinearburnExt,
|
|
AdvancedBlendOp.VividLight => BlendOp.VividlightExt,
|
|
AdvancedBlendOp.LinearLight => BlendOp.LinearlightExt,
|
|
AdvancedBlendOp.PinLight => BlendOp.PinlightExt,
|
|
AdvancedBlendOp.HardMix => BlendOp.HardmixExt,
|
|
AdvancedBlendOp.Red => BlendOp.RedExt,
|
|
AdvancedBlendOp.Green => BlendOp.GreenExt,
|
|
AdvancedBlendOp.Blue => BlendOp.BlueExt,
|
|
AdvancedBlendOp.HslHue => BlendOp.HslHueExt,
|
|
AdvancedBlendOp.HslSaturation => BlendOp.HslSaturationExt,
|
|
AdvancedBlendOp.HslColor => BlendOp.HslColorExt,
|
|
AdvancedBlendOp.HslLuminosity => BlendOp.HslLuminosityExt,
|
|
_ => LogInvalidAndReturn(op, nameof(AdvancedBlendOp), BlendOp.Add),
|
|
};
|
|
}
|
|
|
|
public static BlendOp Convert(this GAL.BlendOp op)
|
|
{
|
|
return op switch
|
|
{
|
|
GAL.BlendOp.Add or GAL.BlendOp.AddGl => BlendOp.Add,
|
|
GAL.BlendOp.Subtract or GAL.BlendOp.SubtractGl => BlendOp.Subtract,
|
|
GAL.BlendOp.ReverseSubtract or GAL.BlendOp.ReverseSubtractGl => BlendOp.ReverseSubtract,
|
|
GAL.BlendOp.Minimum or GAL.BlendOp.MinimumGl => BlendOp.Min,
|
|
GAL.BlendOp.Maximum or GAL.BlendOp.MaximumGl => BlendOp.Max,
|
|
_ => LogInvalidAndReturn(op, nameof(GAL.BlendOp), BlendOp.Add),
|
|
};
|
|
}
|
|
|
|
public static BlendOverlapEXT Convert(this AdvancedBlendOverlap overlap)
|
|
{
|
|
return overlap switch
|
|
{
|
|
AdvancedBlendOverlap.Uncorrelated => BlendOverlapEXT.UncorrelatedExt,
|
|
AdvancedBlendOverlap.Disjoint => BlendOverlapEXT.DisjointExt,
|
|
AdvancedBlendOverlap.Conjoint => BlendOverlapEXT.ConjointExt,
|
|
_ => LogInvalidAndReturn(overlap, nameof(AdvancedBlendOverlap), BlendOverlapEXT.UncorrelatedExt),
|
|
};
|
|
}
|
|
|
|
public static CompareOp Convert(this GAL.CompareOp op)
|
|
{
|
|
return op switch
|
|
{
|
|
GAL.CompareOp.Never or GAL.CompareOp.NeverGl => CompareOp.Never,
|
|
GAL.CompareOp.Less or GAL.CompareOp.LessGl => CompareOp.Less,
|
|
GAL.CompareOp.Equal or GAL.CompareOp.EqualGl => CompareOp.Equal,
|
|
GAL.CompareOp.LessOrEqual or GAL.CompareOp.LessOrEqualGl => CompareOp.LessOrEqual,
|
|
GAL.CompareOp.Greater or GAL.CompareOp.GreaterGl => CompareOp.Greater,
|
|
GAL.CompareOp.NotEqual or GAL.CompareOp.NotEqualGl => CompareOp.NotEqual,
|
|
GAL.CompareOp.GreaterOrEqual or GAL.CompareOp.GreaterOrEqualGl => CompareOp.GreaterOrEqual,
|
|
GAL.CompareOp.Always or GAL.CompareOp.AlwaysGl => CompareOp.Always,
|
|
_ => LogInvalidAndReturn(op, nameof(GAL.CompareOp), CompareOp.Never),
|
|
};
|
|
}
|
|
|
|
public static CullModeFlags Convert(this Face face)
|
|
{
|
|
return face switch
|
|
{
|
|
Face.Back => CullModeFlags.BackBit,
|
|
Face.Front => CullModeFlags.FrontBit,
|
|
Face.FrontAndBack => CullModeFlags.FrontAndBack,
|
|
_ => LogInvalidAndReturn(face, nameof(Face), CullModeFlags.BackBit),
|
|
};
|
|
}
|
|
|
|
public static FrontFace Convert(this GAL.FrontFace frontFace)
|
|
{
|
|
// Flipped to account for origin differences.
|
|
return frontFace switch
|
|
{
|
|
GAL.FrontFace.Clockwise => FrontFace.CounterClockwise,
|
|
GAL.FrontFace.CounterClockwise => FrontFace.Clockwise,
|
|
_ => LogInvalidAndReturn(frontFace, nameof(GAL.FrontFace), FrontFace.Clockwise),
|
|
};
|
|
}
|
|
|
|
public static IndexType Convert(this GAL.IndexType type)
|
|
{
|
|
return type switch
|
|
{
|
|
GAL.IndexType.UByte => IndexType.Uint8Ext,
|
|
GAL.IndexType.UShort => IndexType.Uint16,
|
|
GAL.IndexType.UInt => IndexType.Uint32,
|
|
_ => LogInvalidAndReturn(type, nameof(GAL.IndexType), IndexType.Uint16),
|
|
};
|
|
}
|
|
|
|
public static Filter Convert(this MagFilter filter)
|
|
{
|
|
return filter switch
|
|
{
|
|
MagFilter.Nearest => Filter.Nearest,
|
|
MagFilter.Linear => Filter.Linear,
|
|
_ => LogInvalidAndReturn(filter, nameof(MagFilter), Filter.Nearest),
|
|
};
|
|
}
|
|
|
|
public static (Filter, SamplerMipmapMode) Convert(this MinFilter filter)
|
|
{
|
|
return filter switch
|
|
{
|
|
MinFilter.Nearest => (Filter.Nearest, SamplerMipmapMode.Nearest),
|
|
MinFilter.Linear => (Filter.Linear, SamplerMipmapMode.Nearest),
|
|
MinFilter.NearestMipmapNearest => (Filter.Nearest, SamplerMipmapMode.Nearest),
|
|
MinFilter.LinearMipmapNearest => (Filter.Linear, SamplerMipmapMode.Nearest),
|
|
MinFilter.NearestMipmapLinear => (Filter.Nearest, SamplerMipmapMode.Linear),
|
|
MinFilter.LinearMipmapLinear => (Filter.Linear, SamplerMipmapMode.Linear),
|
|
_ => LogInvalidAndReturn(filter, nameof(MinFilter), (Filter.Nearest, SamplerMipmapMode.Nearest)),
|
|
};
|
|
}
|
|
|
|
public static PrimitiveTopology Convert(this GAL.PrimitiveTopology topology)
|
|
{
|
|
return topology switch
|
|
{
|
|
GAL.PrimitiveTopology.Points => PrimitiveTopology.PointList,
|
|
GAL.PrimitiveTopology.Lines => PrimitiveTopology.LineList,
|
|
GAL.PrimitiveTopology.LineStrip => PrimitiveTopology.LineStrip,
|
|
GAL.PrimitiveTopology.Triangles => PrimitiveTopology.TriangleList,
|
|
GAL.PrimitiveTopology.TriangleStrip => PrimitiveTopology.TriangleStrip,
|
|
GAL.PrimitiveTopology.TriangleFan => PrimitiveTopology.TriangleFan,
|
|
GAL.PrimitiveTopology.LinesAdjacency => PrimitiveTopology.LineListWithAdjacency,
|
|
GAL.PrimitiveTopology.LineStripAdjacency => PrimitiveTopology.LineStripWithAdjacency,
|
|
GAL.PrimitiveTopology.TrianglesAdjacency => PrimitiveTopology.TriangleListWithAdjacency,
|
|
GAL.PrimitiveTopology.TriangleStripAdjacency => PrimitiveTopology.TriangleStripWithAdjacency,
|
|
GAL.PrimitiveTopology.Patches => PrimitiveTopology.PatchList,
|
|
GAL.PrimitiveTopology.Polygon => PrimitiveTopology.TriangleFan,
|
|
GAL.PrimitiveTopology.Quads => throw new NotSupportedException("Quad topology is not available in Vulkan."),
|
|
GAL.PrimitiveTopology.QuadStrip => throw new NotSupportedException("QuadStrip topology is not available in Vulkan."),
|
|
_ => LogInvalidAndReturn(topology, nameof(GAL.PrimitiveTopology), PrimitiveTopology.TriangleList),
|
|
};
|
|
}
|
|
|
|
public static StencilOp Convert(this GAL.StencilOp op)
|
|
{
|
|
return op switch
|
|
{
|
|
GAL.StencilOp.Keep or GAL.StencilOp.KeepGl => StencilOp.Keep,
|
|
GAL.StencilOp.Zero or GAL.StencilOp.ZeroGl => StencilOp.Zero,
|
|
GAL.StencilOp.Replace or GAL.StencilOp.ReplaceGl => StencilOp.Replace,
|
|
GAL.StencilOp.IncrementAndClamp or GAL.StencilOp.IncrementAndClampGl => StencilOp.IncrementAndClamp,
|
|
GAL.StencilOp.DecrementAndClamp or GAL.StencilOp.DecrementAndClampGl => StencilOp.DecrementAndClamp,
|
|
GAL.StencilOp.Invert or GAL.StencilOp.InvertGl => StencilOp.Invert,
|
|
GAL.StencilOp.IncrementAndWrap or GAL.StencilOp.IncrementAndWrapGl => StencilOp.IncrementAndWrap,
|
|
GAL.StencilOp.DecrementAndWrap or GAL.StencilOp.DecrementAndWrapGl => StencilOp.DecrementAndWrap,
|
|
_ => LogInvalidAndReturn(op, nameof(GAL.StencilOp), StencilOp.Keep),
|
|
};
|
|
}
|
|
|
|
public static ComponentSwizzle Convert(this SwizzleComponent swizzleComponent)
|
|
{
|
|
return swizzleComponent switch
|
|
{
|
|
SwizzleComponent.Zero => ComponentSwizzle.Zero,
|
|
SwizzleComponent.One => ComponentSwizzle.One,
|
|
SwizzleComponent.Red => ComponentSwizzle.R,
|
|
SwizzleComponent.Green => ComponentSwizzle.G,
|
|
SwizzleComponent.Blue => ComponentSwizzle.B,
|
|
SwizzleComponent.Alpha => ComponentSwizzle.A,
|
|
_ => LogInvalidAndReturn(swizzleComponent, nameof(SwizzleComponent), ComponentSwizzle.Zero),
|
|
};
|
|
}
|
|
|
|
public static ImageType Convert(this Target target)
|
|
{
|
|
return target switch
|
|
{
|
|
Target.Texture1D or
|
|
Target.Texture1DArray or
|
|
Target.TextureBuffer => ImageType.Type1D,
|
|
Target.Texture2D or
|
|
Target.Texture2DArray or
|
|
Target.Texture2DMultisample or
|
|
Target.Cubemap or
|
|
Target.CubemapArray => ImageType.Type2D,
|
|
Target.Texture3D => ImageType.Type3D,
|
|
_ => LogInvalidAndReturn(target, nameof(Target), ImageType.Type2D),
|
|
};
|
|
}
|
|
|
|
public static ImageViewType ConvertView(this Target target)
|
|
{
|
|
return target switch
|
|
{
|
|
Target.Texture1D => ImageViewType.Type1D,
|
|
Target.Texture2D or Target.Texture2DMultisample => ImageViewType.Type2D,
|
|
Target.Texture3D => ImageViewType.Type3D,
|
|
Target.Texture1DArray => ImageViewType.Type1DArray,
|
|
Target.Texture2DArray => ImageViewType.Type2DArray,
|
|
Target.Cubemap => ImageViewType.TypeCube,
|
|
Target.CubemapArray => ImageViewType.TypeCubeArray,
|
|
_ => LogInvalidAndReturn(target, nameof(Target), ImageViewType.Type2D),
|
|
};
|
|
}
|
|
|
|
public static ImageAspectFlags ConvertAspectFlags(this Format format)
|
|
{
|
|
return format switch
|
|
{
|
|
Format.D16Unorm or Format.D32Float => ImageAspectFlags.DepthBit,
|
|
Format.S8Uint => ImageAspectFlags.StencilBit,
|
|
Format.D24UnormS8Uint or
|
|
Format.D32FloatS8Uint or
|
|
Format.S8UintD24Unorm => ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit,
|
|
_ => ImageAspectFlags.ColorBit,
|
|
};
|
|
}
|
|
|
|
public static ImageAspectFlags ConvertAspectFlags(this Format format, DepthStencilMode depthStencilMode)
|
|
{
|
|
return format switch
|
|
{
|
|
Format.D16Unorm or Format.D32Float => ImageAspectFlags.DepthBit,
|
|
Format.S8Uint => ImageAspectFlags.StencilBit,
|
|
Format.D24UnormS8Uint or
|
|
Format.D32FloatS8Uint or
|
|
Format.S8UintD24Unorm => depthStencilMode == DepthStencilMode.Stencil ? ImageAspectFlags.StencilBit : ImageAspectFlags.DepthBit,
|
|
_ => ImageAspectFlags.ColorBit,
|
|
};
|
|
}
|
|
|
|
public static LogicOp Convert(this LogicalOp op)
|
|
{
|
|
return op switch
|
|
{
|
|
LogicalOp.Clear => LogicOp.Clear,
|
|
LogicalOp.And => LogicOp.And,
|
|
LogicalOp.AndReverse => LogicOp.AndReverse,
|
|
LogicalOp.Copy => LogicOp.Copy,
|
|
LogicalOp.AndInverted => LogicOp.AndInverted,
|
|
LogicalOp.Noop => LogicOp.NoOp,
|
|
LogicalOp.Xor => LogicOp.Xor,
|
|
LogicalOp.Or => LogicOp.Or,
|
|
LogicalOp.Nor => LogicOp.Nor,
|
|
LogicalOp.Equiv => LogicOp.Equivalent,
|
|
LogicalOp.Invert => LogicOp.Invert,
|
|
LogicalOp.OrReverse => LogicOp.OrReverse,
|
|
LogicalOp.CopyInverted => LogicOp.CopyInverted,
|
|
LogicalOp.OrInverted => LogicOp.OrInverted,
|
|
LogicalOp.Nand => LogicOp.Nand,
|
|
LogicalOp.Set => LogicOp.Set,
|
|
_ => LogInvalidAndReturn(op, nameof(LogicalOp), LogicOp.Copy),
|
|
};
|
|
}
|
|
|
|
public static BufferAllocationType Convert(this BufferAccess access)
|
|
{
|
|
return access switch
|
|
{
|
|
BufferAccess.FlushPersistent => BufferAllocationType.HostMapped,
|
|
BufferAccess.Stream => BufferAllocationType.HostMapped,
|
|
_ => BufferAllocationType.Auto,
|
|
};
|
|
}
|
|
|
|
private static T2 LogInvalidAndReturn<T1, T2>(T1 value, string name, T2 defaultValue = default)
|
|
{
|
|
Logger.Debug?.Print(LogClass.Gpu, $"Invalid {name} enum value: {value}.");
|
|
|
|
return defaultValue;
|
|
}
|
|
}
|
|
}
|