bunch of Refresh api changes, plus more validation

pull/31/head
Caleb Cornett 2022-11-04 23:20:07 -04:00
parent 1b38f8606b
commit 05593d9bf1
7 changed files with 48 additions and 115 deletions

View File

@ -16,6 +16,7 @@ namespace MoonWorks.Graphics
GraphicsPipeline currentGraphicsPipeline; GraphicsPipeline currentGraphicsPipeline;
ComputePipeline currentComputePipeline; ComputePipeline currentComputePipeline;
bool renderPassActive; bool renderPassActive;
SampleCount currentSampleCount;
// called from RefreshDevice // called from RefreshDevice
internal CommandBuffer(GraphicsDevice device, IntPtr handle) internal CommandBuffer(GraphicsDevice device, IntPtr handle)
@ -25,6 +26,7 @@ namespace MoonWorks.Graphics
currentGraphicsPipeline = null; currentGraphicsPipeline = null;
currentComputePipeline = null; currentComputePipeline = null;
renderPassActive = false; renderPassActive = false;
currentSampleCount = SampleCount.One;
} }
// FIXME: we can probably use the NativeMemory functions to not have to generate arrays here // FIXME: we can probably use the NativeMemory functions to not have to generate arrays here
@ -55,7 +57,6 @@ namespace MoonWorks.Graphics
Refresh.Refresh_BeginRenderPass( Refresh.Refresh_BeginRenderPass(
Device.Handle, Device.Handle,
Handle, Handle,
IntPtr.Zero,
(IntPtr) pColorAttachmentInfos, (IntPtr) pColorAttachmentInfos,
(uint) colorAttachmentInfos.Length, (uint) colorAttachmentInfos.Length,
IntPtr.Zero IntPtr.Zero
@ -78,7 +79,7 @@ namespace MoonWorks.Graphics
) )
{ {
#if DEBUG #if DEBUG
AssertValidDepthAttachments(depthStencilAttachmentInfo); AssertValidDepthAttachment(depthStencilAttachmentInfo);
AssertValidColorAttachments(colorAttachmentInfos, false); AssertValidColorAttachments(colorAttachmentInfos, false);
#endif #endif
@ -96,88 +97,6 @@ namespace MoonWorks.Graphics
Refresh.Refresh_BeginRenderPass( Refresh.Refresh_BeginRenderPass(
Device.Handle, Device.Handle,
Handle, Handle,
IntPtr.Zero,
pColorAttachmentInfos,
(uint) colorAttachmentInfos.Length,
&refreshDepthStencilAttachmentInfo
);
}
renderPassActive = true;
}
/// <summary>
/// Begins a render pass.
/// All render state, resource binding, and draw commands must be made within a render pass.
/// It is an error to call this after calling BeginRenderPass but before calling EndRenderPass.
/// </summary>
/// <param name="renderArea">The rectangle that should be drawn to on the attachments.</param>
/// <param name="colorAttachmentInfos">The color attachments to use in the render pass.</param>
public unsafe void BeginRenderPass(
in Rect renderArea,
params ColorAttachmentInfo[] colorAttachmentInfos
)
{
#if DEBUG
AssertValidColorAttachments(colorAttachmentInfos, true);
#endif
var refreshColorAttachmentInfos = new Refresh.ColorAttachmentInfo[colorAttachmentInfos.Length];
for (var i = 0; i < colorAttachmentInfos.Length; i += 1)
{
refreshColorAttachmentInfos[i] = colorAttachmentInfos[i].ToRefresh();
}
fixed (Refresh.ColorAttachmentInfo* pColorAttachmentInfos = refreshColorAttachmentInfos)
{
Refresh.Refresh_BeginRenderPass(
Device.Handle,
Handle,
renderArea.ToRefresh(),
(IntPtr) pColorAttachmentInfos,
(uint) colorAttachmentInfos.Length,
IntPtr.Zero
);
}
renderPassActive = true;
}
/// <summary>
/// Begins a render pass.
/// All render state, resource binding, and draw commands must be made within a render pass.
/// It is an error to call this after calling BeginRenderPass but before calling EndRenderPass.
/// </summary>
/// <param name="renderArea">The rectangle that should be drawn to on the attachments.</param>
/// <param name="depthStencilAttachmentInfo">The depth stencil attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfos">The color attachments to use in the render pass.</param>
public unsafe void BeginRenderPass(
in Rect renderArea,
DepthStencilAttachmentInfo depthStencilAttachmentInfo,
params ColorAttachmentInfo[] colorAttachmentInfos
)
{
#if DEBUG
AssertValidDepthAttachments(depthStencilAttachmentInfo);
AssertValidColorAttachments(colorAttachmentInfos, false);
#endif
var refreshColorAttachmentInfos = new Refresh.ColorAttachmentInfo[colorAttachmentInfos.Length];
for (var i = 0; i < colorAttachmentInfos.Length; i += 1)
{
refreshColorAttachmentInfos[i] = colorAttachmentInfos[i].ToRefresh();
}
var refreshDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToRefresh();
fixed (Refresh.ColorAttachmentInfo* pColorAttachmentInfos = refreshColorAttachmentInfos)
{
Refresh.Refresh_BeginRenderPass(
Device.Handle,
Handle,
renderArea.ToRefresh(),
pColorAttachmentInfos, pColorAttachmentInfos,
(uint) colorAttachmentInfos.Length, (uint) colorAttachmentInfos.Length,
&refreshDepthStencilAttachmentInfo &refreshDepthStencilAttachmentInfo
@ -312,6 +231,15 @@ namespace MoonWorks.Graphics
GraphicsPipeline graphicsPipeline GraphicsPipeline graphicsPipeline
) )
{ {
#if DEBUG
AssertRenderPassActive();
if (graphicsPipeline.SampleCount != currentSampleCount)
{
throw new System.ArgumentException("The sample count of the bound GraphicsPipeline must match the sample count of the current render pass!");
}
#endif
Refresh.Refresh_BindGraphicsPipeline( Refresh.Refresh_BindGraphicsPipeline(
Device.Handle, Device.Handle,
Handle, Handle,
@ -1073,6 +1001,8 @@ namespace MoonWorks.Graphics
throw new System.ArgumentException("Render pass must contain at least one attachment!"); throw new System.ArgumentException("Render pass must contain at least one attachment!");
} }
currentSampleCount = (colorAttachmentInfos.Length > 0) ? colorAttachmentInfos[0].SampleCount : SampleCount.One;
if (colorAttachmentInfos.Length > 4) if (colorAttachmentInfos.Length > 4)
{ {
throw new System.ArgumentException("Render pass cannot have more than 4 color attachments!"); throw new System.ArgumentException("Render pass cannot have more than 4 color attachments!");
@ -1090,10 +1020,15 @@ namespace MoonWorks.Graphics
{ {
throw new System.ArgumentException("Render pass color attachment UsageFlags must include TextureUsageFlags.ColorTarget!"); throw new System.ArgumentException("Render pass color attachment UsageFlags must include TextureUsageFlags.ColorTarget!");
} }
if (colorAttachmentInfos[i].SampleCount != currentSampleCount)
{
throw new System.ArgumentException("All color attachments in a render pass must have the same SampleCount!");
}
} }
} }
private void AssertValidDepthAttachments(DepthStencilAttachmentInfo depthStencilAttachmentInfo) private void AssertValidDepthAttachment(DepthStencilAttachmentInfo depthStencilAttachmentInfo)
{ {
if (depthStencilAttachmentInfo.Texture == null || if (depthStencilAttachmentInfo.Texture == null ||
depthStencilAttachmentInfo.Texture.Handle == IntPtr.Zero) depthStencilAttachmentInfo.Texture.Handle == IntPtr.Zero)

View File

@ -110,10 +110,7 @@ namespace MoonWorks.Graphics
One, One,
Two, Two,
Four, Four,
Eight, Eight
Sixteen,
ThirtyTwo,
SixtyFour
} }
public enum CubeMapFace : uint public enum CubeMapFace : uint

View File

@ -209,25 +209,35 @@ namespace MoonWorks.Graphics
public LoadOp LoadOp; public LoadOp LoadOp;
public StoreOp StoreOp; public StoreOp StoreOp;
public ColorAttachmentInfo(Texture texture, Color clearColor, StoreOp storeOp = StoreOp.Store) public ColorAttachmentInfo(
Texture texture,
Color clearColor,
SampleCount sampleCount = SampleCount.One,
StoreOp storeOp = StoreOp.Store
)
{ {
Texture = texture; Texture = texture;
Depth = 0; Depth = 0;
Layer = 0; Layer = 0;
Level = 0; Level = 0;
SampleCount = SampleCount.One; SampleCount = sampleCount;
ClearColor = clearColor; ClearColor = clearColor;
LoadOp = LoadOp.Clear; LoadOp = LoadOp.Clear;
StoreOp = storeOp; StoreOp = storeOp;
} }
public ColorAttachmentInfo(Texture texture, LoadOp loadOp = LoadOp.DontCare, StoreOp storeOp = StoreOp.Store) public ColorAttachmentInfo(
Texture texture,
LoadOp loadOp = LoadOp.DontCare,
SampleCount sampleCount = SampleCount.One,
StoreOp storeOp = StoreOp.Store
)
{ {
Texture = texture; Texture = texture;
Depth = 0; Depth = 0;
Layer = 0; Layer = 0;
Level = 0; Level = 0;
SampleCount = SampleCount.One; SampleCount = sampleCount;
ClearColor = Color.White; ClearColor = Color.White;
LoadOp = loadOp; LoadOp = loadOp;
StoreOp = storeOp; StoreOp = storeOp;
@ -344,16 +354,13 @@ namespace MoonWorks.Graphics
public struct ColorAttachmentDescription public struct ColorAttachmentDescription
{ {
public TextureFormat Format; public TextureFormat Format;
public SampleCount SampleCount;
public ColorAttachmentBlendState BlendState; public ColorAttachmentBlendState BlendState;
public ColorAttachmentDescription( public ColorAttachmentDescription(
TextureFormat format, TextureFormat format,
ColorAttachmentBlendState blendState, ColorAttachmentBlendState blendState
SampleCount sampleCount = SampleCount.One
) { ) {
Format = format; Format = format;
SampleCount = sampleCount;
BlendState = blendState; BlendState = blendState;
} }
} }

View File

@ -14,6 +14,7 @@ namespace MoonWorks.Graphics
public GraphicsShaderInfo VertexShaderInfo { get; } public GraphicsShaderInfo VertexShaderInfo { get; }
public GraphicsShaderInfo FragmentShaderInfo { get; } public GraphicsShaderInfo FragmentShaderInfo { get; }
internal SampleCount SampleCount { get; }
public unsafe GraphicsPipeline( public unsafe GraphicsPipeline(
GraphicsDevice device, GraphicsDevice device,
@ -46,7 +47,6 @@ namespace MoonWorks.Graphics
for (var i = 0; i < attachmentInfo.ColorAttachmentDescriptions.Length; i += 1) for (var i = 0; i < attachmentInfo.ColorAttachmentDescriptions.Length; i += 1)
{ {
colorAttachmentDescriptions[i].format = (Refresh.TextureFormat) attachmentInfo.ColorAttachmentDescriptions[i].Format; colorAttachmentDescriptions[i].format = (Refresh.TextureFormat) attachmentInfo.ColorAttachmentDescriptions[i].Format;
colorAttachmentDescriptions[i].sampleCount = (Refresh.SampleCount) attachmentInfo.ColorAttachmentDescriptions[i].SampleCount;
colorAttachmentDescriptions[i].blendState = attachmentInfo.ColorAttachmentDescriptions[i].BlendState.ToRefresh(); colorAttachmentDescriptions[i].blendState = attachmentInfo.ColorAttachmentDescriptions[i].BlendState.ToRefresh();
} }
@ -112,6 +112,7 @@ namespace MoonWorks.Graphics
VertexShaderInfo = vertexShaderInfo; VertexShaderInfo = vertexShaderInfo;
FragmentShaderInfo = fragmentShaderInfo; FragmentShaderInfo = fragmentShaderInfo;
SampleCount = multisampleState.MultisampleCount;
} }
} }
} }

View File

@ -15,7 +15,6 @@ namespace MoonWorks.Graphics
public TextureFormat Format { get; } public TextureFormat Format { get; }
public bool IsCube { get; } public bool IsCube { get; }
public uint LevelCount { get; } public uint LevelCount { get; }
public SampleCount SampleCount { get; }
public TextureUsageFlags UsageFlags { get; } public TextureUsageFlags UsageFlags { get; }
protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyTexture; protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyTexture;
@ -46,7 +45,6 @@ namespace MoonWorks.Graphics
textureCreateInfo.Format = TextureFormat.R8G8B8A8; textureCreateInfo.Format = TextureFormat.R8G8B8A8;
textureCreateInfo.IsCube = false; textureCreateInfo.IsCube = false;
textureCreateInfo.LevelCount = 1; textureCreateInfo.LevelCount = 1;
textureCreateInfo.SampleCount = SampleCount.One;
textureCreateInfo.UsageFlags = TextureUsageFlags.Sampler; textureCreateInfo.UsageFlags = TextureUsageFlags.Sampler;
var texture = new Texture(device, textureCreateInfo); var texture = new Texture(device, textureCreateInfo);
@ -83,12 +81,12 @@ namespace MoonWorks.Graphics
if (isCube) if (isCube)
{ {
texture = CreateTextureCube(graphicsDevice, (uint) width, format, TextureUsageFlags.Sampler, SampleCount.One, (uint) levels); texture = CreateTextureCube(graphicsDevice, (uint) width, format, TextureUsageFlags.Sampler, (uint) levels);
faces = 6; faces = 6;
} }
else else
{ {
texture = CreateTexture2D(graphicsDevice, (uint) width, (uint) height, format, TextureUsageFlags.Sampler, SampleCount.One, (uint) levels); texture = CreateTexture2D(graphicsDevice, (uint) width, (uint) height, format, TextureUsageFlags.Sampler, (uint) levels);
faces = 1; faces = 1;
} }
@ -124,7 +122,6 @@ namespace MoonWorks.Graphics
/// <param name="height">The height of the texture.</param> /// <param name="height">The height of the texture.</param>
/// <param name="format">The format of the texture.</param> /// <param name="format">The format of the texture.</param>
/// <param name="usageFlags">Specifies how the texture will be used.</param> /// <param name="usageFlags">Specifies how the texture will be used.</param>
/// <param name="sampleCount">Specifies the multisample count.</param>
/// <param name="levelCount">Specifies the number of mip levels.</param> /// <param name="levelCount">Specifies the number of mip levels.</param>
public static Texture CreateTexture2D( public static Texture CreateTexture2D(
GraphicsDevice device, GraphicsDevice device,
@ -132,7 +129,6 @@ namespace MoonWorks.Graphics
uint height, uint height,
TextureFormat format, TextureFormat format,
TextureUsageFlags usageFlags, TextureUsageFlags usageFlags,
SampleCount sampleCount = SampleCount.One,
uint levelCount = 1 uint levelCount = 1
) )
{ {
@ -142,7 +138,6 @@ namespace MoonWorks.Graphics
Height = height, Height = height,
Depth = 1, Depth = 1,
IsCube = false, IsCube = false,
SampleCount = sampleCount,
LevelCount = levelCount, LevelCount = levelCount,
Format = format, Format = format,
UsageFlags = usageFlags UsageFlags = usageFlags
@ -160,7 +155,6 @@ namespace MoonWorks.Graphics
/// <param name="depth">The depth of the texture.</param> /// <param name="depth">The depth of the texture.</param>
/// <param name="format">The format of the texture.</param> /// <param name="format">The format of the texture.</param>
/// <param name="usageFlags">Specifies how the texture will be used.</param> /// <param name="usageFlags">Specifies how the texture will be used.</param>
/// <param name="sampleCount">Specifies the multisample count.</param>
/// <param name="levelCount">Specifies the number of mip levels.</param> /// <param name="levelCount">Specifies the number of mip levels.</param>
public static Texture CreateTexture3D( public static Texture CreateTexture3D(
GraphicsDevice device, GraphicsDevice device,
@ -169,7 +163,6 @@ namespace MoonWorks.Graphics
uint depth, uint depth,
TextureFormat format, TextureFormat format,
TextureUsageFlags usageFlags, TextureUsageFlags usageFlags,
SampleCount sampleCount = SampleCount.One,
uint levelCount = 1 uint levelCount = 1
) )
{ {
@ -179,7 +172,6 @@ namespace MoonWorks.Graphics
Height = height, Height = height,
Depth = depth, Depth = depth,
IsCube = false, IsCube = false,
SampleCount = sampleCount,
LevelCount = levelCount, LevelCount = levelCount,
Format = format, Format = format,
UsageFlags = usageFlags UsageFlags = usageFlags
@ -195,14 +187,12 @@ namespace MoonWorks.Graphics
/// <param name="size">The length of one side of the cube.</param> /// <param name="size">The length of one side of the cube.</param>
/// <param name="format">The format of the texture.</param> /// <param name="format">The format of the texture.</param>
/// <param name="usageFlags">Specifies how the texture will be used.</param> /// <param name="usageFlags">Specifies how the texture will be used.</param>
/// <param name="sampleCount">Specifies the multisample count.</param>
/// <param name="levelCount">Specifies the number of mip levels.</param> /// <param name="levelCount">Specifies the number of mip levels.</param>
public static Texture CreateTextureCube( public static Texture CreateTextureCube(
GraphicsDevice device, GraphicsDevice device,
uint size, uint size,
TextureFormat format, TextureFormat format,
TextureUsageFlags usageFlags, TextureUsageFlags usageFlags,
SampleCount sampleCount = SampleCount.One,
uint levelCount = 1 uint levelCount = 1
) )
{ {
@ -212,7 +202,6 @@ namespace MoonWorks.Graphics
Height = size, Height = size,
Depth = 1, Depth = 1,
IsCube = true, IsCube = true,
SampleCount = sampleCount,
LevelCount = levelCount, LevelCount = levelCount,
Format = format, Format = format,
UsageFlags = usageFlags UsageFlags = usageFlags
@ -241,7 +230,6 @@ namespace MoonWorks.Graphics
Height = textureCreateInfo.Height; Height = textureCreateInfo.Height;
Depth = textureCreateInfo.Depth; Depth = textureCreateInfo.Depth;
IsCube = textureCreateInfo.IsCube; IsCube = textureCreateInfo.IsCube;
SampleCount = textureCreateInfo.SampleCount;
LevelCount = textureCreateInfo.LevelCount; LevelCount = textureCreateInfo.LevelCount;
UsageFlags = textureCreateInfo.UsageFlags; UsageFlags = textureCreateInfo.UsageFlags;
} }
@ -265,7 +253,6 @@ namespace MoonWorks.Graphics
Height = height; Height = height;
Depth = 1; Depth = 1;
IsCube = false; IsCube = false;
SampleCount = SampleCount.One;
LevelCount = 1; LevelCount = 1;
UsageFlags = TextureUsageFlags.ColorTarget; UsageFlags = TextureUsageFlags.ColorTarget;
} }

View File

@ -13,5 +13,13 @@
MultisampleCount = SampleCount.One, MultisampleCount = SampleCount.One,
SampleMask = uint.MaxValue SampleMask = uint.MaxValue
}; };
public MultisampleState(
SampleCount sampleCount,
uint sampleMask = uint.MaxValue
) {
MultisampleCount = sampleCount;
SampleMask = sampleMask;
}
} }
} }

View File

@ -8,7 +8,6 @@ namespace MoonWorks.Graphics
public uint Height; public uint Height;
public uint Depth; public uint Depth;
public bool IsCube; public bool IsCube;
public SampleCount SampleCount;
public uint LevelCount; public uint LevelCount;
public TextureFormat Format; public TextureFormat Format;
public TextureUsageFlags UsageFlags; public TextureUsageFlags UsageFlags;
@ -21,7 +20,6 @@ namespace MoonWorks.Graphics
height = Height, height = Height,
depth = Depth, depth = Depth,
isCube = Conversions.BoolToByte(IsCube), isCube = Conversions.BoolToByte(IsCube),
sampleCount = (Refresh.SampleCount) SampleCount,
levelCount = LevelCount, levelCount = LevelCount,
format = (Refresh.TextureFormat) Format, format = (Refresh.TextureFormat) Format,
usageFlags = (Refresh.TextureUsageFlags) UsageFlags usageFlags = (Refresh.TextureUsageFlags) UsageFlags