struct and enum conversions
							parent
							
								
									8b35b6b0b7
								
							
						
					
					
						commit
						4e8653fb1f
					
				|  | @ -1 +1 @@ | ||||||
| Subproject commit b3cf918f900a24d131b4eb130a87dd12b4e4ca8c | Subproject commit 2866dd2a7d4ffd4366bd4885e04c68cf4b485b55 | ||||||
|  | @ -21,7 +21,7 @@ namespace MoonWorks | ||||||
| 			{ VertexElementFormat.NormalizedShort4, (uint) Marshal.SizeOf<NormalizedShort4>() }, | 			{ VertexElementFormat.NormalizedShort4, (uint) Marshal.SizeOf<NormalizedShort4>() }, | ||||||
| 			{ VertexElementFormat.Short2, (uint) Marshal.SizeOf<Short2>() }, | 			{ VertexElementFormat.Short2, (uint) Marshal.SizeOf<Short2>() }, | ||||||
| 			{ VertexElementFormat.Short4, (uint) Marshal.SizeOf<Short4>() }, | 			{ VertexElementFormat.Short4, (uint) Marshal.SizeOf<Short4>() }, | ||||||
| 			{ VertexElementFormat.UInt, (uint) Marshal.SizeOf<uint>() }, | 			{ VertexElementFormat.Uint, (uint) Marshal.SizeOf<uint>() }, | ||||||
| 			{ VertexElementFormat.Vector2, (uint) Marshal.SizeOf<Math.Float.Vector2>() }, | 			{ VertexElementFormat.Vector2, (uint) Marshal.SizeOf<Math.Float.Vector2>() }, | ||||||
| 			{ VertexElementFormat.Vector3, (uint) Marshal.SizeOf<Math.Float.Vector3>() }, | 			{ VertexElementFormat.Vector3, (uint) Marshal.SizeOf<Math.Float.Vector3>() }, | ||||||
| 			{ VertexElementFormat.Vector4, (uint) Marshal.SizeOf<Math.Float.Vector4>() } | 			{ VertexElementFormat.Vector4, (uint) Marshal.SizeOf<Math.Float.Vector4>() } | ||||||
|  | @ -37,6 +37,16 @@ namespace MoonWorks | ||||||
| 			return b != 0; | 			return b != 0; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		public static int BoolToInt(bool b) | ||||||
|  | 		{ | ||||||
|  | 			return b ? 1 : 0; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		public static bool IntToBool(int b) | ||||||
|  | 		{ | ||||||
|  | 			return b != 0; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		public static uint VertexElementFormatSize(VertexElementFormat format) | 		public static uint VertexElementFormatSize(VertexElementFormat format) | ||||||
| 		{ | 		{ | ||||||
| 			return Sizes[format]; | 			return Sizes[format]; | ||||||
|  |  | ||||||
|  | @ -1,326 +0,0 @@ | ||||||
| using System; |  | ||||||
| 
 |  | ||||||
| namespace MoonWorks |  | ||||||
| { |  | ||||||
| 	/// <summary> |  | ||||||
| 	/// Presentation mode for a window. |  | ||||||
| 	/// </summary> |  | ||||||
| 	public enum PresentMode |  | ||||||
| 	{ |  | ||||||
| 		/// <summary> |  | ||||||
| 		/// Does not wait for v-blank to update the window. Can cause visible tearing. |  | ||||||
| 		/// </summary> |  | ||||||
| 		Immediate, |  | ||||||
| 		/// <summary> |  | ||||||
| 		/// Waits for v-blank and uses a queue to hold present requests. |  | ||||||
| 		/// Allows for low latency while preventing tearing. |  | ||||||
| 		/// May not be supported on non-Vulkan non-Linux systems or older hardware. |  | ||||||
| 		/// </summary> |  | ||||||
| 		Mailbox, |  | ||||||
| 		/// <summary> |  | ||||||
| 		/// Waits for v-blank and adds present requests to a queue. |  | ||||||
| 		/// Will probably cause latency. |  | ||||||
| 		/// Required to be supported by all compliant hardware. |  | ||||||
| 		/// </summary> |  | ||||||
| 		FIFO, |  | ||||||
| 		/// <summary> |  | ||||||
| 		/// Usually waits for v-blank, but if v-blank has passed since last update will update immediately. |  | ||||||
| 		/// May cause visible tearing. |  | ||||||
| 		/// </summary> |  | ||||||
| 		FIFORelaxed |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* Recreate all the enums in here so we don't need to explicitly |  | ||||||
|  * reference the RefreshCS namespace when using MoonWorks.Graphics |  | ||||||
|  */ |  | ||||||
| namespace MoonWorks.Graphics |  | ||||||
| { |  | ||||||
| 	public enum PrimitiveType |  | ||||||
| 	{ |  | ||||||
| 		PointList, |  | ||||||
| 		LineList, |  | ||||||
| 		LineStrip, |  | ||||||
| 		TriangleList, |  | ||||||
| 		TriangleStrip |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/// <summary> |  | ||||||
| 	/// Describes the operation that a render pass will use when loading a render target. |  | ||||||
| 	/// </summary> |  | ||||||
| 	public enum LoadOp |  | ||||||
| 	{ |  | ||||||
| 		Load, |  | ||||||
| 		Clear, |  | ||||||
| 		DontCare |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/// <summary> |  | ||||||
| 	/// Describes the operation that a render pass will use when storing a render target. |  | ||||||
| 	/// </summary> |  | ||||||
| 	public enum StoreOp |  | ||||||
| 	{ |  | ||||||
| 		Store, |  | ||||||
| 		DontCare |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	[Flags] |  | ||||||
| 	public enum ClearOptionsFlags : uint |  | ||||||
| 	{ |  | ||||||
| 		Color = 1, |  | ||||||
| 		Depth = 2, |  | ||||||
| 		Stencil = 4, |  | ||||||
| 		DepthStencil = Depth | Stencil, |  | ||||||
| 		All = Color | Depth | Stencil |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum IndexElementSize |  | ||||||
| 	{ |  | ||||||
| 		Sixteen, |  | ||||||
| 		ThirtyTwo |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum TextureFormat |  | ||||||
| 	{ |  | ||||||
| 		R8G8B8A8, |  | ||||||
| 		B8G8R8A8, |  | ||||||
| 		R5G6B5, |  | ||||||
| 		A1R5G5B5, |  | ||||||
| 		B4G4R4A4, |  | ||||||
| 		A2R10G10B10, |  | ||||||
| 		R16G16, |  | ||||||
| 		R16G16B16A16, |  | ||||||
| 		R8, |  | ||||||
| 		BC1, |  | ||||||
| 		BC2, |  | ||||||
| 		BC3, |  | ||||||
| 		BC7, |  | ||||||
| 		R8G8_SNORM, |  | ||||||
| 		R8G8B8A8_SNORM, |  | ||||||
| 		R16_SFLOAT, |  | ||||||
| 		R16G16_SFLOAT, |  | ||||||
| 		R16G16B16A16_SFLOAT, |  | ||||||
| 		R32_SFLOAT, |  | ||||||
| 		R32G32_SFLOAT, |  | ||||||
| 		R32G32B32A32_SFLOAT, |  | ||||||
| 
 |  | ||||||
| 		R8_UINT, |  | ||||||
| 		R8G8_UINT, |  | ||||||
| 		R8G8B8A8_UINT, |  | ||||||
| 		R16_UINT, |  | ||||||
| 		R16G16_UINT, |  | ||||||
| 		R16G16B16A16_UINT, |  | ||||||
| 		D16, |  | ||||||
| 		D32, |  | ||||||
| 		D16S8, |  | ||||||
| 		D32S8 |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	[Flags] |  | ||||||
| 	public enum TextureUsageFlags : uint |  | ||||||
| 	{ |  | ||||||
| 		Sampler = 1, |  | ||||||
| 		ColorTarget = 2, |  | ||||||
| 		DepthStencilTarget = 4, |  | ||||||
| 		Compute = 8 |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum SampleCount |  | ||||||
| 	{ |  | ||||||
| 		One, |  | ||||||
| 		Two, |  | ||||||
| 		Four, |  | ||||||
| 		Eight |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum CubeMapFace : uint |  | ||||||
| 	{ |  | ||||||
| 		PositiveX, |  | ||||||
| 		NegativeX, |  | ||||||
| 		PositiveY, |  | ||||||
| 		NegativeY, |  | ||||||
| 		PositiveZ, |  | ||||||
| 		NegativeZ |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	[Flags] |  | ||||||
| 	public enum BufferUsageFlags : uint |  | ||||||
| 	{ |  | ||||||
| 		Vertex = 1, |  | ||||||
| 		Index = 2, |  | ||||||
| 		Compute = 4, |  | ||||||
| 		Indirect = 8 |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum VertexElementFormat |  | ||||||
| 	{ |  | ||||||
| 		UInt, |  | ||||||
| 		Float, |  | ||||||
| 		Vector2, |  | ||||||
| 		Vector3, |  | ||||||
| 		Vector4, |  | ||||||
| 		Color, |  | ||||||
| 		Byte4, |  | ||||||
| 		Short2, |  | ||||||
| 		Short4, |  | ||||||
| 		NormalizedShort2, |  | ||||||
| 		NormalizedShort4, |  | ||||||
| 		HalfVector2, |  | ||||||
| 		HalfVector4 |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum VertexInputRate |  | ||||||
| 	{ |  | ||||||
| 		Vertex, |  | ||||||
| 		Instance |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum FillMode |  | ||||||
| 	{ |  | ||||||
| 		Fill, |  | ||||||
| 		Line |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum CullMode |  | ||||||
| 	{ |  | ||||||
| 		None, |  | ||||||
| 		Front, |  | ||||||
| 		Back |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum FrontFace |  | ||||||
| 	{ |  | ||||||
| 		CounterClockwise, |  | ||||||
| 		Clockwise |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum CompareOp |  | ||||||
| 	{ |  | ||||||
| 		Never, |  | ||||||
| 		Less, |  | ||||||
| 		Equal, |  | ||||||
| 		LessOrEqual, |  | ||||||
| 		Greater, |  | ||||||
| 		NotEqual, |  | ||||||
| 		GreaterOrEqual, |  | ||||||
| 		Always |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum StencilOp |  | ||||||
| 	{ |  | ||||||
| 		Keep, |  | ||||||
| 		Zero, |  | ||||||
| 		Replace, |  | ||||||
| 		IncrementAndClamp, |  | ||||||
| 		DecrementAndClamp, |  | ||||||
| 		Invert, |  | ||||||
| 		IncrementAndWrap, |  | ||||||
| 		DecrementAndWrap |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum BlendOp |  | ||||||
| 	{ |  | ||||||
| 		Add, |  | ||||||
| 		Subtract, |  | ||||||
| 		ReverseSubtract, |  | ||||||
| 		Min, |  | ||||||
| 		Max |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum BlendFactor |  | ||||||
| 	{ |  | ||||||
| 		Zero, |  | ||||||
| 		One, |  | ||||||
| 		SourceColor, |  | ||||||
| 		OneMinusSourceColor, |  | ||||||
| 		DestinationColor, |  | ||||||
| 		OneMinusDestinationColor, |  | ||||||
| 		SourceAlpha, |  | ||||||
| 		OneMinusSourceAlpha, |  | ||||||
| 		DestinationAlpha, |  | ||||||
| 		OneMinusDestinationAlpha, |  | ||||||
| 		ConstantColor, |  | ||||||
| 		OneMinusConstantColor, |  | ||||||
| 		SourceAlphaSaturate |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	[Flags] |  | ||||||
| 	public enum ColorComponentFlags : uint |  | ||||||
| 	{ |  | ||||||
| 		R = 1, |  | ||||||
| 		G = 2, |  | ||||||
| 		B = 4, |  | ||||||
| 		A = 8, |  | ||||||
| 
 |  | ||||||
| 		RG = R | G, |  | ||||||
| 		RB = R | B, |  | ||||||
| 		RA = R | A, |  | ||||||
| 		GB = G | B, |  | ||||||
| 		GA = G | A, |  | ||||||
| 		BA = B | A, |  | ||||||
| 
 |  | ||||||
| 		RGB = R | G | B, |  | ||||||
| 		RGA = R | G | A, |  | ||||||
| 		GBA = G | B | A, |  | ||||||
| 
 |  | ||||||
| 		RGBA = R | G | B | A, |  | ||||||
| 		None = 0 |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum Filter |  | ||||||
| 	{ |  | ||||||
| 		Nearest, |  | ||||||
| 		Linear |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum SamplerMipmapMode |  | ||||||
| 	{ |  | ||||||
| 		Nearest, |  | ||||||
| 		Linear |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum SamplerAddressMode |  | ||||||
| 	{ |  | ||||||
| 		Repeat, |  | ||||||
| 		MirroredRepeat, |  | ||||||
| 		ClampToEdge, |  | ||||||
| 		ClampToBorder |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum BorderColor |  | ||||||
| 	{ |  | ||||||
| 		FloatTransparentBlack, |  | ||||||
| 		IntTransparentBlack, |  | ||||||
| 		FloatOpaqueBlack, |  | ||||||
| 		IntOpaqueBlack, |  | ||||||
| 		FloatOpaqueWhite, |  | ||||||
| 		IntOpaqueWhite |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum TransferUsage |  | ||||||
| 	{ |  | ||||||
| 		Buffer, |  | ||||||
| 		Texture |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum TransferOptions |  | ||||||
| 	{ |  | ||||||
| 		Cycle, |  | ||||||
| 		Unsafe |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum WriteOptions |  | ||||||
| 	{ |  | ||||||
| 		Cycle, |  | ||||||
| 		Unsafe, |  | ||||||
| 		Safe |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	public enum Backend |  | ||||||
| 	{ |  | ||||||
| 		Vulkan, |  | ||||||
| 		D3D11, |  | ||||||
| 		PS5, |  | ||||||
| 		Invalid |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  | @ -1,508 +0,0 @@ | ||||||
| using RefreshCS; |  | ||||||
| using System.Runtime.InteropServices; |  | ||||||
| 
 |  | ||||||
| /* Recreate some structs in here so we don't need to explicitly |  | ||||||
|  * reference the RefreshCS namespace when using MoonWorks.Graphics |  | ||||||
|  */ |  | ||||||
| namespace MoonWorks.Graphics |  | ||||||
| { |  | ||||||
| 	[StructLayout(LayoutKind.Sequential)] |  | ||||||
| 	public struct DepthStencilValue |  | ||||||
| 	{ |  | ||||||
| 		public float Depth; |  | ||||||
| 		public uint Stencil; |  | ||||||
| 
 |  | ||||||
| 		public DepthStencilValue(float depth, uint stencil) |  | ||||||
| 		{ |  | ||||||
| 			Depth = depth; |  | ||||||
| 			Stencil = stencil; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		// FIXME: can we do an unsafe cast somehow? |  | ||||||
| 		public Refresh.DepthStencilValue ToRefresh() |  | ||||||
| 		{ |  | ||||||
| 			return new Refresh.DepthStencilValue |  | ||||||
| 			{ |  | ||||||
| 				depth = Depth, |  | ||||||
| 				stencil = Stencil |  | ||||||
| 			}; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	[StructLayout(LayoutKind.Sequential)] |  | ||||||
| 	public struct Rect |  | ||||||
| 	{ |  | ||||||
| 		public int X; |  | ||||||
| 		public int Y; |  | ||||||
| 		public int W; |  | ||||||
| 		public int H; |  | ||||||
| 
 |  | ||||||
| 		public Rect(int x, int y, int w, int h) |  | ||||||
| 		{ |  | ||||||
| 			X = x; |  | ||||||
| 			Y = y; |  | ||||||
| 			W = w; |  | ||||||
| 			H = h; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public Rect(int w, int h) |  | ||||||
| 		{ |  | ||||||
| 			X = 0; |  | ||||||
| 			Y = 0; |  | ||||||
| 			W = w; |  | ||||||
| 			H = h; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		// FIXME: can we do an unsafe cast somehow? |  | ||||||
| 		public Refresh.Rect ToRefresh() |  | ||||||
| 		{ |  | ||||||
| 			return new Refresh.Rect |  | ||||||
| 			{ |  | ||||||
| 				x = X, |  | ||||||
| 				y = Y, |  | ||||||
| 				w = W, |  | ||||||
| 				h = H |  | ||||||
| 			}; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	[StructLayout(LayoutKind.Sequential)] |  | ||||||
| 	public struct Viewport |  | ||||||
| 	{ |  | ||||||
| 		public float X; |  | ||||||
| 		public float Y; |  | ||||||
| 		public float W; |  | ||||||
| 		public float H; |  | ||||||
| 		public float MinDepth; |  | ||||||
| 		public float MaxDepth; |  | ||||||
| 
 |  | ||||||
| 		public Viewport(float w, float h) |  | ||||||
| 		{ |  | ||||||
| 			X = 0; |  | ||||||
| 			Y = 0; |  | ||||||
| 			W = w; |  | ||||||
| 			H = h; |  | ||||||
| 			MinDepth = 0; |  | ||||||
| 			MaxDepth = 1; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public Viewport(float x, float y, float w, float h) |  | ||||||
| 		{ |  | ||||||
| 			X = x; |  | ||||||
| 			Y = y; |  | ||||||
| 			W = w; |  | ||||||
| 			H = h; |  | ||||||
| 			MinDepth = 0; |  | ||||||
| 			MaxDepth = 1; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public Viewport(float x, float y, float w, float h, float minDepth, float maxDepth) |  | ||||||
| 		{ |  | ||||||
| 			X = x; |  | ||||||
| 			Y = y; |  | ||||||
| 			W = w; |  | ||||||
| 			H = h; |  | ||||||
| 			MinDepth = minDepth; |  | ||||||
| 			MaxDepth = maxDepth; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public Refresh.Viewport ToRefresh() |  | ||||||
| 		{ |  | ||||||
| 			return new Refresh.Viewport |  | ||||||
| 			{ |  | ||||||
| 				x = X, |  | ||||||
| 				y = Y, |  | ||||||
| 				w = W, |  | ||||||
| 				h = H, |  | ||||||
| 				minDepth = MinDepth, |  | ||||||
| 				maxDepth = MaxDepth |  | ||||||
| 			}; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	[StructLayout(LayoutKind.Sequential)] |  | ||||||
| 	public struct VertexBinding |  | ||||||
| 	{ |  | ||||||
| 		public uint Binding; |  | ||||||
| 		public uint Stride; |  | ||||||
| 		public VertexInputRate InputRate; |  | ||||||
| 
 |  | ||||||
| 		public static VertexBinding Create<T>(uint binding = 0, VertexInputRate inputRate = VertexInputRate.Vertex) where T : unmanaged |  | ||||||
| 		{ |  | ||||||
| 			return new VertexBinding |  | ||||||
| 			{ |  | ||||||
| 				Binding = binding, |  | ||||||
| 				InputRate = inputRate, |  | ||||||
| 				Stride = (uint) Marshal.SizeOf<T>() |  | ||||||
| 			}; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	[StructLayout(LayoutKind.Sequential)] |  | ||||||
| 	public struct VertexAttribute |  | ||||||
| 	{ |  | ||||||
| 		public uint Location; |  | ||||||
| 		public uint Binding; |  | ||||||
| 		public VertexElementFormat Format; |  | ||||||
| 		public uint Offset; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	[StructLayout(LayoutKind.Sequential)] |  | ||||||
| 	public struct StencilOpState |  | ||||||
| 	{ |  | ||||||
| 		public StencilOp FailOp; |  | ||||||
| 		public StencilOp PassOp; |  | ||||||
| 		public StencilOp DepthFailOp; |  | ||||||
| 		public CompareOp CompareOp; |  | ||||||
| 
 |  | ||||||
| 		public Refresh.StencilOpState ToRefresh() |  | ||||||
| 		{ |  | ||||||
| 			return new Refresh.StencilOpState |  | ||||||
| 			{ |  | ||||||
| 				failOp = (Refresh.StencilOp) FailOp, |  | ||||||
| 				passOp = (Refresh.StencilOp) PassOp, |  | ||||||
| 				depthFailOp = (Refresh.StencilOp) DepthFailOp, |  | ||||||
| 				compareOp = (Refresh.CompareOp) CompareOp |  | ||||||
| 			}; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/// <summary> |  | ||||||
| 	/// Determines how a color texture will be read/written in a render pass. |  | ||||||
| 	/// </summary> |  | ||||||
| 	public struct ColorAttachmentInfo |  | ||||||
| 	{ |  | ||||||
| 		public TextureSlice TextureSlice; |  | ||||||
| 
 |  | ||||||
| 		/// <summary> |  | ||||||
| 		/// If LoadOp is set to Clear, the texture slice will be cleared to this color. |  | ||||||
| 		/// </summary> |  | ||||||
| 		public Color ClearColor; |  | ||||||
| 
 |  | ||||||
| 		/// <summary> |  | ||||||
| 		/// Determines what is done with the texture slice memory |  | ||||||
| 		/// at the beginning of the render pass. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   Load: |  | ||||||
| 		///     Loads the data currently in the texture slice. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   Clear: |  | ||||||
| 		///     Clears the texture slice to a single color. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   DontCare: |  | ||||||
| 		///     The driver will do whatever it wants with the texture slice data. |  | ||||||
| 		///     This is a good option if you know that every single pixel will be written in the render pass. |  | ||||||
| 		/// </summary> |  | ||||||
| 		public LoadOp LoadOp; |  | ||||||
| 
 |  | ||||||
| 		/// <summary> |  | ||||||
| 		/// Determines what is done with the texture slice memory |  | ||||||
| 		/// at the end of the render pass. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   Store: |  | ||||||
| 		///     Stores the results of the render pass in the texture slice memory. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   DontCare: |  | ||||||
| 		///     The driver will do whatever it wants with the texture slice memory. |  | ||||||
| 		/// </summary> |  | ||||||
| 		public StoreOp StoreOp; |  | ||||||
| 
 |  | ||||||
| 		/// <summary> |  | ||||||
| 		/// Specifies data dependency behavior. This option is ignored if LoadOp is Load. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   Cycle: |  | ||||||
| 		///     If this texture slice has been used in commands that have not completed, |  | ||||||
| 		///     the implementation may prevent a dependency on those commands |  | ||||||
| 		///     at the cost of increased memory usage. |  | ||||||
| 		///     You may NOT assume that any of the previous texture (not slice!) data is retained. |  | ||||||
| 		///     This may prevent stalls when frequently reusing a texture slice in rendering. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   SafeOverwrite: |  | ||||||
| 		///     Overwrites the data safely using a GPU memory barrier. |  | ||||||
| 		/// </summary> |  | ||||||
| 		public WriteOptions WriteOption; |  | ||||||
| 
 |  | ||||||
| 		public ColorAttachmentInfo( |  | ||||||
| 			TextureSlice textureSlice, |  | ||||||
| 			WriteOptions writeOption, |  | ||||||
| 			Color clearColor, |  | ||||||
| 			StoreOp storeOp = StoreOp.Store |  | ||||||
| 		) { |  | ||||||
| 			TextureSlice = textureSlice; |  | ||||||
| 			ClearColor = clearColor; |  | ||||||
| 			LoadOp = LoadOp.Clear; |  | ||||||
| 			StoreOp = storeOp; |  | ||||||
| 			WriteOption = writeOption; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public ColorAttachmentInfo( |  | ||||||
| 			TextureSlice textureSlice, |  | ||||||
| 			WriteOptions writeOption, |  | ||||||
| 			LoadOp loadOp = LoadOp.DontCare, |  | ||||||
| 			StoreOp storeOp = StoreOp.Store |  | ||||||
| 		) { |  | ||||||
| 			TextureSlice = textureSlice; |  | ||||||
| 			ClearColor = Color.White; |  | ||||||
| 			LoadOp = loadOp; |  | ||||||
| 			StoreOp = storeOp; |  | ||||||
| 			WriteOption = writeOption; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public Refresh.ColorAttachmentInfo ToRefresh() |  | ||||||
| 		{ |  | ||||||
| 			return new Refresh.ColorAttachmentInfo |  | ||||||
| 			{ |  | ||||||
| 				textureSlice = TextureSlice.ToRefreshTextureSlice(), |  | ||||||
| 				clearColor = new Refresh.Vec4 |  | ||||||
| 				{ |  | ||||||
| 					x = ClearColor.R / 255f, |  | ||||||
| 					y = ClearColor.G / 255f, |  | ||||||
| 					z = ClearColor.B / 255f, |  | ||||||
| 					w = ClearColor.A / 255f |  | ||||||
| 				}, |  | ||||||
| 				loadOp = (Refresh.LoadOp) LoadOp, |  | ||||||
| 				storeOp = (Refresh.StoreOp) StoreOp, |  | ||||||
| 				writeOption = (Refresh.WriteOptions) WriteOption |  | ||||||
| 			}; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/// <summary> |  | ||||||
| 	/// Determines how a depth/stencil texture will be read/written in a render pass. |  | ||||||
| 	/// </summary> |  | ||||||
| 	public struct DepthStencilAttachmentInfo |  | ||||||
| 	{ |  | ||||||
| 		public TextureSlice TextureSlice; |  | ||||||
| 
 |  | ||||||
| 		/// <summary> |  | ||||||
| 		/// If LoadOp is set to Clear, the texture slice depth will be cleared to this depth value. <br/> |  | ||||||
| 		/// If StencilLoadOp is set to Clear, the texture slice stencil value will be cleared to this stencil value. |  | ||||||
| 		/// </summary> |  | ||||||
| 		public DepthStencilValue DepthStencilClearValue; |  | ||||||
| 
 |  | ||||||
| 		/// <summary> |  | ||||||
| 		/// Determines what is done with the texture slice depth values |  | ||||||
| 		/// at the beginning of the render pass. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   Load: |  | ||||||
| 		///     Loads the data currently in the texture slice. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   Clear: |  | ||||||
| 		///     Clears the texture slice to a single depth value. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   DontCare: |  | ||||||
| 		///     The driver will do whatever it wants with the texture slice data. |  | ||||||
| 		///     This is a good option if you know that every single pixel will be written in the render pass. |  | ||||||
| 		/// </summary> |  | ||||||
| 		public LoadOp LoadOp; |  | ||||||
| 
 |  | ||||||
| 		/// <summary> |  | ||||||
| 		/// Determines what is done with the texture slice depth values |  | ||||||
| 		/// at the end of the render pass. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   Store: |  | ||||||
| 		///     Stores the results of the render pass in the texture slice memory. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   DontCare: |  | ||||||
| 		///     The driver will do whatever it wants with the texture slice memory. |  | ||||||
| 		///     This is usually a good option for depth textures that don't need to be reused. |  | ||||||
| 		/// </summary> |  | ||||||
| 		public StoreOp StoreOp; |  | ||||||
| 
 |  | ||||||
| 		/// <summary> |  | ||||||
| 		/// Determines what is done with the texture slice stencil values |  | ||||||
| 		/// at the beginning of the render pass. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   Load: |  | ||||||
| 		///     Loads the data currently in the texture slice. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   Clear: |  | ||||||
| 		///     Clears the texture slice to a single stencil value. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   DontCare: |  | ||||||
| 		///     The driver will do whatever it wants with the texture slice data. |  | ||||||
| 		///     This is a good option if you know that every single pixel will be written in the render pass. |  | ||||||
| 		/// </summary> |  | ||||||
| 		public LoadOp StencilLoadOp; |  | ||||||
| 
 |  | ||||||
| 		/// <summary> |  | ||||||
| 		/// Determines what is done with the texture slice stencil values |  | ||||||
| 		/// at the end of the render pass. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   Store: |  | ||||||
| 		///     Stores the results of the render pass in the texture slice memory. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   DontCare: |  | ||||||
| 		///     The driver will do whatever it wants with the texture slice memory. |  | ||||||
| 		///     This is usually a good option for stencil textures that don't need to be reused. |  | ||||||
| 		/// </summary> |  | ||||||
| 		public StoreOp StencilStoreOp; |  | ||||||
| 
 |  | ||||||
| 		/// <summary> |  | ||||||
| 		/// Specifies data dependency behavior. This option is ignored if LoadOp or StencilLoadOp is Load. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   Cycle: |  | ||||||
| 		///     If this texture slice has been used in commands that have not completed, |  | ||||||
| 		///     the implementation may prevent a dependency on those commands |  | ||||||
| 		///     at the cost of increased memory usage. |  | ||||||
| 		///     You may NOT assume that any of the previous texture (not slice!) data is retained. |  | ||||||
| 		///     This may prevent stalls when frequently reusing a texture slice in rendering. <br/> |  | ||||||
| 		/// |  | ||||||
| 		///   SafeOverwrite: |  | ||||||
| 		///     Overwrites the data safely using a GPU memory barrier. |  | ||||||
| 		/// </summary> |  | ||||||
| 		public WriteOptions WriteOption; |  | ||||||
| 
 |  | ||||||
| 		public DepthStencilAttachmentInfo( |  | ||||||
| 			TextureSlice textureSlice, |  | ||||||
| 			WriteOptions writeOption, |  | ||||||
| 			DepthStencilValue clearValue, |  | ||||||
| 			StoreOp depthStoreOp = StoreOp.DontCare, |  | ||||||
| 			StoreOp stencilStoreOp = StoreOp.DontCare |  | ||||||
| 		){ |  | ||||||
| 			TextureSlice = textureSlice; |  | ||||||
| 			DepthStencilClearValue = clearValue; |  | ||||||
| 			LoadOp = LoadOp.Clear; |  | ||||||
| 			StoreOp = depthStoreOp; |  | ||||||
| 			StencilLoadOp = LoadOp.Clear; |  | ||||||
| 			StencilStoreOp = stencilStoreOp; |  | ||||||
| 			WriteOption = writeOption; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public DepthStencilAttachmentInfo( |  | ||||||
| 			TextureSlice textureSlice, |  | ||||||
| 			WriteOptions writeOption, |  | ||||||
| 			LoadOp loadOp = LoadOp.DontCare, |  | ||||||
| 			StoreOp storeOp = StoreOp.DontCare, |  | ||||||
| 			LoadOp stencilLoadOp = LoadOp.DontCare, |  | ||||||
| 			StoreOp stencilStoreOp = StoreOp.DontCare |  | ||||||
| 		) { |  | ||||||
| 			TextureSlice = textureSlice; |  | ||||||
| 			DepthStencilClearValue = new DepthStencilValue(); |  | ||||||
| 			LoadOp = loadOp; |  | ||||||
| 			StoreOp = storeOp; |  | ||||||
| 			StencilLoadOp = stencilLoadOp; |  | ||||||
| 			StencilStoreOp = stencilStoreOp; |  | ||||||
| 			WriteOption = writeOption; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public DepthStencilAttachmentInfo( |  | ||||||
| 			TextureSlice textureSlice, |  | ||||||
| 			WriteOptions writeOption, |  | ||||||
| 			DepthStencilValue clearValue, |  | ||||||
| 			LoadOp loadOp, |  | ||||||
| 			StoreOp storeOp, |  | ||||||
| 			LoadOp stencilLoadOp, |  | ||||||
| 			StoreOp stencilStoreOp |  | ||||||
| 		) { |  | ||||||
| 			TextureSlice = textureSlice; |  | ||||||
| 			DepthStencilClearValue = clearValue; |  | ||||||
| 			LoadOp = loadOp; |  | ||||||
| 			StoreOp = storeOp; |  | ||||||
| 			StencilLoadOp = stencilLoadOp; |  | ||||||
| 			StencilStoreOp = stencilStoreOp; |  | ||||||
| 			WriteOption = writeOption; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public Refresh.DepthStencilAttachmentInfo ToRefresh() |  | ||||||
| 		{ |  | ||||||
| 			return new Refresh.DepthStencilAttachmentInfo |  | ||||||
| 			{ |  | ||||||
| 				textureSlice = TextureSlice.ToRefreshTextureSlice(), |  | ||||||
| 				depthStencilClearValue = DepthStencilClearValue.ToRefresh(), |  | ||||||
| 				loadOp = (Refresh.LoadOp) LoadOp, |  | ||||||
| 				storeOp = (Refresh.StoreOp) StoreOp, |  | ||||||
| 				stencilLoadOp = (Refresh.LoadOp) StencilLoadOp, |  | ||||||
| 				stencilStoreOp = (Refresh.StoreOp) StencilStoreOp, |  | ||||||
| 				writeOption = (Refresh.WriteOptions) WriteOption |  | ||||||
| 			}; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	[StructLayout(LayoutKind.Sequential)] |  | ||||||
| 	public struct ColorAttachmentDescription |  | ||||||
| 	{ |  | ||||||
| 		public TextureFormat Format; |  | ||||||
| 		public ColorAttachmentBlendState BlendState; |  | ||||||
| 
 |  | ||||||
| 		public ColorAttachmentDescription( |  | ||||||
| 			TextureFormat format, |  | ||||||
| 			ColorAttachmentBlendState blendState |  | ||||||
| 		) { |  | ||||||
| 			Format = format; |  | ||||||
| 			BlendState = blendState; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	[StructLayout(LayoutKind.Sequential)] |  | ||||||
| 	public struct IndirectDrawCommand |  | ||||||
| 	{ |  | ||||||
| 		public uint VertexCount; |  | ||||||
| 		public uint InstanceCount; |  | ||||||
| 		public uint FirstVertex; |  | ||||||
| 		public uint FirstInstance; |  | ||||||
| 
 |  | ||||||
| 		public IndirectDrawCommand( |  | ||||||
| 			uint vertexCount, |  | ||||||
| 			uint instanceCount, |  | ||||||
| 			uint firstVertex, |  | ||||||
| 			uint firstInstance |  | ||||||
| 		) { |  | ||||||
| 			VertexCount = vertexCount; |  | ||||||
| 			InstanceCount = instanceCount; |  | ||||||
| 			FirstVertex = firstVertex; |  | ||||||
| 			FirstInstance = firstInstance; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	[StructLayout(LayoutKind.Sequential)] |  | ||||||
| 	public struct BufferCopy |  | ||||||
| 	{ |  | ||||||
| 		public uint SrcOffset; |  | ||||||
| 		public uint DstOffset; |  | ||||||
| 		public uint Size; |  | ||||||
| 
 |  | ||||||
| 		public BufferCopy( |  | ||||||
| 			uint srcOffset, |  | ||||||
| 			uint dstOffset, |  | ||||||
| 			uint size |  | ||||||
| 		) { |  | ||||||
| 			SrcOffset = srcOffset; |  | ||||||
| 			DstOffset = dstOffset; |  | ||||||
| 			Size = size; |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public Refresh.BufferCopy ToRefresh() |  | ||||||
| 		{ |  | ||||||
| 			return new Refresh.BufferCopy |  | ||||||
| 			{ |  | ||||||
| 				srcOffset = SrcOffset, |  | ||||||
| 				dstOffset = DstOffset, |  | ||||||
| 				size = Size |  | ||||||
| 			}; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	/// <summary> |  | ||||||
| 	/// Parameters for a copy between buffer and image. |  | ||||||
| 	/// </summary> |  | ||||||
| 	/// <param name="BufferOffset">The offset into the buffer.</param> |  | ||||||
| 	/// <param name="BufferStride">If 0, image data is assumed tightly packed.</param> |  | ||||||
| 	/// <param name="BufferImageHeight">If 0, image data is assumed tightly packed.</param> |  | ||||||
| 	[StructLayout(LayoutKind.Sequential)] |  | ||||||
| 	public readonly record struct BufferImageCopy( |  | ||||||
| 		uint BufferOffset, |  | ||||||
| 		uint BufferStride, |  | ||||||
| 		uint BufferImageHeight |  | ||||||
| 	) { |  | ||||||
| 		public Refresh.BufferImageCopy ToRefresh() |  | ||||||
| 		{ |  | ||||||
| 			return new Refresh.BufferImageCopy |  | ||||||
| 			{ |  | ||||||
| 				bufferOffset = BufferOffset, |  | ||||||
| 				bufferStride = BufferStride, |  | ||||||
| 				bufferImageHeight = BufferImageHeight |  | ||||||
| 			}; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  | @ -6,9 +6,9 @@ namespace MoonWorks.Graphics | ||||||
| 	/// <summary> | 	/// <summary> | ||||||
| 	/// Compute pipelines perform arbitrary parallel processing on input data. | 	/// Compute pipelines perform arbitrary parallel processing on input data. | ||||||
| 	/// </summary> | 	/// </summary> | ||||||
| 	public class ComputePipeline : RefreshResource | 	public class ComputePipeline : SDL_GpuResource | ||||||
| 	{ | 	{ | ||||||
| 		protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyComputePipeline; | 		protected override Action<IntPtr, IntPtr> ReleaseFunction => Refresh.Refresh_QueueDestroyComputePipeline; | ||||||
| 
 | 
 | ||||||
| 		public ComputeShaderInfo ComputeShaderInfo { get; } | 		public ComputeShaderInfo ComputeShaderInfo { get; } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -10,9 +10,9 @@ namespace MoonWorks.Graphics | ||||||
| 	/// The Fence object itself is basically just a wrapper for the Refresh_Fence. <br/> | 	/// The Fence object itself is basically just a wrapper for the Refresh_Fence. <br/> | ||||||
| 	/// The internal handle is replaced so that we can pool Fence objects to manage garbage. | 	/// The internal handle is replaced so that we can pool Fence objects to manage garbage. | ||||||
| 	/// </summary> | 	/// </summary> | ||||||
| 	public class Fence : RefreshResource | 	public class Fence : SDL_GpuResource | ||||||
| 	{ | 	{ | ||||||
| 		protected override Action<nint, nint> QueueDestroyFunction => Refresh.Refresh_ReleaseFence; | 		protected override Action<nint, nint> ReleaseFunction => Refresh.Refresh_ReleaseFence; | ||||||
| 
 | 
 | ||||||
| 		internal Fence(GraphicsDevice device) : base(device) | 		internal Fence(GraphicsDevice device) : base(device) | ||||||
| 		{ | 		{ | ||||||
|  |  | ||||||
|  | @ -7,9 +7,9 @@ namespace MoonWorks.Graphics | ||||||
| 	/// <summary> | 	/// <summary> | ||||||
| 	/// GpuBuffers are generic data containers that can be used by the GPU. | 	/// GpuBuffers are generic data containers that can be used by the GPU. | ||||||
| 	/// </summary> | 	/// </summary> | ||||||
| 	public class GpuBuffer : RefreshResource | 	public class GpuBuffer : SDL_GpuResource | ||||||
| 	{ | 	{ | ||||||
| 		protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyGpuBuffer; | 		protected override Action<IntPtr, IntPtr> ReleaseFunction => Refresh.Refresh_QueueDestroyGpuBuffer; | ||||||
| 
 | 
 | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// Size in bytes. | 		/// Size in bytes. | ||||||
|  |  | ||||||
|  | @ -8,9 +8,9 @@ namespace MoonWorks.Graphics | ||||||
| 	/// Graphics pipelines encapsulate all of the render state in a single object. <br/> | 	/// Graphics pipelines encapsulate all of the render state in a single object. <br/> | ||||||
| 	/// These pipelines are bound before draw calls are issued. | 	/// These pipelines are bound before draw calls are issued. | ||||||
| 	/// </summary> | 	/// </summary> | ||||||
| 	public class GraphicsPipeline : RefreshResource | 	public class GraphicsPipeline : SDL_GpuResource | ||||||
| 	{ | 	{ | ||||||
| 		protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyGraphicsPipeline; | 		protected override Action<IntPtr, IntPtr> ReleaseFunction => Refresh.Refresh_QueueDestroyGraphicsPipeline; | ||||||
| 
 | 
 | ||||||
| 		public GraphicsShaderInfo VertexShaderInfo { get; } | 		public GraphicsShaderInfo VertexShaderInfo { get; } | ||||||
| 		public GraphicsShaderInfo FragmentShaderInfo { get; } | 		public GraphicsShaderInfo FragmentShaderInfo { get; } | ||||||
|  |  | ||||||
|  | @ -6,9 +6,9 @@ namespace MoonWorks.Graphics | ||||||
| 	/// <summary> | 	/// <summary> | ||||||
| 	/// A sampler specifies how a texture will be sampled in a shader. | 	/// A sampler specifies how a texture will be sampled in a shader. | ||||||
| 	/// </summary> | 	/// </summary> | ||||||
| 	public class Sampler : RefreshResource | 	public class Sampler : SDL_GpuResource | ||||||
| 	{ | 	{ | ||||||
| 		protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroySampler; | 		protected override Action<IntPtr, IntPtr> ReleaseFunction => Refresh.Refresh_QueueDestroySampler; | ||||||
| 
 | 
 | ||||||
| 		public Sampler( | 		public Sampler( | ||||||
| 			GraphicsDevice device, | 			GraphicsDevice device, | ||||||
|  |  | ||||||
|  | @ -0,0 +1,65 @@ | ||||||
|  | using SDL2_gpuCS; | ||||||
|  | using System; | ||||||
|  | using System.IO; | ||||||
|  | using System.Runtime.InteropServices; | ||||||
|  | 
 | ||||||
|  | namespace MoonWorks.Graphics | ||||||
|  | { | ||||||
|  | 	/// <summary> | ||||||
|  | 	/// Shader modules expect input in Refresh bytecode format. | ||||||
|  | 	/// </summary> | ||||||
|  | 	public class Shader : SDL_GpuResource | ||||||
|  | 	{ | ||||||
|  | 		protected override Action<IntPtr, IntPtr> ReleaseFunction => SDL_Gpu.SDL_GpuReleaseShader; | ||||||
|  | 
 | ||||||
|  | 		public unsafe Shader( | ||||||
|  | 			GraphicsDevice device, | ||||||
|  | 			string filePath, | ||||||
|  | 			string entryPointName, | ||||||
|  | 			ShaderStage shaderStage, | ||||||
|  | 			ShaderFormat shaderFormat | ||||||
|  | 		) : base(device) | ||||||
|  | 		{ | ||||||
|  | 			using var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read); | ||||||
|  | 			Handle = CreateFromStream(device, stream, entryPointName, shaderStage, shaderFormat); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		public unsafe Shader( | ||||||
|  | 			GraphicsDevice device, | ||||||
|  | 			Stream stream, | ||||||
|  | 			string entryPointName, | ||||||
|  | 			ShaderStage shaderStage, | ||||||
|  | 			ShaderFormat shaderFormat | ||||||
|  | 		) : base(device) | ||||||
|  | 		{ | ||||||
|  | 			Handle = CreateFromStream(device, stream, entryPointName, shaderStage, shaderFormat); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		private static unsafe IntPtr CreateFromStream( | ||||||
|  | 			GraphicsDevice device, | ||||||
|  | 			Stream stream, | ||||||
|  | 			string entryPointName, | ||||||
|  | 			ShaderStage shaderStage, | ||||||
|  | 			ShaderFormat shaderFormat | ||||||
|  | 		) { | ||||||
|  | 			var bytecodeBuffer = NativeMemory.Alloc((nuint) stream.Length); | ||||||
|  | 			var bytecodeSpan = new Span<byte>(bytecodeBuffer, (int) stream.Length); | ||||||
|  | 			stream.ReadExactly(bytecodeSpan); | ||||||
|  | 
 | ||||||
|  | 			SDL_Gpu.ShaderCreateInfo shaderCreateInfo; | ||||||
|  | 			shaderCreateInfo.CodeSize = (nuint) stream.Length; | ||||||
|  | 			shaderCreateInfo.Code = (byte*) bytecodeBuffer; | ||||||
|  | 			shaderCreateInfo.EntryPointName = entryPointName; | ||||||
|  | 			shaderCreateInfo.Stage = (SDL_Gpu.ShaderStage) shaderStage; | ||||||
|  | 			shaderCreateInfo.Format = (SDL_Gpu.ShaderFormat) shaderFormat; | ||||||
|  | 
 | ||||||
|  | 			var shaderModule = SDL_Gpu.SDL_GpuCreateShader( | ||||||
|  | 				device.Handle, | ||||||
|  | 				shaderCreateInfo | ||||||
|  | 			); | ||||||
|  | 
 | ||||||
|  | 			NativeMemory.Free(bytecodeBuffer); | ||||||
|  | 			return shaderModule; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -1,42 +0,0 @@ | ||||||
| using RefreshCS; |  | ||||||
| using System; |  | ||||||
| using System.IO; |  | ||||||
| using System.Runtime.InteropServices; |  | ||||||
| 
 |  | ||||||
| namespace MoonWorks.Graphics |  | ||||||
| { |  | ||||||
| 	/// <summary> |  | ||||||
| 	/// Shader modules expect input in Refresh bytecode format. |  | ||||||
| 	/// </summary> |  | ||||||
| 	public class ShaderModule : RefreshResource |  | ||||||
| 	{ |  | ||||||
| 		protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyShaderModule; |  | ||||||
| 
 |  | ||||||
| 		public unsafe ShaderModule(GraphicsDevice device, string filePath) : base(device) |  | ||||||
| 		{ |  | ||||||
| 			using var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read); |  | ||||||
| 			Handle = CreateFromStream(device, stream); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		public unsafe ShaderModule(GraphicsDevice device, Stream stream) : base(device) |  | ||||||
| 		{ |  | ||||||
| 			Handle = CreateFromStream(device, stream); |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		private static unsafe IntPtr CreateFromStream(GraphicsDevice device, Stream stream) |  | ||||||
| 		{ |  | ||||||
| 			var bytecodeBuffer = NativeMemory.Alloc((nuint) stream.Length); |  | ||||||
| 			var bytecodeSpan = new Span<byte>(bytecodeBuffer, (int) stream.Length); |  | ||||||
| 			stream.ReadExactly(bytecodeSpan); |  | ||||||
| 
 |  | ||||||
| 			Refresh.ShaderModuleCreateInfo shaderModuleCreateInfo; |  | ||||||
| 			shaderModuleCreateInfo.codeSize = (nuint) stream.Length; |  | ||||||
| 			shaderModuleCreateInfo.byteCode = (nint) bytecodeBuffer; |  | ||||||
| 
 |  | ||||||
| 			var shaderModule = Refresh.Refresh_CreateShaderModule(device.Handle, shaderModuleCreateInfo); |  | ||||||
| 
 |  | ||||||
| 			NativeMemory.Free(bytecodeBuffer); |  | ||||||
| 			return shaderModule; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  | @ -7,7 +7,7 @@ namespace MoonWorks.Graphics | ||||||
| 	/// <summary> | 	/// <summary> | ||||||
| 	/// A container for pixel data. | 	/// A container for pixel data. | ||||||
| 	/// </summary> | 	/// </summary> | ||||||
| 	public class Texture : RefreshResource | 	public class Texture : SDL_GpuResource | ||||||
| 	{ | 	{ | ||||||
| 		public uint Width { get; internal set; } | 		public uint Width { get; internal set; } | ||||||
| 		public uint Height { get; internal set; } | 		public uint Height { get; internal set; } | ||||||
|  | @ -41,7 +41,7 @@ namespace MoonWorks.Graphics | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// FIXME: this allocates a delegate instance | 		// FIXME: this allocates a delegate instance | ||||||
| 		protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyTexture; | 		protected override Action<IntPtr, IntPtr> ReleaseFunction => Refresh.Refresh_QueueDestroyTexture; | ||||||
| 
 | 
 | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// Creates a 2D texture. | 		/// Creates a 2D texture. | ||||||
|  |  | ||||||
|  | @ -4,9 +4,9 @@ using RefreshCS; | ||||||
| 
 | 
 | ||||||
| namespace MoonWorks.Graphics | namespace MoonWorks.Graphics | ||||||
| { | { | ||||||
| 	public unsafe class TransferBuffer : RefreshResource | 	public unsafe class TransferBuffer : SDL_GpuResource | ||||||
| 	{ | 	{ | ||||||
| 		protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyTransferBuffer; | 		protected override Action<IntPtr, IntPtr> ReleaseFunction => Refresh.Refresh_QueueDestroyTransferBuffer; | ||||||
| 
 | 
 | ||||||
| 		/// <summary> | 		/// <summary> | ||||||
| 		/// Size in bytes. | 		/// Size in bytes. | ||||||
|  |  | ||||||
|  | @ -1,17 +1,16 @@ | ||||||
| using System; | using System; | ||||||
| using System.Runtime.InteropServices; |  | ||||||
| using System.Threading; | using System.Threading; | ||||||
| 
 | 
 | ||||||
| namespace MoonWorks.Graphics; | namespace MoonWorks.Graphics; | ||||||
| 
 | 
 | ||||||
| public abstract class RefreshResource : GraphicsResource | public abstract class SDL_GpuResource : GraphicsResource | ||||||
| { | { | ||||||
| 	public IntPtr Handle { get => handle; internal set => handle = value; } | 	public IntPtr Handle { get => handle; internal set => handle = value; } | ||||||
| 	private IntPtr handle; | 	private IntPtr handle; | ||||||
| 
 | 
 | ||||||
| 	protected abstract Action<IntPtr, IntPtr> QueueDestroyFunction { get; } | 	protected abstract Action<IntPtr, IntPtr> ReleaseFunction { get; } | ||||||
| 
 | 
 | ||||||
| 	protected RefreshResource(GraphicsDevice device) : base(device) | 	protected SDL_GpuResource(GraphicsDevice device) : base(device) | ||||||
| 	{ | 	{ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -19,11 +18,11 @@ public abstract class RefreshResource : GraphicsResource | ||||||
| 	{ | 	{ | ||||||
| 		if (!IsDisposed) | 		if (!IsDisposed) | ||||||
| 		{ | 		{ | ||||||
| 			// Atomically call destroy function in case this is called from the finalizer thread | 			// Atomically call release function in case this is called from the finalizer thread | ||||||
| 			var toDispose = Interlocked.Exchange(ref handle, IntPtr.Zero); | 			var toDispose = Interlocked.Exchange(ref handle, IntPtr.Zero); | ||||||
| 			if (toDispose != IntPtr.Zero) | 			if (toDispose != IntPtr.Zero) | ||||||
| 			{ | 			{ | ||||||
| 				QueueDestroyFunction(Device.Handle, toDispose); | 				ReleaseFunction(Device.Handle, toDispose); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		base.Dispose(disposing); | 		base.Dispose(disposing); | ||||||
|  | @ -0,0 +1,799 @@ | ||||||
|  | using System; | ||||||
|  | using System.Runtime.InteropServices; | ||||||
|  | using SDL2_gpuCS; | ||||||
|  | 
 | ||||||
|  | namespace MoonWorks.Graphics; | ||||||
|  | 
 | ||||||
|  | // Recreate certain types in here so we can hide the SDL_GpuCS namespace | ||||||
|  | 
 | ||||||
|  | public enum PrimitiveType | ||||||
|  | { | ||||||
|  | 	PointList, | ||||||
|  | 	LineList, | ||||||
|  | 	LineStrip, | ||||||
|  | 	TriangleList, | ||||||
|  | 	TriangleStrip | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum LoadOp | ||||||
|  | { | ||||||
|  | 	Load, | ||||||
|  | 	Clear, | ||||||
|  | 	DontCare | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum StoreOp | ||||||
|  | { | ||||||
|  | 	Store, | ||||||
|  | 	DontCare | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum IndexElementSize | ||||||
|  | { | ||||||
|  | 	Sixteen, | ||||||
|  | 	ThirtyTwo | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum TextureFormat | ||||||
|  | { | ||||||
|  | /* Unsigned Normalized Float Color Formats */ | ||||||
|  | R8G8B8A8, | ||||||
|  | B8G8R8A8, | ||||||
|  | R5G6B5, | ||||||
|  | A1R5G5B5, | ||||||
|  | B4G4R4A4, | ||||||
|  | A2R10G10B10, | ||||||
|  | A2B10G10R10, | ||||||
|  | R16G16, | ||||||
|  | R16G16B16A16, | ||||||
|  | R8, | ||||||
|  | A8, | ||||||
|  | /* Compressed Unsigned Normalized Float Color Formats */ | ||||||
|  | BC1, | ||||||
|  | BC2, | ||||||
|  | BC3, | ||||||
|  | BC7, | ||||||
|  | /* Signed Normalized Float Color Formats  */ | ||||||
|  | R8G8_SNORM, | ||||||
|  | R8G8B8A8_SNORM, | ||||||
|  | /* Signed Float Color Formats */ | ||||||
|  | R16_SFLOAT, | ||||||
|  | R16G16_SFLOAT, | ||||||
|  | R16G16B16A16_SFLOAT, | ||||||
|  | R32_SFLOAT, | ||||||
|  | R32G32_SFLOAT, | ||||||
|  | R32G32B32A32_SFLOAT, | ||||||
|  | /* Unsigned Integer Color Formats */ | ||||||
|  | R8_UINT, | ||||||
|  | R8G8_UINT, | ||||||
|  | R8G8B8A8_UINT, | ||||||
|  | R16_UINT, | ||||||
|  | R16G16_UINT, | ||||||
|  | R16G16B16A16_UINT, | ||||||
|  | /* SRGB Color Formats */ | ||||||
|  | R8G8B8A8_SRGB, | ||||||
|  | B8G8R8A8_SRGB, | ||||||
|  | /* Compressed SRGB Color Formats */ | ||||||
|  | BC3_SRGB, | ||||||
|  | BC7_SRGB, | ||||||
|  | /* Depth Formats */ | ||||||
|  | D16_UNORM, | ||||||
|  | D24_UNORM, | ||||||
|  | D32_SFLOAT, | ||||||
|  | D24_UNORM_S8_UINT, | ||||||
|  | D32_SFLOAT_S8_UINT | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [Flags] | ||||||
|  | public enum TextureUsageFlags | ||||||
|  | { | ||||||
|  | 	Sampler = 0x1, | ||||||
|  | 	ColorTarget = 0x2, | ||||||
|  | 	DepthStencil = 0x4, | ||||||
|  | 	GraphicsStorage = 0x8, | ||||||
|  | 	ComputeStorageRead = 0x20, | ||||||
|  | 	ComputeStorageWrite = 0x40 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum TextureType | ||||||
|  | { | ||||||
|  | 	TwoD, | ||||||
|  | 	ThreeD, | ||||||
|  | 	Cube | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum SampleCount | ||||||
|  | { | ||||||
|  | 	One, | ||||||
|  | 	Two, | ||||||
|  | 	Four, | ||||||
|  | 	Eight | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum CubeMapFace | ||||||
|  | { | ||||||
|  | 	PositiveX, | ||||||
|  | 	NegativeX, | ||||||
|  | 	PositiveY, | ||||||
|  | 	NegativeY, | ||||||
|  | 	PositiveZ, | ||||||
|  | 	NegativeZ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [Flags] | ||||||
|  | public enum BufferUsageFlags | ||||||
|  | { | ||||||
|  | 	Vertex = 0x1, | ||||||
|  | 	Index = 0x2, | ||||||
|  | 	Indirect = 0x4, | ||||||
|  | 	GraphicsStorage = 0x8, | ||||||
|  | 	ComputeStorageRead = 0x20, | ||||||
|  | 	ComputeStorageWrite = 0x40 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [Flags] | ||||||
|  | public enum TransferBufferMapFlags | ||||||
|  | { | ||||||
|  | 	Read = 0x1, | ||||||
|  | 	Write = 0x2 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum ShaderStage | ||||||
|  | { | ||||||
|  | 	Vertex, | ||||||
|  | 	Fragment, | ||||||
|  | 	Compute | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum ShaderFormat | ||||||
|  | { | ||||||
|  | 	Invalid, | ||||||
|  | 	SPIRV, | ||||||
|  | 	DXBC, | ||||||
|  | 	DXIL, | ||||||
|  | 	MSL, | ||||||
|  | 	METALLIB, | ||||||
|  | 	SECRET | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum VertexElementFormat | ||||||
|  | { | ||||||
|  | 	Uint, | ||||||
|  | 	Float, | ||||||
|  | 	Vector2, | ||||||
|  | 	Vector3, | ||||||
|  | 	Vector4, | ||||||
|  | 	Color, | ||||||
|  | 	Byte4, | ||||||
|  | 	Short2, | ||||||
|  | 	Short4, | ||||||
|  | 	NormalizedShort2, | ||||||
|  | 	NormalizedShort4, | ||||||
|  | 	HalfVector2, | ||||||
|  | 	HalfVector4 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum VertexInputRate | ||||||
|  | { | ||||||
|  | 	Vertex, | ||||||
|  | 	Instance | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum FillMode | ||||||
|  | { | ||||||
|  | 	Fill, | ||||||
|  | 	Line | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum CullMode | ||||||
|  | { | ||||||
|  | 	None, | ||||||
|  | 	Front, | ||||||
|  | 	Back | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum FrontFace | ||||||
|  | { | ||||||
|  | 	CounterClockwise, | ||||||
|  | 	Clockwise | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum CompareOp | ||||||
|  | { | ||||||
|  | 	Never, | ||||||
|  | 	Less, | ||||||
|  | 	Equal, | ||||||
|  | 	LessOrEqual, | ||||||
|  | 	Greater, | ||||||
|  | 	NotEqual, | ||||||
|  | 	GreaterOrEqual, | ||||||
|  | 	Always | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum StencilOp | ||||||
|  | { | ||||||
|  | 	Keep, | ||||||
|  | 	Zero, | ||||||
|  | 	Replace, | ||||||
|  | 	IncrementAndClamp, | ||||||
|  | 	DecrementAndClamp, | ||||||
|  | 	Invert, | ||||||
|  | 	IncrementAndWrap, | ||||||
|  | 	DecrementAndWrap | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum BlendOp | ||||||
|  | { | ||||||
|  | 	Add, | ||||||
|  | 	Subtract, | ||||||
|  | 	ReverseSubtract, | ||||||
|  | 	Min, | ||||||
|  | 	Max | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum BlendFactor | ||||||
|  | { | ||||||
|  | 	Zero, | ||||||
|  | 	One, | ||||||
|  | 	SourceColor, | ||||||
|  | 	OneMinusSourceColor, | ||||||
|  | 	DestinationColor, | ||||||
|  | 	OneMinusDestinationColor, | ||||||
|  | 	SourceAlpha, | ||||||
|  | 	OneMinusSourceAlpha, | ||||||
|  | 	DestinationAlpha, | ||||||
|  | 	OneMinusDestinationAlpha, | ||||||
|  | 	ConstantColor, | ||||||
|  | 	OneMinusConstantColor, | ||||||
|  | 	SourceAlphaSaturate | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [Flags] | ||||||
|  | public enum ColorComponentFlags | ||||||
|  | { | ||||||
|  | 	R = 0x1, | ||||||
|  | 	G = 0x2, | ||||||
|  | 	B = 0x4, | ||||||
|  | 	A = 0x8 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum Filter | ||||||
|  | { | ||||||
|  | 	Nearest, | ||||||
|  | 	Linear | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum SamplerMipmapMode | ||||||
|  | { | ||||||
|  | 	Nearest, | ||||||
|  | 	Linear | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum SamplerAddressMode | ||||||
|  | { | ||||||
|  | 	Repeat, | ||||||
|  | 	MirroredRepeat, | ||||||
|  | 	ClampToEdge, | ||||||
|  | 	ClampToBorder | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum BorderColor | ||||||
|  | { | ||||||
|  | 	FloatTransparentBlack, | ||||||
|  | 	IntTransparentBlack, | ||||||
|  | 	FloatOpaqueBlack, | ||||||
|  | 	IntOpaqueBlack, | ||||||
|  | 	FloatOpaqueWhite, | ||||||
|  | 	IntOpaqueWhite | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum TransferUsage | ||||||
|  | { | ||||||
|  | 	Buffer, | ||||||
|  | 	Texture | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum PresentMode | ||||||
|  | { | ||||||
|  | 	VSync, | ||||||
|  | 	Immediate, | ||||||
|  | 	Mailbox | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | public enum SwapchainComposition | ||||||
|  | { | ||||||
|  | 	SDR, | ||||||
|  | 	SDRLinear, | ||||||
|  | 	HDRExtendedLinear, | ||||||
|  | 	HDR10_ST2084 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [Flags] | ||||||
|  | public enum BackendFlags | ||||||
|  | { | ||||||
|  | 	Invalid = 0x0, | ||||||
|  | 	Vulkan = 0x1, | ||||||
|  | 	D3D11 = 0x2, | ||||||
|  | 	Metal = 0x4, | ||||||
|  | 	All = Vulkan | D3D11 | Metal | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [StructLayout(LayoutKind.Sequential)] | ||||||
|  | public struct DepthStencilValue | ||||||
|  | { | ||||||
|  | 	public float Depth; | ||||||
|  | 	public uint Stencil; | ||||||
|  | 
 | ||||||
|  | 	public DepthStencilValue(float depth, uint stencil) | ||||||
|  | 	{ | ||||||
|  | 		Depth = depth; | ||||||
|  | 		Stencil = stencil; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// FIXME: can we do an unsafe cast somehow? | ||||||
|  | 	public SDL_Gpu.DepthStencilValue ToSDL() | ||||||
|  | 	{ | ||||||
|  | 		return new SDL_Gpu.DepthStencilValue | ||||||
|  | 		{ | ||||||
|  | 			Depth = Depth, | ||||||
|  | 			Stencil = Stencil | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [StructLayout(LayoutKind.Sequential)] | ||||||
|  | public struct Rect | ||||||
|  | { | ||||||
|  | 	public int X; | ||||||
|  | 	public int Y; | ||||||
|  | 	public int W; | ||||||
|  | 	public int H; | ||||||
|  | 
 | ||||||
|  | 	public Rect(int x, int y, int w, int h) | ||||||
|  | 	{ | ||||||
|  | 		X = x; | ||||||
|  | 		Y = y; | ||||||
|  | 		W = w; | ||||||
|  | 		H = h; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public Rect(int w, int h) | ||||||
|  | 	{ | ||||||
|  | 		X = 0; | ||||||
|  | 		Y = 0; | ||||||
|  | 		W = w; | ||||||
|  | 		H = h; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// FIXME: can we do an unsafe cast somehow? | ||||||
|  | 	public SDL_Gpu.Rect ToRefresh() | ||||||
|  | 	{ | ||||||
|  | 		return new SDL_Gpu.Rect | ||||||
|  | 		{ | ||||||
|  | 			X = X, | ||||||
|  | 			Y = Y, | ||||||
|  | 			W = W, | ||||||
|  | 			H = H | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [StructLayout(LayoutKind.Sequential)] | ||||||
|  | public struct Viewport | ||||||
|  | { | ||||||
|  | 	public float X; | ||||||
|  | 	public float Y; | ||||||
|  | 	public float W; | ||||||
|  | 	public float H; | ||||||
|  | 	public float MinDepth; | ||||||
|  | 	public float MaxDepth; | ||||||
|  | 
 | ||||||
|  | 	public Viewport(float w, float h) | ||||||
|  | 	{ | ||||||
|  | 		X = 0; | ||||||
|  | 		Y = 0; | ||||||
|  | 		W = w; | ||||||
|  | 		H = h; | ||||||
|  | 		MinDepth = 0; | ||||||
|  | 		MaxDepth = 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public Viewport(float x, float y, float w, float h) | ||||||
|  | 	{ | ||||||
|  | 		X = x; | ||||||
|  | 		Y = y; | ||||||
|  | 		W = w; | ||||||
|  | 		H = h; | ||||||
|  | 		MinDepth = 0; | ||||||
|  | 		MaxDepth = 1; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public Viewport(float x, float y, float w, float h, float minDepth, float maxDepth) | ||||||
|  | 	{ | ||||||
|  | 		X = x; | ||||||
|  | 		Y = y; | ||||||
|  | 		W = w; | ||||||
|  | 		H = h; | ||||||
|  | 		MinDepth = minDepth; | ||||||
|  | 		MaxDepth = maxDepth; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public SDL_Gpu.Viewport ToSDL() | ||||||
|  | 	{ | ||||||
|  | 		return new SDL_Gpu.Viewport | ||||||
|  | 		{ | ||||||
|  | 			X = X, | ||||||
|  | 			Y = Y, | ||||||
|  | 			W = W, | ||||||
|  | 			H = H, | ||||||
|  | 			MinDepth = MinDepth, | ||||||
|  | 			MaxDepth = MaxDepth | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [StructLayout(LayoutKind.Sequential)] | ||||||
|  | public struct VertexBinding | ||||||
|  | { | ||||||
|  | 	public uint Binding; | ||||||
|  | 	public uint Stride; | ||||||
|  | 	public VertexInputRate InputRate; | ||||||
|  | 
 | ||||||
|  | 	public static VertexBinding Create<T>(uint binding = 0, VertexInputRate inputRate = VertexInputRate.Vertex) where T : unmanaged | ||||||
|  | 	{ | ||||||
|  | 		return new VertexBinding | ||||||
|  | 		{ | ||||||
|  | 			Binding = binding, | ||||||
|  | 			InputRate = inputRate, | ||||||
|  | 			Stride = (uint) Marshal.SizeOf<T>() | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [StructLayout(LayoutKind.Sequential)] | ||||||
|  | public struct VertexAttribute | ||||||
|  | { | ||||||
|  | 	public uint Location; | ||||||
|  | 	public uint Binding; | ||||||
|  | 	public VertexElementFormat Format; | ||||||
|  | 	public uint Offset; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [StructLayout(LayoutKind.Sequential)] | ||||||
|  | public struct StencilOpState | ||||||
|  | { | ||||||
|  | 	public StencilOp FailOp; | ||||||
|  | 	public StencilOp PassOp; | ||||||
|  | 	public StencilOp DepthFailOp; | ||||||
|  | 	public CompareOp CompareOp; | ||||||
|  | 
 | ||||||
|  | 	public SDL_Gpu.StencilOpState ToSDL() | ||||||
|  | 	{ | ||||||
|  | 		return new SDL_Gpu.StencilOpState | ||||||
|  | 		{ | ||||||
|  | 			FailOp = (SDL_Gpu.StencilOp) FailOp, | ||||||
|  | 			PassOp = (SDL_Gpu.StencilOp) PassOp, | ||||||
|  | 			DepthFailOp = (SDL_Gpu.StencilOp) DepthFailOp, | ||||||
|  | 			CompareOp = (SDL_Gpu.CompareOp) CompareOp | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// <summary> | ||||||
|  | /// Determines how a color texture will be read/written in a render pass. | ||||||
|  | /// </summary> | ||||||
|  | public struct ColorAttachmentInfo | ||||||
|  | { | ||||||
|  | 	public TextureSlice TextureSlice; | ||||||
|  | 
 | ||||||
|  | 	/// <summary> | ||||||
|  | 	/// If LoadOp is set to Clear, the texture slice will be cleared to this color. | ||||||
|  | 	/// </summary> | ||||||
|  | 	public Color ClearColor; | ||||||
|  | 
 | ||||||
|  | 	/// <summary> | ||||||
|  | 	/// Determines what is done with the texture slice memory | ||||||
|  | 	/// at the beginning of the render pass. <br/> | ||||||
|  | 	/// | ||||||
|  | 	///   Load: | ||||||
|  | 	///     Loads the data currently in the texture slice. <br/> | ||||||
|  | 	/// | ||||||
|  | 	///   Clear: | ||||||
|  | 	///     Clears the texture slice to a single color. <br/> | ||||||
|  | 	/// | ||||||
|  | 	///   DontCare: | ||||||
|  | 	///     The driver will do whatever it wants with the texture slice data. | ||||||
|  | 	///     This is a good option if you know that every single pixel will be written in the render pass. | ||||||
|  | 	/// </summary> | ||||||
|  | 	public LoadOp LoadOp; | ||||||
|  | 
 | ||||||
|  | 	/// <summary> | ||||||
|  | 	/// Determines what is done with the texture slice memory | ||||||
|  | 	/// at the end of the render pass. <br/> | ||||||
|  | 	/// | ||||||
|  | 	///   Store: | ||||||
|  | 	///     Stores the results of the render pass in the texture slice memory. <br/> | ||||||
|  | 	/// | ||||||
|  | 	///   DontCare: | ||||||
|  | 	///     The driver will do whatever it wants with the texture slice memory. | ||||||
|  | 	/// </summary> | ||||||
|  | 	public StoreOp StoreOp; | ||||||
|  | 
 | ||||||
|  | 	/// <summary> | ||||||
|  | 	/// If true, cycles the texture if it is bound. | ||||||
|  | 	/// </summary> | ||||||
|  | 	public bool Cycle; | ||||||
|  | 
 | ||||||
|  | 	public ColorAttachmentInfo( | ||||||
|  | 		TextureSlice textureSlice, | ||||||
|  | 		bool cycle, | ||||||
|  | 		Color clearColor, | ||||||
|  | 		StoreOp storeOp = StoreOp.Store | ||||||
|  | 	) { | ||||||
|  | 		TextureSlice = textureSlice; | ||||||
|  | 		ClearColor = clearColor; | ||||||
|  | 		LoadOp = LoadOp.Clear; | ||||||
|  | 		StoreOp = storeOp; | ||||||
|  | 		Cycle = cycle; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public ColorAttachmentInfo( | ||||||
|  | 		TextureSlice textureSlice, | ||||||
|  | 		bool cycle, | ||||||
|  | 		LoadOp loadOp = LoadOp.DontCare, | ||||||
|  | 		StoreOp storeOp = StoreOp.Store | ||||||
|  | 	) { | ||||||
|  | 		TextureSlice = textureSlice; | ||||||
|  | 		ClearColor = Color.White; | ||||||
|  | 		LoadOp = loadOp; | ||||||
|  | 		StoreOp = storeOp; | ||||||
|  | 		Cycle = cycle; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public SDL_Gpu.ColorAttachmentInfo ToSDL() | ||||||
|  | 	{ | ||||||
|  | 		return new SDL_Gpu.ColorAttachmentInfo | ||||||
|  | 		{ | ||||||
|  | 			TextureSlice = TextureSlice.ToSDL(), | ||||||
|  | 			ClearColor = new SDL_Gpu.Color | ||||||
|  | 			{ | ||||||
|  | 				R = ClearColor.R / 255f, | ||||||
|  | 				G = ClearColor.G / 255f, | ||||||
|  | 				B = ClearColor.B / 255f, | ||||||
|  | 				A = ClearColor.A / 255f | ||||||
|  | 			}, | ||||||
|  | 			LoadOp = (SDL_Gpu.LoadOp) LoadOp, | ||||||
|  | 			StoreOp = (SDL_Gpu.StoreOp) StoreOp, | ||||||
|  | 			Cycle = Conversions.BoolToInt(Cycle) | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// <summary> | ||||||
|  | /// Determines how a depth/stencil texture will be read/written in a render pass. | ||||||
|  | /// </summary> | ||||||
|  | public struct DepthStencilAttachmentInfo | ||||||
|  | { | ||||||
|  | 	public TextureSlice TextureSlice; | ||||||
|  | 
 | ||||||
|  | 	/// <summary> | ||||||
|  | 	/// If LoadOp is set to Clear, the texture slice depth will be cleared to this depth value. <br/> | ||||||
|  | 	/// If StencilLoadOp is set to Clear, the texture slice stencil value will be cleared to this stencil value. | ||||||
|  | 	/// </summary> | ||||||
|  | 	public DepthStencilValue DepthStencilClearValue; | ||||||
|  | 
 | ||||||
|  | 	/// <summary> | ||||||
|  | 	/// Determines what is done with the texture slice depth values | ||||||
|  | 	/// at the beginning of the render pass. <br/> | ||||||
|  | 	/// | ||||||
|  | 	///   Load: | ||||||
|  | 	///     Loads the data currently in the texture slice. <br/> | ||||||
|  | 	/// | ||||||
|  | 	///   Clear: | ||||||
|  | 	///     Clears the texture slice to a single depth value. <br/> | ||||||
|  | 	/// | ||||||
|  | 	///   DontCare: | ||||||
|  | 	///     The driver will do whatever it wants with the texture slice data. | ||||||
|  | 	///     This is a good option if you know that every single pixel will be written in the render pass. | ||||||
|  | 	/// </summary> | ||||||
|  | 	public LoadOp LoadOp; | ||||||
|  | 
 | ||||||
|  | 	/// <summary> | ||||||
|  | 	/// Determines what is done with the texture slice depth values | ||||||
|  | 	/// at the end of the render pass. <br/> | ||||||
|  | 	/// | ||||||
|  | 	///   Store: | ||||||
|  | 	///     Stores the results of the render pass in the texture slice memory. <br/> | ||||||
|  | 	/// | ||||||
|  | 	///   DontCare: | ||||||
|  | 	///     The driver will do whatever it wants with the texture slice memory. | ||||||
|  | 	///     This is usually a good option for depth textures that don't need to be reused. | ||||||
|  | 	/// </summary> | ||||||
|  | 	public StoreOp StoreOp; | ||||||
|  | 
 | ||||||
|  | 	/// <summary> | ||||||
|  | 	/// Determines what is done with the texture slice stencil values | ||||||
|  | 	/// at the beginning of the render pass. <br/> | ||||||
|  | 	/// | ||||||
|  | 	///   Load: | ||||||
|  | 	///     Loads the data currently in the texture slice. <br/> | ||||||
|  | 	/// | ||||||
|  | 	///   Clear: | ||||||
|  | 	///     Clears the texture slice to a single stencil value. <br/> | ||||||
|  | 	/// | ||||||
|  | 	///   DontCare: | ||||||
|  | 	///     The driver will do whatever it wants with the texture slice data. | ||||||
|  | 	///     This is a good option if you know that every single pixel will be written in the render pass. | ||||||
|  | 	/// </summary> | ||||||
|  | 	public LoadOp StencilLoadOp; | ||||||
|  | 
 | ||||||
|  | 	/// <summary> | ||||||
|  | 	/// Determines what is done with the texture slice stencil values | ||||||
|  | 	/// at the end of the render pass. <br/> | ||||||
|  | 	/// | ||||||
|  | 	///   Store: | ||||||
|  | 	///     Stores the results of the render pass in the texture slice memory. <br/> | ||||||
|  | 	/// | ||||||
|  | 	///   DontCare: | ||||||
|  | 	///     The driver will do whatever it wants with the texture slice memory. | ||||||
|  | 	///     This is usually a good option for stencil textures that don't need to be reused. | ||||||
|  | 	/// </summary> | ||||||
|  | 	public StoreOp StencilStoreOp; | ||||||
|  | 
 | ||||||
|  | 	/// <summary> | ||||||
|  | 	/// If true, cycles the texture if it is bound. | ||||||
|  | 	/// </summary> | ||||||
|  | 	public bool Cycle; | ||||||
|  | 
 | ||||||
|  | 	public DepthStencilAttachmentInfo( | ||||||
|  | 		TextureSlice textureSlice, | ||||||
|  | 		bool cycle, | ||||||
|  | 		DepthStencilValue clearValue, | ||||||
|  | 		StoreOp depthStoreOp = StoreOp.DontCare, | ||||||
|  | 		StoreOp stencilStoreOp = StoreOp.DontCare | ||||||
|  | 	){ | ||||||
|  | 		TextureSlice = textureSlice; | ||||||
|  | 		DepthStencilClearValue = clearValue; | ||||||
|  | 		LoadOp = LoadOp.Clear; | ||||||
|  | 		StoreOp = depthStoreOp; | ||||||
|  | 		StencilLoadOp = LoadOp.Clear; | ||||||
|  | 		StencilStoreOp = stencilStoreOp; | ||||||
|  | 		Cycle = cycle; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public DepthStencilAttachmentInfo( | ||||||
|  | 		TextureSlice textureSlice, | ||||||
|  | 		bool cycle, | ||||||
|  | 		LoadOp loadOp = LoadOp.DontCare, | ||||||
|  | 		StoreOp storeOp = StoreOp.DontCare, | ||||||
|  | 		LoadOp stencilLoadOp = LoadOp.DontCare, | ||||||
|  | 		StoreOp stencilStoreOp = StoreOp.DontCare | ||||||
|  | 	) { | ||||||
|  | 		TextureSlice = textureSlice; | ||||||
|  | 		DepthStencilClearValue = new DepthStencilValue(); | ||||||
|  | 		LoadOp = loadOp; | ||||||
|  | 		StoreOp = storeOp; | ||||||
|  | 		StencilLoadOp = stencilLoadOp; | ||||||
|  | 		StencilStoreOp = stencilStoreOp; | ||||||
|  | 		Cycle = cycle; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public DepthStencilAttachmentInfo( | ||||||
|  | 		TextureSlice textureSlice, | ||||||
|  | 		bool cycle, | ||||||
|  | 		DepthStencilValue clearValue, | ||||||
|  | 		LoadOp loadOp, | ||||||
|  | 		StoreOp storeOp, | ||||||
|  | 		LoadOp stencilLoadOp, | ||||||
|  | 		StoreOp stencilStoreOp | ||||||
|  | 	) { | ||||||
|  | 		TextureSlice = textureSlice; | ||||||
|  | 		DepthStencilClearValue = clearValue; | ||||||
|  | 		LoadOp = loadOp; | ||||||
|  | 		StoreOp = storeOp; | ||||||
|  | 		StencilLoadOp = stencilLoadOp; | ||||||
|  | 		StencilStoreOp = stencilStoreOp; | ||||||
|  | 		Cycle = cycle; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public SDL_Gpu.DepthStencilAttachmentInfo ToSDL() | ||||||
|  | 	{ | ||||||
|  | 		return new SDL_Gpu.DepthStencilAttachmentInfo | ||||||
|  | 		{ | ||||||
|  | 			TextureSlice = TextureSlice.ToSDL(), | ||||||
|  | 			DepthStencilClearValue = DepthStencilClearValue.ToSDL(), | ||||||
|  | 			LoadOp = (SDL_Gpu.LoadOp) LoadOp, | ||||||
|  | 			StoreOp = (SDL_Gpu.StoreOp) StoreOp, | ||||||
|  | 			StencilLoadOp = (SDL_Gpu.LoadOp) StencilLoadOp, | ||||||
|  | 			StencilStoreOp = (SDL_Gpu.StoreOp) StencilStoreOp, | ||||||
|  | 			Cycle = Conversions.BoolToInt(Cycle) | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [StructLayout(LayoutKind.Sequential)] | ||||||
|  | public struct ColorAttachmentDescription | ||||||
|  | { | ||||||
|  | 	public TextureFormat Format; | ||||||
|  | 	public ColorAttachmentBlendState BlendState; | ||||||
|  | 
 | ||||||
|  | 	public ColorAttachmentDescription( | ||||||
|  | 		TextureFormat format, | ||||||
|  | 		ColorAttachmentBlendState blendState | ||||||
|  | 	) { | ||||||
|  | 		Format = format; | ||||||
|  | 		BlendState = blendState; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [StructLayout(LayoutKind.Sequential)] | ||||||
|  | public struct IndirectDrawCommand | ||||||
|  | { | ||||||
|  | 	public uint VertexCount; | ||||||
|  | 	public uint InstanceCount; | ||||||
|  | 	public uint FirstVertex; | ||||||
|  | 	public uint FirstInstance; | ||||||
|  | 
 | ||||||
|  | 	public IndirectDrawCommand( | ||||||
|  | 		uint vertexCount, | ||||||
|  | 		uint instanceCount, | ||||||
|  | 		uint firstVertex, | ||||||
|  | 		uint firstInstance | ||||||
|  | 	) { | ||||||
|  | 		VertexCount = vertexCount; | ||||||
|  | 		InstanceCount = instanceCount; | ||||||
|  | 		FirstVertex = firstVertex; | ||||||
|  | 		FirstInstance = firstInstance; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | [StructLayout(LayoutKind.Sequential)] | ||||||
|  | public struct BufferCopy | ||||||
|  | { | ||||||
|  | 	public uint SrcOffset; | ||||||
|  | 	public uint DstOffset; | ||||||
|  | 	public uint Size; | ||||||
|  | 
 | ||||||
|  | 	public BufferCopy( | ||||||
|  | 		uint srcOffset, | ||||||
|  | 		uint dstOffset, | ||||||
|  | 		uint size | ||||||
|  | 	) { | ||||||
|  | 		SrcOffset = srcOffset; | ||||||
|  | 		DstOffset = dstOffset; | ||||||
|  | 		Size = size; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	public SDL_Gpu.BufferCopy ToRefresh() | ||||||
|  | 	{ | ||||||
|  | 		return new SDL_Gpu.BufferCopy | ||||||
|  | 		{ | ||||||
|  | 			SourceOffset = SrcOffset, | ||||||
|  | 			DestinationOffset = DstOffset, | ||||||
|  | 			Size = Size | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /// <summary> | ||||||
|  | /// Parameters for a copy between buffer and image. | ||||||
|  | /// </summary> | ||||||
|  | /// <param name="BufferOffset">The offset into the buffer.</param> | ||||||
|  | /// <param name="BufferStride">If 0, image data is assumed tightly packed.</param> | ||||||
|  | /// <param name="BufferImageHeight">If 0, image data is assumed tightly packed.</param> | ||||||
|  | [StructLayout(LayoutKind.Sequential)] | ||||||
|  | public readonly record struct BufferImageCopy( | ||||||
|  | 	uint BufferOffset, | ||||||
|  | 	uint BufferStride, | ||||||
|  | 	uint BufferImageHeight | ||||||
|  | ) { | ||||||
|  | 	public SDL_Gpu.BufferImageCopy ToRefresh() | ||||||
|  | 	{ | ||||||
|  | 		return new SDL_Gpu.BufferImageCopy | ||||||
|  | 		{ | ||||||
|  | 			BufferOffset = BufferOffset, | ||||||
|  | 			BufferStride = BufferStride, | ||||||
|  | 			BufferImageHeight = BufferImageHeight | ||||||
|  | 		}; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| using RefreshCS; | using SDL2_gpuCS; | ||||||
|  | 
 | ||||||
|  | namespace MoonWorks.Graphics; | ||||||
| 
 | 
 | ||||||
| namespace MoonWorks.Graphics |  | ||||||
| { |  | ||||||
| /// <summary> | /// <summary> | ||||||
| /// All of the information that is used to create a sampler. | /// All of the information that is used to create a sampler. | ||||||
| /// </summary> | /// </summary> | ||||||
|  | @ -150,25 +150,24 @@ namespace MoonWorks.Graphics | ||||||
| 		MaxLod = 1000 | 		MaxLod = 1000 | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| 		public Refresh.SamplerStateCreateInfo ToRefreshSamplerStateCreateInfo() | 	public SDL_Gpu.SamplerCreateInfo ToSDL() | ||||||
| 	{ | 	{ | ||||||
| 			return new Refresh.SamplerStateCreateInfo | 		return new SDL_Gpu.SamplerCreateInfo | ||||||
| 		{ | 		{ | ||||||
| 				minFilter = (Refresh.Filter) MinFilter, | 			MinFilter = (SDL_Gpu.Filter) MinFilter, | ||||||
| 				magFilter = (Refresh.Filter) MagFilter, | 			MagFilter = (SDL_Gpu.Filter) MagFilter, | ||||||
| 				mipmapMode = (Refresh.SamplerMipmapMode) MipmapMode, | 			MipmapMode = (SDL_Gpu.SamplerMipmapMode) MipmapMode, | ||||||
| 				addressModeU = (Refresh.SamplerAddressMode) AddressModeU, | 			AddressModeU = (SDL_Gpu.SamplerAddressMode) AddressModeU, | ||||||
| 				addressModeV = (Refresh.SamplerAddressMode) AddressModeV, | 			AddressModeV = (SDL_Gpu.SamplerAddressMode) AddressModeV, | ||||||
| 				addressModeW = (Refresh.SamplerAddressMode) AddressModeW, | 			AddressModeW = (SDL_Gpu.SamplerAddressMode) AddressModeW, | ||||||
| 				mipLodBias = MipLodBias, | 			MipLodBias = MipLodBias, | ||||||
| 				anisotropyEnable = Conversions.BoolToByte(AnisotropyEnable), | 			AnisotropyEnable = Conversions.BoolToByte(AnisotropyEnable), | ||||||
| 				maxAnisotropy = MaxAnisotropy, | 			MaxAnisotropy = MaxAnisotropy, | ||||||
| 				compareEnable = Conversions.BoolToByte(CompareEnable), | 			CompareEnable = Conversions.BoolToByte(CompareEnable), | ||||||
| 				compareOp = (Refresh.CompareOp) CompareOp, | 			CompareOp = (SDL_Gpu.CompareOp) CompareOp, | ||||||
| 				minLod = MinLod, | 			MinLod = MinLod, | ||||||
| 				maxLod = MaxLod, | 			MaxLod = MaxLod, | ||||||
| 				borderColor = (Refresh.BorderColor) BorderColor | 			BorderColor = (SDL_Gpu.BorderColor) BorderColor | ||||||
| 		}; | 		}; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| } |  | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue