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(uint binding = 0, VertexInputRate inputRate = VertexInputRate.Vertex) where T : unmanaged { return new VertexBinding { Binding = binding, InputRate = inputRate, Stride = (uint) Marshal.SizeOf() }; } } [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 }; } } /// /// Determines how a color texture will be read/written in a render pass. /// public struct ColorAttachmentInfo { public TextureSlice TextureSlice; /// /// If LoadOp is set to Clear, the texture slice will be cleared to this color. /// public Color ClearColor; /// /// Determines what is done with the texture slice memory /// at the beginning of the render pass.
/// /// Load: /// Loads the data currently in the texture slice.
/// /// Clear: /// Clears the texture slice to a single color.
/// /// 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. ///
public LoadOp LoadOp; /// /// Determines what is done with the texture slice memory /// at the end of the render pass.
/// /// Store: /// Stores the results of the render pass in the texture slice memory.
/// /// DontCare: /// The driver will do whatever it wants with the texture slice memory. ///
public StoreOp StoreOp; /// /// Specifies data dependency behavior. This option is ignored if LoadOp is Load.
/// /// 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.
/// /// SafeOverwrite: /// Overwrites the data safely using a GPU memory barrier. ///
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 }; } } /// /// Determines how a depth/stencil texture will be read/written in a render pass. /// public struct DepthStencilAttachmentInfo { public TextureSlice TextureSlice; /// /// If LoadOp is set to Clear, the texture slice depth will be cleared to this depth value.
/// If StencilLoadOp is set to Clear, the texture slice stencil value will be cleared to this stencil value. ///
public DepthStencilValue DepthStencilClearValue; /// /// Determines what is done with the texture slice depth values /// at the beginning of the render pass.
/// /// Load: /// Loads the data currently in the texture slice.
/// /// Clear: /// Clears the texture slice to a single depth value.
/// /// 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. ///
public LoadOp LoadOp; /// /// Determines what is done with the texture slice depth values /// at the end of the render pass.
/// /// Store: /// Stores the results of the render pass in the texture slice memory.
/// /// 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. ///
public StoreOp StoreOp; /// /// Determines what is done with the texture slice stencil values /// at the beginning of the render pass.
/// /// Load: /// Loads the data currently in the texture slice.
/// /// Clear: /// Clears the texture slice to a single stencil value.
/// /// 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. ///
public LoadOp StencilLoadOp; /// /// Determines what is done with the texture slice stencil values /// at the end of the render pass.
/// /// Store: /// Stores the results of the render pass in the texture slice memory.
/// /// 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. ///
public StoreOp StencilStoreOp; /// /// Specifies data dependency behavior. This option is ignored if LoadOp or StencilLoadOp is Load.
/// /// 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.
/// /// SafeOverwrite: /// Overwrites the data safely using a GPU memory barrier. ///
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 }; } } /// /// Parameters for a copy between buffer and image. /// /// The offset into the buffer. /// If 0, image data is assumed tightly packed. /// If 0, image data is assumed tightly packed. [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 }; } } }