various convenience states

main
cosmonaut 2021-01-15 18:08:58 -08:00
parent 424ff7f00c
commit e9dfdb0921
12 changed files with 447 additions and 26 deletions

@ -1 +1 @@
Subproject commit 3379b95e449904b30d66d8bc17e4da83fc60c1be
Subproject commit 2e3871a03d99e413f84748e40bdb6c03df2ecd1c

View File

@ -7,8 +7,11 @@ namespace Campari
{
protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyBuffer;
/* FIXME: could we have a special flags struct? */
public Buffer(RefreshDevice device, uint usageFlags, uint sizeInBytes) : base(device)
public Buffer(
RefreshDevice device,
Refresh.BufferUsageFlags usageFlags,
uint sizeInBytes
) : base(device)
{
Handle = Refresh.Refresh_CreateBuffer(
device.Handle,

View File

@ -23,17 +23,23 @@ namespace Campari
RenderPass renderPass
) : base(device)
{
var blendStateHandle = GCHandle.Alloc(colorBlendState.ColorTargetBlendStates, GCHandleType.Pinned);
var vertexAttributesHandle = GCHandle.Alloc(vertexInputState.VertexAttributes, GCHandleType.Pinned);
var vertexBindingsHandle = GCHandle.Alloc(vertexInputState.VertexBindings, GCHandleType.Pinned);
var viewportHandle = GCHandle.Alloc(viewportState.Viewports, GCHandleType.Pinned);
var scissorHandle = GCHandle.Alloc(viewportState.Scissors, GCHandleType.Pinned);
var colorTargetBlendStates = stackalloc Refresh.ColorTargetBlendState[colorBlendState.ColorTargetBlendStates.Length];
for (var i = 0; i < colorBlendState.ColorTargetBlendStates.Length; i += 1)
{
colorTargetBlendStates[i] = colorBlendState.ColorTargetBlendStates[i].ToRefreshColorTargetBlendState();
}
Refresh.GraphicsPipelineCreateInfo graphicsPipelineCreateInfo;
graphicsPipelineCreateInfo.colorBlendState.logicOpEnable = Conversions.BoolToByte(colorBlendState.LogicOpEnable);
graphicsPipelineCreateInfo.colorBlendState.logicOp = colorBlendState.LogicOp;
graphicsPipelineCreateInfo.colorBlendState.blendStates = blendStateHandle.AddrOfPinnedObject();
graphicsPipelineCreateInfo.colorBlendState.blendStates = (IntPtr) colorTargetBlendStates;
graphicsPipelineCreateInfo.colorBlendState.blendStateCount = (uint) colorBlendState.ColorTargetBlendStates.Length;
graphicsPipelineCreateInfo.colorBlendState.blendConstants[0] = colorBlendState.BlendConstants.R;
graphicsPipelineCreateInfo.colorBlendState.blendConstants[1] = colorBlendState.BlendConstants.G;
@ -89,7 +95,6 @@ namespace Campari
Handle = Refresh.Refresh_CreateGraphicsPipeline(device.Handle, ref graphicsPipelineCreateInfo);
blendStateHandle.Free();
vertexAttributesHandle.Free();
vertexBindingsHandle.Free();
viewportHandle.Free();

View File

@ -9,10 +9,15 @@ namespace Campari
public Sampler(
RefreshDevice device,
ref Refresh.SamplerStateCreateInfo samplerStateCreateInfo
ref SamplerState samplerState
) : base(device)
{
Handle = Refresh.Refresh_CreateSampler(device.Handle, ref samplerStateCreateInfo);
var refreshSamplerStateCreateInfo = samplerState.ToRefreshSamplerStateCreateInfo();
Handle = Refresh.Refresh_CreateSampler(
device.Handle,
ref refreshSamplerStateCreateInfo
);
}
}
}

View File

@ -7,6 +7,6 @@ namespace Campari
public bool LogicOpEnable;
public Refresh.LogicOp LogicOp;
public BlendConstants BlendConstants;
public Refresh.ColorTargetBlendState[] ColorTargetBlendStates;
public ColorTargetBlendState[] ColorTargetBlendStates;
}
}

View File

@ -0,0 +1,85 @@
using RefreshCS;
namespace Campari
{
public struct ColorTargetBlendState
{
public bool BlendEnable;
public Refresh.BlendOp AlphaBlendOp;
public Refresh.BlendOp ColorBlendOp;
public Refresh.ColorComponentFlags ColorWriteMask;
public Refresh.BlendFactor DestinationAlphaBlendFactor;
public Refresh.BlendFactor DestinationColorBlendFactor;
public Refresh.BlendFactor SourceAlphaBlendFactor;
public Refresh.BlendFactor SourceColorBlendFactor;
public static readonly ColorTargetBlendState Additive = new ColorTargetBlendState
{
BlendEnable = true,
AlphaBlendOp = Refresh.BlendOp.Add,
ColorBlendOp = Refresh.BlendOp.Add,
ColorWriteMask = Refresh.ColorComponentFlags.RGBA,
SourceColorBlendFactor = Refresh.BlendFactor.SourceAlpha,
SourceAlphaBlendFactor = Refresh.BlendFactor.SourceAlpha,
DestinationColorBlendFactor = Refresh.BlendFactor.One,
DestinationAlphaBlendFactor = Refresh.BlendFactor.One
};
public static readonly ColorTargetBlendState AlphaBlend = new ColorTargetBlendState
{
BlendEnable = true,
AlphaBlendOp = Refresh.BlendOp.Add,
ColorBlendOp = Refresh.BlendOp.Add,
ColorWriteMask = Refresh.ColorComponentFlags.RGBA,
SourceColorBlendFactor = Refresh.BlendFactor.One,
SourceAlphaBlendFactor = Refresh.BlendFactor.One,
DestinationColorBlendFactor = Refresh.BlendFactor.OneMinusSourceAlpha,
DestinationAlphaBlendFactor = Refresh.BlendFactor.OneMinusSourceAlpha
};
public static readonly ColorTargetBlendState NonPremultiplied = new ColorTargetBlendState
{
BlendEnable = true,
AlphaBlendOp = Refresh.BlendOp.Add,
ColorBlendOp = Refresh.BlendOp.Add,
ColorWriteMask = Refresh.ColorComponentFlags.RGBA,
SourceColorBlendFactor = Refresh.BlendFactor.SourceAlpha,
SourceAlphaBlendFactor = Refresh.BlendFactor.SourceAlpha,
DestinationColorBlendFactor = Refresh.BlendFactor.OneMinusSourceAlpha,
DestinationAlphaBlendFactor = Refresh.BlendFactor.OneMinusSourceAlpha
};
public static readonly ColorTargetBlendState Opaque = new ColorTargetBlendState
{
BlendEnable = true,
AlphaBlendOp = Refresh.BlendOp.Add,
ColorBlendOp = Refresh.BlendOp.Add,
ColorWriteMask = Refresh.ColorComponentFlags.RGBA,
SourceColorBlendFactor = Refresh.BlendFactor.One,
SourceAlphaBlendFactor = Refresh.BlendFactor.One,
DestinationColorBlendFactor = Refresh.BlendFactor.Zero,
DestinationAlphaBlendFactor = Refresh.BlendFactor.Zero
};
public static readonly ColorTargetBlendState None = new ColorTargetBlendState
{
BlendEnable = false,
ColorWriteMask = Refresh.ColorComponentFlags.RGBA
};
public Refresh.ColorTargetBlendState ToRefreshColorTargetBlendState()
{
return new Refresh.ColorTargetBlendState
{
blendEnable = Conversions.BoolToByte(BlendEnable),
alphaBlendOp = AlphaBlendOp,
colorBlendOp = ColorBlendOp,
colorWriteMask = ColorWriteMask,
destinationAlphaBlendFactor = DestinationAlphaBlendFactor,
destinationColorBlendFactor = DestinationColorBlendFactor,
sourceAlphaBlendFactor = SourceAlphaBlendFactor,
sourceColorBlendFactor = SourceColorBlendFactor
};
}
}
}

View File

@ -13,5 +13,31 @@ namespace Campari
public float MinDepthBounds;
public float MaxDepthBounds;
public bool StencilTestEnable;
public static readonly DepthStencilState DepthReadWrite = new DepthStencilState
{
DepthTestEnable = true,
DepthWriteEnable = true,
DepthBoundsTestEnable = false,
StencilTestEnable = false,
CompareOp = Refresh.CompareOp.LessOrEqual
};
public static readonly DepthStencilState DepthRead = new DepthStencilState
{
DepthTestEnable = true,
DepthWriteEnable = false,
DepthBoundsTestEnable = false,
StencilTestEnable = false,
CompareOp = Refresh.CompareOp.LessOrEqual
};
public static readonly DepthStencilState Disable = new DepthStencilState
{
DepthTestEnable = false,
DepthWriteEnable = false,
DepthBoundsTestEnable = false,
StencilTestEnable = false
};
}
}

View File

@ -6,5 +6,11 @@ namespace Campari
{
public Refresh.SampleCount MultisampleCount;
public uint SampleMask;
public static readonly MultisampleState None = new MultisampleState
{
MultisampleCount = Refresh.SampleCount.One,
SampleMask = uint.MaxValue
};
}
}

View File

@ -13,5 +13,41 @@ namespace Campari
public Refresh.FillMode FillMode;
public Refresh.FrontFace FrontFace;
public float LineWidth;
public static readonly RasterizerState CullClockwise = new RasterizerState
{
CullMode = Refresh.CullMode.Front,
FrontFace = Refresh.FrontFace.Clockwise,
FillMode = Refresh.FillMode.Fill,
DepthBiasEnable = false,
LineWidth = 1f
};
public static readonly RasterizerState CullCounterClockwise = new RasterizerState
{
CullMode = Refresh.CullMode.Back,
FrontFace = Refresh.FrontFace.Clockwise,
FillMode = Refresh.FillMode.Fill,
DepthBiasEnable = false,
LineWidth = 1f
};
public static readonly RasterizerState CullNone = new RasterizerState
{
CullMode = Refresh.CullMode.None,
FrontFace = Refresh.FrontFace.Clockwise,
FillMode = Refresh.FillMode.Fill,
DepthBiasEnable = false,
LineWidth = 1f
};
public static readonly RasterizerState Wireframe = new RasterizerState
{
CullMode = Refresh.CullMode.None,
FrontFace = Refresh.FrontFace.Clockwise,
FillMode = Refresh.FillMode.Fill,
DepthBiasEnable = false,
LineWidth = 1f
};
}
}

135
src/State/SamplerState.cs Normal file
View File

@ -0,0 +1,135 @@
using RefreshCS;
namespace Campari
{
public struct SamplerState
{
public Refresh.Filter MinFilter;
public Refresh.Filter MagFilter;
public Refresh.SamplerMipmapMode MipmapMode;
public Refresh.SamplerAddressMode AddressModeU;
public Refresh.SamplerAddressMode AddressModeV;
public Refresh.SamplerAddressMode AddressModeW;
public float MipLodBias;
public bool AnisotropyEnable;
public float MaxAnisotropy;
public bool CompareEnable;
public Refresh.CompareOp CompareOp;
public float MinLod;
public float MaxLod;
public Refresh.BorderColor BorderColor;
public static readonly SamplerState AnisotropicClamp = new SamplerState
{
MinFilter = Refresh.Filter.Linear,
MagFilter = Refresh.Filter.Linear,
MipmapMode = Refresh.SamplerMipmapMode.Linear,
AddressModeU = Refresh.SamplerAddressMode.ClampToEdge,
AddressModeV = Refresh.SamplerAddressMode.ClampToEdge,
AddressModeW = Refresh.SamplerAddressMode.ClampToEdge,
CompareEnable = false,
AnisotropyEnable = true,
MaxAnisotropy = 4,
MipLodBias = 0f,
MinLod = 0,
MaxLod = 1000 /* VK_LOD_CLAMP_NONE */
};
public static readonly SamplerState AnisotropicWrap = new SamplerState
{
MinFilter = Refresh.Filter.Linear,
MagFilter = Refresh.Filter.Linear,
MipmapMode = Refresh.SamplerMipmapMode.Linear,
AddressModeU = Refresh.SamplerAddressMode.Repeat,
AddressModeV = Refresh.SamplerAddressMode.Repeat,
AddressModeW = Refresh.SamplerAddressMode.Repeat,
CompareEnable = false,
AnisotropyEnable = true,
MaxAnisotropy = 4,
MipLodBias = 0f,
MinLod = 0,
MaxLod = 1000 /* VK_LOD_CLAMP_NONE */
};
public static readonly SamplerState LinearClamp = new SamplerState
{
MinFilter = Refresh.Filter.Linear,
MagFilter = Refresh.Filter.Linear,
MipmapMode = Refresh.SamplerMipmapMode.Linear,
AddressModeU = Refresh.SamplerAddressMode.ClampToEdge,
AddressModeV = Refresh.SamplerAddressMode.ClampToEdge,
AddressModeW = Refresh.SamplerAddressMode.ClampToEdge,
CompareEnable = false,
AnisotropyEnable = false,
MipLodBias = 0f,
MinLod = 0,
MaxLod = 1000
};
public static readonly SamplerState LinearWrap = new SamplerState
{
MinFilter = Refresh.Filter.Linear,
MagFilter = Refresh.Filter.Linear,
MipmapMode = Refresh.SamplerMipmapMode.Linear,
AddressModeU = Refresh.SamplerAddressMode.Repeat,
AddressModeV = Refresh.SamplerAddressMode.Repeat,
AddressModeW = Refresh.SamplerAddressMode.Repeat,
CompareEnable = false,
AnisotropyEnable = false,
MipLodBias = 0f,
MinLod = 0,
MaxLod = 1000
};
public static readonly SamplerState PointClamp = new SamplerState
{
MinFilter = Refresh.Filter.Nearest,
MagFilter = Refresh.Filter.Nearest,
MipmapMode = Refresh.SamplerMipmapMode.Nearest,
AddressModeU = Refresh.SamplerAddressMode.ClampToEdge,
AddressModeV = Refresh.SamplerAddressMode.ClampToEdge,
AddressModeW = Refresh.SamplerAddressMode.ClampToEdge,
CompareEnable = false,
AnisotropyEnable = false,
MipLodBias = 0f,
MinLod = 0,
MaxLod = 1000
};
public static readonly SamplerState PointWrap = new SamplerState
{
MinFilter = Refresh.Filter.Nearest,
MagFilter = Refresh.Filter.Nearest,
MipmapMode = Refresh.SamplerMipmapMode.Nearest,
AddressModeU = Refresh.SamplerAddressMode.Repeat,
AddressModeV = Refresh.SamplerAddressMode.Repeat,
AddressModeW = Refresh.SamplerAddressMode.Repeat,
CompareEnable = false,
AnisotropyEnable = false,
MipLodBias = 0f,
MinLod = 0,
MaxLod = 1000
};
public Refresh.SamplerStateCreateInfo ToRefreshSamplerStateCreateInfo()
{
return new Refresh.SamplerStateCreateInfo
{
minFilter = MinFilter,
magFilter = MagFilter,
mipmapMode = MipmapMode,
addressModeU = AddressModeU,
addressModeV = AddressModeV,
addressModeW = AddressModeW,
mipLodBias = MipLodBias,
anisotropyEnable = Conversions.BoolToByte(AnisotropyEnable),
maxAnisotropy = MaxAnisotropy,
compareEnable = Conversions.BoolToByte(CompareEnable),
compareOp = CompareOp,
minLod = MinLod,
maxLod = MaxLod,
borderColor = BorderColor
};
}
}
}

View File

@ -0,0 +1,31 @@
using RefreshCS;
namespace Campari
{
public struct TextureCreateInfo
{
public uint Width;
public uint Height;
public uint Depth;
public bool IsCube;
public Refresh.SampleCount SampleCount;
public uint LevelCount;
public Refresh.ColorFormat Format;
public Refresh.TextureUsageFlags UsageFlags;
public Refresh.TextureCreateInfo ToRefreshTextureCreateInfo()
{
return new Refresh.TextureCreateInfo
{
width = Width,
height = Height,
depth = Depth,
isCube = Conversions.BoolToByte(IsCube),
sampleCount = SampleCount,
levelCount = LevelCount,
format = Format,
usageFlags = UsageFlags
};
}
}
}

View File

@ -21,34 +21,111 @@ namespace Campari
out var channels
);
Refresh.TextureCreateInfo textureCreateInfo;
textureCreateInfo.width = (uint) width;
textureCreateInfo.height = (uint) height;
textureCreateInfo.depth = 1;
textureCreateInfo.format = Refresh.ColorFormat.R8G8B8A8;
textureCreateInfo.isCube = 0;
textureCreateInfo.levelCount = 1;
textureCreateInfo.sampleCount = Refresh.SampleCount.One;
textureCreateInfo.usageFlags = (uint) Refresh.TextureUsageFlagBits.SamplerBit;
Campari.TextureCreateInfo textureCreateInfo;
textureCreateInfo.Width = (uint)width;
textureCreateInfo.Height = (uint)height;
textureCreateInfo.Depth = 1;
textureCreateInfo.Format = Refresh.ColorFormat.R8G8B8A8;
textureCreateInfo.IsCube = false;
textureCreateInfo.LevelCount = 1;
textureCreateInfo.SampleCount = Refresh.SampleCount.One;
textureCreateInfo.UsageFlags = Refresh.TextureUsageFlags.SamplerBit;
var texture = new Texture(device, ref textureCreateInfo);
texture.SetData(pixels, (uint) (width * height * 4));
texture.SetData(pixels, (uint)(width * height * 4));
Refresh.Refresh_Image_Free(pixels);
return texture;
}
public Texture(RefreshDevice device, ref Refresh.TextureCreateInfo textureCreateInfo) : base(device)
public static Texture CreateTexture2D(
RefreshDevice device,
uint width,
uint height,
Refresh.ColorFormat format,
Refresh.TextureUsageFlags usageFlags,
Refresh.SampleCount sampleCount = Refresh.SampleCount.One,
uint levelCount = 1
)
{
var textureCreateInfo = new Campari.TextureCreateInfo
{
Width = width,
Height = height,
Depth = 1,
IsCube = false,
SampleCount = sampleCount,
LevelCount = levelCount,
Format = format,
UsageFlags = usageFlags
};
return new Texture(device, ref textureCreateInfo);
}
public static Texture CreateTexture3D(
RefreshDevice device,
uint width,
uint height,
uint depth,
Refresh.ColorFormat format,
Refresh.TextureUsageFlags usageFlags,
Refresh.SampleCount sampleCount = Refresh.SampleCount.One,
uint levelCount = 1
)
{
var textureCreateInfo = new Campari.TextureCreateInfo
{
Width = width,
Height = height,
Depth = depth,
IsCube = false,
SampleCount = sampleCount,
LevelCount = levelCount,
Format = format,
UsageFlags = usageFlags
};
return new Texture(device, ref textureCreateInfo);
}
public static Texture CreateTextureCube(
RefreshDevice device,
uint size,
Refresh.ColorFormat format,
Refresh.TextureUsageFlags usageFlags,
Refresh.SampleCount sampleCount = Refresh.SampleCount.One,
uint levelCount = 1
)
{
var textureCreateInfo = new Campari.TextureCreateInfo
{
Width = size,
Height = size,
Depth = 1,
IsCube = true,
SampleCount = sampleCount,
LevelCount = levelCount,
Format = format,
UsageFlags = usageFlags
};
return new Texture(device, ref textureCreateInfo);
}
public Texture(RefreshDevice device, ref Campari.TextureCreateInfo textureCreateInfo) : base(device)
{
var refreshTextureCreateInfo = textureCreateInfo.ToRefreshTextureCreateInfo();
Handle = Refresh.Refresh_CreateTexture(
device.Handle,
ref textureCreateInfo
ref refreshTextureCreateInfo
);
Format = textureCreateInfo.format;
Width = textureCreateInfo.width;
Height = textureCreateInfo.height;
Format = textureCreateInfo.Format;
Width = textureCreateInfo.Width;
Height = textureCreateInfo.Height;
}
public void SetData(IntPtr data, uint dataLengthInBytes)
@ -57,8 +134,8 @@ namespace Campari
textureSlice.texture = Handle;
textureSlice.rectangle.x = 0;
textureSlice.rectangle.y = 0;
textureSlice.rectangle.w = (int) Width;
textureSlice.rectangle.h = (int) Height;
textureSlice.rectangle.w = (int)Width;
textureSlice.rectangle.h = (int)Height;
textureSlice.level = 0;
textureSlice.layer = 0;
textureSlice.depth = 0;
@ -70,5 +147,17 @@ namespace Campari
dataLengthInBytes
);
}
public void SetData(ref TextureSlice textureSlice, IntPtr data, uint dataLengthInBytes)
{
var refreshTextureSlice = textureSlice.ToRefreshTextureSlice();
Refresh.Refresh_SetTextureData(
Device.Handle,
ref refreshTextureSlice,
data,
dataLengthInBytes
);
}
}
}