/ src / Ryujinx.Graphics.Vulkan / EnumConversion.cs
EnumConversion.cs
  1  using Ryujinx.Common.Logging;
  2  using Ryujinx.Graphics.GAL;
  3  using Ryujinx.Graphics.Shader;
  4  using Silk.NET.Vulkan;
  5  using System;
  6  using BlendFactor = Silk.NET.Vulkan.BlendFactor;
  7  using BlendOp = Silk.NET.Vulkan.BlendOp;
  8  using CompareOp = Silk.NET.Vulkan.CompareOp;
  9  using Format = Ryujinx.Graphics.GAL.Format;
 10  using FrontFace = Silk.NET.Vulkan.FrontFace;
 11  using IndexType = Silk.NET.Vulkan.IndexType;
 12  using PrimitiveTopology = Silk.NET.Vulkan.PrimitiveTopology;
 13  using StencilOp = Silk.NET.Vulkan.StencilOp;
 14  
 15  namespace Ryujinx.Graphics.Vulkan
 16  {
 17      static class EnumConversion
 18      {
 19          public static ShaderStageFlags Convert(this ShaderStage stage)
 20          {
 21              return stage switch
 22              {
 23                  ShaderStage.Vertex => ShaderStageFlags.VertexBit,
 24                  ShaderStage.Geometry => ShaderStageFlags.GeometryBit,
 25                  ShaderStage.TessellationControl => ShaderStageFlags.TessellationControlBit,
 26                  ShaderStage.TessellationEvaluation => ShaderStageFlags.TessellationEvaluationBit,
 27                  ShaderStage.Fragment => ShaderStageFlags.FragmentBit,
 28                  ShaderStage.Compute => ShaderStageFlags.ComputeBit,
 29                  _ => LogInvalidAndReturn(stage, nameof(ShaderStage), (ShaderStageFlags)0),
 30              };
 31          }
 32  
 33          public static PipelineStageFlags ConvertToPipelineStageFlags(this ShaderStage stage)
 34          {
 35              return stage switch
 36              {
 37                  ShaderStage.Vertex => PipelineStageFlags.VertexShaderBit,
 38                  ShaderStage.Geometry => PipelineStageFlags.GeometryShaderBit,
 39                  ShaderStage.TessellationControl => PipelineStageFlags.TessellationControlShaderBit,
 40                  ShaderStage.TessellationEvaluation => PipelineStageFlags.TessellationEvaluationShaderBit,
 41                  ShaderStage.Fragment => PipelineStageFlags.FragmentShaderBit,
 42                  ShaderStage.Compute => PipelineStageFlags.ComputeShaderBit,
 43                  _ => LogInvalidAndReturn(stage, nameof(ShaderStage), (PipelineStageFlags)0),
 44              };
 45          }
 46  
 47          public static ShaderStageFlags Convert(this ResourceStages stages)
 48          {
 49              ShaderStageFlags stageFlags = stages.HasFlag(ResourceStages.Compute)
 50                  ? ShaderStageFlags.ComputeBit
 51                  : ShaderStageFlags.None;
 52  
 53              if (stages.HasFlag(ResourceStages.Vertex))
 54              {
 55                  stageFlags |= ShaderStageFlags.VertexBit;
 56              }
 57  
 58              if (stages.HasFlag(ResourceStages.TessellationControl))
 59              {
 60                  stageFlags |= ShaderStageFlags.TessellationControlBit;
 61              }
 62  
 63              if (stages.HasFlag(ResourceStages.TessellationEvaluation))
 64              {
 65                  stageFlags |= ShaderStageFlags.TessellationEvaluationBit;
 66              }
 67  
 68              if (stages.HasFlag(ResourceStages.Geometry))
 69              {
 70                  stageFlags |= ShaderStageFlags.GeometryBit;
 71              }
 72  
 73              if (stages.HasFlag(ResourceStages.Fragment))
 74              {
 75                  stageFlags |= ShaderStageFlags.FragmentBit;
 76              }
 77  
 78              return stageFlags;
 79          }
 80  
 81          public static DescriptorType Convert(this ResourceType type)
 82          {
 83              return type switch
 84              {
 85                  ResourceType.UniformBuffer => DescriptorType.UniformBuffer,
 86                  ResourceType.StorageBuffer => DescriptorType.StorageBuffer,
 87                  ResourceType.Texture => DescriptorType.SampledImage,
 88                  ResourceType.Sampler => DescriptorType.Sampler,
 89                  ResourceType.TextureAndSampler => DescriptorType.CombinedImageSampler,
 90                  ResourceType.Image => DescriptorType.StorageImage,
 91                  ResourceType.BufferTexture => DescriptorType.UniformTexelBuffer,
 92                  ResourceType.BufferImage => DescriptorType.StorageTexelBuffer,
 93                  _ => throw new ArgumentException($"Invalid resource type \"{type}\"."),
 94              };
 95          }
 96  
 97          public static SamplerAddressMode Convert(this AddressMode mode)
 98          {
 99              return mode switch
100              {
101                  AddressMode.Clamp => SamplerAddressMode.ClampToEdge, // TODO: Should be clamp.
102                  AddressMode.Repeat => SamplerAddressMode.Repeat,
103                  AddressMode.MirrorClamp => SamplerAddressMode.ClampToEdge, // TODO: Should be mirror clamp.
104                  AddressMode.MirrorClampToEdge => SamplerAddressMode.MirrorClampToEdgeKhr,
105                  AddressMode.MirrorClampToBorder => SamplerAddressMode.ClampToBorder, // TODO: Should be mirror clamp to border.
106                  AddressMode.ClampToBorder => SamplerAddressMode.ClampToBorder,
107                  AddressMode.MirroredRepeat => SamplerAddressMode.MirroredRepeat,
108                  AddressMode.ClampToEdge => SamplerAddressMode.ClampToEdge,
109                  _ => LogInvalidAndReturn(mode, nameof(AddressMode), SamplerAddressMode.ClampToEdge), // TODO: Should be clamp.
110              };
111          }
112  
113          public static BlendFactor Convert(this GAL.BlendFactor factor)
114          {
115              return factor switch
116              {
117                  GAL.BlendFactor.Zero or GAL.BlendFactor.ZeroGl => BlendFactor.Zero,
118                  GAL.BlendFactor.One or GAL.BlendFactor.OneGl => BlendFactor.One,
119                  GAL.BlendFactor.SrcColor or GAL.BlendFactor.SrcColorGl => BlendFactor.SrcColor,
120                  GAL.BlendFactor.OneMinusSrcColor or GAL.BlendFactor.OneMinusSrcColorGl => BlendFactor.OneMinusSrcColor,
121                  GAL.BlendFactor.SrcAlpha or GAL.BlendFactor.SrcAlphaGl => BlendFactor.SrcAlpha,
122                  GAL.BlendFactor.OneMinusSrcAlpha or GAL.BlendFactor.OneMinusSrcAlphaGl => BlendFactor.OneMinusSrcAlpha,
123                  GAL.BlendFactor.DstAlpha or GAL.BlendFactor.DstAlphaGl => BlendFactor.DstAlpha,
124                  GAL.BlendFactor.OneMinusDstAlpha or GAL.BlendFactor.OneMinusDstAlphaGl => BlendFactor.OneMinusDstAlpha,
125                  GAL.BlendFactor.DstColor or GAL.BlendFactor.DstColorGl => BlendFactor.DstColor,
126                  GAL.BlendFactor.OneMinusDstColor or GAL.BlendFactor.OneMinusDstColorGl => BlendFactor.OneMinusDstColor,
127                  GAL.BlendFactor.SrcAlphaSaturate or GAL.BlendFactor.SrcAlphaSaturateGl => BlendFactor.SrcAlphaSaturate,
128                  GAL.BlendFactor.Src1Color or GAL.BlendFactor.Src1ColorGl => BlendFactor.Src1Color,
129                  GAL.BlendFactor.OneMinusSrc1Color or GAL.BlendFactor.OneMinusSrc1ColorGl => BlendFactor.OneMinusSrc1Color,
130                  GAL.BlendFactor.Src1Alpha or GAL.BlendFactor.Src1AlphaGl => BlendFactor.Src1Alpha,
131                  GAL.BlendFactor.OneMinusSrc1Alpha or GAL.BlendFactor.OneMinusSrc1AlphaGl => BlendFactor.OneMinusSrc1Alpha,
132                  GAL.BlendFactor.ConstantColor => BlendFactor.ConstantColor,
133                  GAL.BlendFactor.OneMinusConstantColor => BlendFactor.OneMinusConstantColor,
134                  GAL.BlendFactor.ConstantAlpha => BlendFactor.ConstantAlpha,
135                  GAL.BlendFactor.OneMinusConstantAlpha => BlendFactor.OneMinusConstantAlpha,
136                  _ => LogInvalidAndReturn(factor, nameof(GAL.BlendFactor), BlendFactor.Zero),
137              };
138          }
139  
140          public static BlendOp Convert(this AdvancedBlendOp op)
141          {
142              return op switch
143              {
144                  AdvancedBlendOp.Zero => BlendOp.ZeroExt,
145                  AdvancedBlendOp.Src => BlendOp.SrcExt,
146                  AdvancedBlendOp.Dst => BlendOp.DstExt,
147                  AdvancedBlendOp.SrcOver => BlendOp.SrcOverExt,
148                  AdvancedBlendOp.DstOver => BlendOp.DstOverExt,
149                  AdvancedBlendOp.SrcIn => BlendOp.SrcInExt,
150                  AdvancedBlendOp.DstIn => BlendOp.DstInExt,
151                  AdvancedBlendOp.SrcOut => BlendOp.SrcOutExt,
152                  AdvancedBlendOp.DstOut => BlendOp.DstOutExt,
153                  AdvancedBlendOp.SrcAtop => BlendOp.SrcAtopExt,
154                  AdvancedBlendOp.DstAtop => BlendOp.DstAtopExt,
155                  AdvancedBlendOp.Xor => BlendOp.XorExt,
156                  AdvancedBlendOp.Plus => BlendOp.PlusExt,
157                  AdvancedBlendOp.PlusClamped => BlendOp.PlusClampedExt,
158                  AdvancedBlendOp.PlusClampedAlpha => BlendOp.PlusClampedAlphaExt,
159                  AdvancedBlendOp.PlusDarker => BlendOp.PlusDarkerExt,
160                  AdvancedBlendOp.Multiply => BlendOp.MultiplyExt,
161                  AdvancedBlendOp.Screen => BlendOp.ScreenExt,
162                  AdvancedBlendOp.Overlay => BlendOp.OverlayExt,
163                  AdvancedBlendOp.Darken => BlendOp.DarkenExt,
164                  AdvancedBlendOp.Lighten => BlendOp.LightenExt,
165                  AdvancedBlendOp.ColorDodge => BlendOp.ColordodgeExt,
166                  AdvancedBlendOp.ColorBurn => BlendOp.ColorburnExt,
167                  AdvancedBlendOp.HardLight => BlendOp.HardlightExt,
168                  AdvancedBlendOp.SoftLight => BlendOp.SoftlightExt,
169                  AdvancedBlendOp.Difference => BlendOp.DifferenceExt,
170                  AdvancedBlendOp.Minus => BlendOp.MinusExt,
171                  AdvancedBlendOp.MinusClamped => BlendOp.MinusClampedExt,
172                  AdvancedBlendOp.Exclusion => BlendOp.ExclusionExt,
173                  AdvancedBlendOp.Contrast => BlendOp.ContrastExt,
174                  AdvancedBlendOp.Invert => BlendOp.InvertExt,
175                  AdvancedBlendOp.InvertRGB => BlendOp.InvertRgbExt,
176                  AdvancedBlendOp.InvertOvg => BlendOp.InvertOvgExt,
177                  AdvancedBlendOp.LinearDodge => BlendOp.LineardodgeExt,
178                  AdvancedBlendOp.LinearBurn => BlendOp.LinearburnExt,
179                  AdvancedBlendOp.VividLight => BlendOp.VividlightExt,
180                  AdvancedBlendOp.LinearLight => BlendOp.LinearlightExt,
181                  AdvancedBlendOp.PinLight => BlendOp.PinlightExt,
182                  AdvancedBlendOp.HardMix => BlendOp.HardmixExt,
183                  AdvancedBlendOp.Red => BlendOp.RedExt,
184                  AdvancedBlendOp.Green => BlendOp.GreenExt,
185                  AdvancedBlendOp.Blue => BlendOp.BlueExt,
186                  AdvancedBlendOp.HslHue => BlendOp.HslHueExt,
187                  AdvancedBlendOp.HslSaturation => BlendOp.HslSaturationExt,
188                  AdvancedBlendOp.HslColor => BlendOp.HslColorExt,
189                  AdvancedBlendOp.HslLuminosity => BlendOp.HslLuminosityExt,
190                  _ => LogInvalidAndReturn(op, nameof(AdvancedBlendOp), BlendOp.Add),
191              };
192          }
193  
194          public static BlendOp Convert(this GAL.BlendOp op)
195          {
196              return op switch
197              {
198                  GAL.BlendOp.Add or GAL.BlendOp.AddGl => BlendOp.Add,
199                  GAL.BlendOp.Subtract or GAL.BlendOp.SubtractGl => BlendOp.Subtract,
200                  GAL.BlendOp.ReverseSubtract or GAL.BlendOp.ReverseSubtractGl => BlendOp.ReverseSubtract,
201                  GAL.BlendOp.Minimum or GAL.BlendOp.MinimumGl => BlendOp.Min,
202                  GAL.BlendOp.Maximum or GAL.BlendOp.MaximumGl => BlendOp.Max,
203                  _ => LogInvalidAndReturn(op, nameof(GAL.BlendOp), BlendOp.Add),
204              };
205          }
206  
207          public static BlendOverlapEXT Convert(this AdvancedBlendOverlap overlap)
208          {
209              return overlap switch
210              {
211                  AdvancedBlendOverlap.Uncorrelated => BlendOverlapEXT.UncorrelatedExt,
212                  AdvancedBlendOverlap.Disjoint => BlendOverlapEXT.DisjointExt,
213                  AdvancedBlendOverlap.Conjoint => BlendOverlapEXT.ConjointExt,
214                  _ => LogInvalidAndReturn(overlap, nameof(AdvancedBlendOverlap), BlendOverlapEXT.UncorrelatedExt),
215              };
216          }
217  
218          public static CompareOp Convert(this GAL.CompareOp op)
219          {
220              return op switch
221              {
222                  GAL.CompareOp.Never or GAL.CompareOp.NeverGl => CompareOp.Never,
223                  GAL.CompareOp.Less or GAL.CompareOp.LessGl => CompareOp.Less,
224                  GAL.CompareOp.Equal or GAL.CompareOp.EqualGl => CompareOp.Equal,
225                  GAL.CompareOp.LessOrEqual or GAL.CompareOp.LessOrEqualGl => CompareOp.LessOrEqual,
226                  GAL.CompareOp.Greater or GAL.CompareOp.GreaterGl => CompareOp.Greater,
227                  GAL.CompareOp.NotEqual or GAL.CompareOp.NotEqualGl => CompareOp.NotEqual,
228                  GAL.CompareOp.GreaterOrEqual or GAL.CompareOp.GreaterOrEqualGl => CompareOp.GreaterOrEqual,
229                  GAL.CompareOp.Always or GAL.CompareOp.AlwaysGl => CompareOp.Always,
230                  _ => LogInvalidAndReturn(op, nameof(GAL.CompareOp), CompareOp.Never),
231              };
232          }
233  
234          public static CullModeFlags Convert(this Face face)
235          {
236              return face switch
237              {
238                  Face.Back => CullModeFlags.BackBit,
239                  Face.Front => CullModeFlags.FrontBit,
240                  Face.FrontAndBack => CullModeFlags.FrontAndBack,
241                  _ => LogInvalidAndReturn(face, nameof(Face), CullModeFlags.BackBit),
242              };
243          }
244  
245          public static FrontFace Convert(this GAL.FrontFace frontFace)
246          {
247              // Flipped to account for origin differences.
248              return frontFace switch
249              {
250                  GAL.FrontFace.Clockwise => FrontFace.CounterClockwise,
251                  GAL.FrontFace.CounterClockwise => FrontFace.Clockwise,
252                  _ => LogInvalidAndReturn(frontFace, nameof(GAL.FrontFace), FrontFace.Clockwise),
253              };
254          }
255  
256          public static IndexType Convert(this GAL.IndexType type)
257          {
258              return type switch
259              {
260                  GAL.IndexType.UByte => IndexType.Uint8Ext,
261                  GAL.IndexType.UShort => IndexType.Uint16,
262                  GAL.IndexType.UInt => IndexType.Uint32,
263                  _ => LogInvalidAndReturn(type, nameof(GAL.IndexType), IndexType.Uint16),
264              };
265          }
266  
267          public static Filter Convert(this MagFilter filter)
268          {
269              return filter switch
270              {
271                  MagFilter.Nearest => Filter.Nearest,
272                  MagFilter.Linear => Filter.Linear,
273                  _ => LogInvalidAndReturn(filter, nameof(MagFilter), Filter.Nearest),
274              };
275          }
276  
277          public static (Filter, SamplerMipmapMode) Convert(this MinFilter filter)
278          {
279              return filter switch
280              {
281                  MinFilter.Nearest => (Filter.Nearest, SamplerMipmapMode.Nearest),
282                  MinFilter.Linear => (Filter.Linear, SamplerMipmapMode.Nearest),
283                  MinFilter.NearestMipmapNearest => (Filter.Nearest, SamplerMipmapMode.Nearest),
284                  MinFilter.LinearMipmapNearest => (Filter.Linear, SamplerMipmapMode.Nearest),
285                  MinFilter.NearestMipmapLinear => (Filter.Nearest, SamplerMipmapMode.Linear),
286                  MinFilter.LinearMipmapLinear => (Filter.Linear, SamplerMipmapMode.Linear),
287                  _ => LogInvalidAndReturn(filter, nameof(MinFilter), (Filter.Nearest, SamplerMipmapMode.Nearest)),
288              };
289          }
290  
291          public static PrimitiveTopology Convert(this GAL.PrimitiveTopology topology)
292          {
293              return topology switch
294              {
295                  GAL.PrimitiveTopology.Points => PrimitiveTopology.PointList,
296                  GAL.PrimitiveTopology.Lines => PrimitiveTopology.LineList,
297                  GAL.PrimitiveTopology.LineStrip => PrimitiveTopology.LineStrip,
298                  GAL.PrimitiveTopology.Triangles => PrimitiveTopology.TriangleList,
299                  GAL.PrimitiveTopology.TriangleStrip => PrimitiveTopology.TriangleStrip,
300                  GAL.PrimitiveTopology.TriangleFan => PrimitiveTopology.TriangleFan,
301                  GAL.PrimitiveTopology.LinesAdjacency => PrimitiveTopology.LineListWithAdjacency,
302                  GAL.PrimitiveTopology.LineStripAdjacency => PrimitiveTopology.LineStripWithAdjacency,
303                  GAL.PrimitiveTopology.TrianglesAdjacency => PrimitiveTopology.TriangleListWithAdjacency,
304                  GAL.PrimitiveTopology.TriangleStripAdjacency => PrimitiveTopology.TriangleStripWithAdjacency,
305                  GAL.PrimitiveTopology.Patches => PrimitiveTopology.PatchList,
306                  GAL.PrimitiveTopology.Polygon => PrimitiveTopology.TriangleFan,
307                  GAL.PrimitiveTopology.Quads => throw new NotSupportedException("Quad topology is not available in Vulkan."),
308                  GAL.PrimitiveTopology.QuadStrip => throw new NotSupportedException("QuadStrip topology is not available in Vulkan."),
309                  _ => LogInvalidAndReturn(topology, nameof(GAL.PrimitiveTopology), PrimitiveTopology.TriangleList),
310              };
311          }
312  
313          public static StencilOp Convert(this GAL.StencilOp op)
314          {
315              return op switch
316              {
317                  GAL.StencilOp.Keep or GAL.StencilOp.KeepGl => StencilOp.Keep,
318                  GAL.StencilOp.Zero or GAL.StencilOp.ZeroGl => StencilOp.Zero,
319                  GAL.StencilOp.Replace or GAL.StencilOp.ReplaceGl => StencilOp.Replace,
320                  GAL.StencilOp.IncrementAndClamp or GAL.StencilOp.IncrementAndClampGl => StencilOp.IncrementAndClamp,
321                  GAL.StencilOp.DecrementAndClamp or GAL.StencilOp.DecrementAndClampGl => StencilOp.DecrementAndClamp,
322                  GAL.StencilOp.Invert or GAL.StencilOp.InvertGl => StencilOp.Invert,
323                  GAL.StencilOp.IncrementAndWrap or GAL.StencilOp.IncrementAndWrapGl => StencilOp.IncrementAndWrap,
324                  GAL.StencilOp.DecrementAndWrap or GAL.StencilOp.DecrementAndWrapGl => StencilOp.DecrementAndWrap,
325                  _ => LogInvalidAndReturn(op, nameof(GAL.StencilOp), StencilOp.Keep),
326              };
327          }
328  
329          public static ComponentSwizzle Convert(this SwizzleComponent swizzleComponent)
330          {
331              return swizzleComponent switch
332              {
333                  SwizzleComponent.Zero => ComponentSwizzle.Zero,
334                  SwizzleComponent.One => ComponentSwizzle.One,
335                  SwizzleComponent.Red => ComponentSwizzle.R,
336                  SwizzleComponent.Green => ComponentSwizzle.G,
337                  SwizzleComponent.Blue => ComponentSwizzle.B,
338                  SwizzleComponent.Alpha => ComponentSwizzle.A,
339                  _ => LogInvalidAndReturn(swizzleComponent, nameof(SwizzleComponent), ComponentSwizzle.Zero),
340              };
341          }
342  
343          public static ImageType Convert(this Target target)
344          {
345              return target switch
346              {
347                  Target.Texture1D or
348                  Target.Texture1DArray or
349                  Target.TextureBuffer => ImageType.Type1D,
350                  Target.Texture2D or
351                  Target.Texture2DArray or
352                  Target.Texture2DMultisample or
353                  Target.Cubemap or
354                  Target.CubemapArray => ImageType.Type2D,
355                  Target.Texture3D => ImageType.Type3D,
356                  _ => LogInvalidAndReturn(target, nameof(Target), ImageType.Type2D),
357              };
358          }
359  
360          public static ImageViewType ConvertView(this Target target)
361          {
362              return target switch
363              {
364                  Target.Texture1D => ImageViewType.Type1D,
365                  Target.Texture2D or Target.Texture2DMultisample => ImageViewType.Type2D,
366                  Target.Texture3D => ImageViewType.Type3D,
367                  Target.Texture1DArray => ImageViewType.Type1DArray,
368                  Target.Texture2DArray => ImageViewType.Type2DArray,
369                  Target.Cubemap => ImageViewType.TypeCube,
370                  Target.CubemapArray => ImageViewType.TypeCubeArray,
371                  _ => LogInvalidAndReturn(target, nameof(Target), ImageViewType.Type2D),
372              };
373          }
374  
375          public static ImageAspectFlags ConvertAspectFlags(this Format format)
376          {
377              return format switch
378              {
379                  Format.D16Unorm or Format.D32Float or Format.X8UintD24Unorm => ImageAspectFlags.DepthBit,
380                  Format.S8Uint => ImageAspectFlags.StencilBit,
381                  Format.D24UnormS8Uint or
382                  Format.D32FloatS8Uint or
383                  Format.S8UintD24Unorm => ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit,
384                  _ => ImageAspectFlags.ColorBit,
385              };
386          }
387  
388          public static ImageAspectFlags ConvertAspectFlags(this Format format, DepthStencilMode depthStencilMode)
389          {
390              return format switch
391              {
392                  Format.D16Unorm or Format.D32Float or Format.X8UintD24Unorm => ImageAspectFlags.DepthBit,
393                  Format.S8Uint => ImageAspectFlags.StencilBit,
394                  Format.D24UnormS8Uint or
395                  Format.D32FloatS8Uint or
396                  Format.S8UintD24Unorm => depthStencilMode == DepthStencilMode.Stencil ? ImageAspectFlags.StencilBit : ImageAspectFlags.DepthBit,
397                  _ => ImageAspectFlags.ColorBit,
398              };
399          }
400  
401          public static LogicOp Convert(this LogicalOp op)
402          {
403              return op switch
404              {
405                  LogicalOp.Clear => LogicOp.Clear,
406                  LogicalOp.And => LogicOp.And,
407                  LogicalOp.AndReverse => LogicOp.AndReverse,
408                  LogicalOp.Copy => LogicOp.Copy,
409                  LogicalOp.AndInverted => LogicOp.AndInverted,
410                  LogicalOp.Noop => LogicOp.NoOp,
411                  LogicalOp.Xor => LogicOp.Xor,
412                  LogicalOp.Or => LogicOp.Or,
413                  LogicalOp.Nor => LogicOp.Nor,
414                  LogicalOp.Equiv => LogicOp.Equivalent,
415                  LogicalOp.Invert => LogicOp.Invert,
416                  LogicalOp.OrReverse => LogicOp.OrReverse,
417                  LogicalOp.CopyInverted => LogicOp.CopyInverted,
418                  LogicalOp.OrInverted => LogicOp.OrInverted,
419                  LogicalOp.Nand => LogicOp.Nand,
420                  LogicalOp.Set => LogicOp.Set,
421                  _ => LogInvalidAndReturn(op, nameof(LogicalOp), LogicOp.Copy),
422              };
423          }
424  
425          public static BufferAllocationType Convert(this BufferAccess access)
426          {
427              BufferAccess memType = access & BufferAccess.MemoryTypeMask;
428  
429              if (memType == BufferAccess.HostMemory || access.HasFlag(BufferAccess.Stream))
430              {
431                  return BufferAllocationType.HostMapped;
432              }
433              else if (memType == BufferAccess.DeviceMemory)
434              {
435                  return BufferAllocationType.DeviceLocal;
436              }
437              else if (memType == BufferAccess.DeviceMemoryMapped)
438              {
439                  return BufferAllocationType.DeviceLocalMapped;
440              }
441  
442              return BufferAllocationType.Auto;
443          }
444  
445          private static T2 LogInvalidAndReturn<T1, T2>(T1 value, string name, T2 defaultValue = default)
446          {
447              Logger.Debug?.Print(LogClass.Gpu, $"Invalid {name} enum value: {value}.");
448  
449              return defaultValue;
450          }
451      }
452  }