CommandBuffer is now a pooled class + more state validation

pull/53/head
cosmonaut 2024-01-18 12:27:34 -08:00
parent e50fb472b1
commit 0df2944ccf
3 changed files with 167 additions and 7 deletions

View File

@ -8,12 +8,14 @@ namespace MoonWorks.Graphics
/// Command buffers are used to apply render state and issue draw calls. /// Command buffers are used to apply render state and issue draw calls.
/// NOTE: it is not recommended to hold references to command buffers long term. /// NOTE: it is not recommended to hold references to command buffers long term.
/// </summary> /// </summary>
public struct CommandBuffer public class CommandBuffer
{ {
public GraphicsDevice Device { get; } public GraphicsDevice Device { get; }
public IntPtr Handle { get; } public IntPtr Handle { get; internal set; }
#if DEBUG #if DEBUG
bool swapchainTextureAcquired;
GraphicsPipeline currentGraphicsPipeline; GraphicsPipeline currentGraphicsPipeline;
ComputePipeline currentComputePipeline; ComputePipeline currentComputePipeline;
bool renderPassActive; bool renderPassActive;
@ -26,15 +28,31 @@ namespace MoonWorks.Graphics
bool hasDepthStencilAttachment; bool hasDepthStencilAttachment;
SampleCount depthStencilAttachmentSampleCount; SampleCount depthStencilAttachmentSampleCount;
TextureFormat depthStencilFormat; TextureFormat depthStencilFormat;
internal bool Submitted;
#endif #endif
// called from RefreshDevice // called from CommandBufferPool
internal CommandBuffer(GraphicsDevice device, IntPtr handle) internal CommandBuffer(GraphicsDevice device)
{ {
Device = device; Device = device;
Handle = handle; Handle = IntPtr.Zero;
#if DEBUG #if DEBUG
ResetStateTracking();
#endif
}
internal void SetHandle(nint handle)
{
Handle = handle;
}
#if DEBUG
internal void ResetStateTracking()
{
swapchainTextureAcquired = false;
currentGraphicsPipeline = null; currentGraphicsPipeline = null;
currentComputePipeline = null; currentComputePipeline = null;
renderPassActive = false; renderPassActive = false;
@ -46,8 +64,10 @@ namespace MoonWorks.Graphics
colorFormatThree = TextureFormat.R8G8B8A8; colorFormatThree = TextureFormat.R8G8B8A8;
colorFormatFour = TextureFormat.R8G8B8A8; colorFormatFour = TextureFormat.R8G8B8A8;
depthStencilFormat = TextureFormat.D16; depthStencilFormat = TextureFormat.D16;
#endif
Submitted = false;
} }
#endif
/// <summary> /// <summary>
/// Begins a render pass. /// Begins a render pass.
@ -59,6 +79,7 @@ namespace MoonWorks.Graphics
in ColorAttachmentInfo colorAttachmentInfo in ColorAttachmentInfo colorAttachmentInfo
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertTextureNotNull(colorAttachmentInfo); AssertTextureNotNull(colorAttachmentInfo);
AssertColorTarget(colorAttachmentInfo); AssertColorTarget(colorAttachmentInfo);
#endif #endif
@ -95,6 +116,7 @@ namespace MoonWorks.Graphics
in ColorAttachmentInfo colorAttachmentInfoTwo in ColorAttachmentInfo colorAttachmentInfoTwo
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertTextureNotNull(colorAttachmentInfoOne); AssertTextureNotNull(colorAttachmentInfoOne);
AssertColorTarget(colorAttachmentInfoOne); AssertColorTarget(colorAttachmentInfoOne);
@ -140,6 +162,8 @@ namespace MoonWorks.Graphics
in ColorAttachmentInfo colorAttachmentInfoThree in ColorAttachmentInfo colorAttachmentInfoThree
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertTextureNotNull(colorAttachmentInfoOne); AssertTextureNotNull(colorAttachmentInfoOne);
AssertColorTarget(colorAttachmentInfoOne); AssertColorTarget(colorAttachmentInfoOne);
@ -193,6 +217,8 @@ namespace MoonWorks.Graphics
in ColorAttachmentInfo colorAttachmentInfoFour in ColorAttachmentInfo colorAttachmentInfoFour
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertTextureNotNull(colorAttachmentInfoOne); AssertTextureNotNull(colorAttachmentInfoOne);
AssertColorTarget(colorAttachmentInfoOne); AssertColorTarget(colorAttachmentInfoOne);
@ -246,6 +272,7 @@ namespace MoonWorks.Graphics
in DepthStencilAttachmentInfo depthStencilAttachmentInfo in DepthStencilAttachmentInfo depthStencilAttachmentInfo
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertValidDepthAttachment(depthStencilAttachmentInfo); AssertValidDepthAttachment(depthStencilAttachmentInfo);
#endif #endif
@ -279,6 +306,7 @@ namespace MoonWorks.Graphics
in ColorAttachmentInfo colorAttachmentInfo in ColorAttachmentInfo colorAttachmentInfo
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertValidDepthAttachment(depthStencilAttachmentInfo); AssertValidDepthAttachment(depthStencilAttachmentInfo);
AssertTextureNotNull(colorAttachmentInfo); AssertTextureNotNull(colorAttachmentInfo);
@ -324,6 +352,7 @@ namespace MoonWorks.Graphics
in ColorAttachmentInfo colorAttachmentInfoTwo in ColorAttachmentInfo colorAttachmentInfoTwo
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertValidDepthAttachment(depthStencilAttachmentInfo); AssertValidDepthAttachment(depthStencilAttachmentInfo);
AssertTextureNotNull(colorAttachmentInfoOne); AssertTextureNotNull(colorAttachmentInfoOne);
@ -377,6 +406,7 @@ namespace MoonWorks.Graphics
in ColorAttachmentInfo colorAttachmentInfoThree in ColorAttachmentInfo colorAttachmentInfoThree
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertValidDepthAttachment(depthStencilAttachmentInfo); AssertValidDepthAttachment(depthStencilAttachmentInfo);
AssertTextureNotNull(colorAttachmentInfoOne); AssertTextureNotNull(colorAttachmentInfoOne);
@ -438,6 +468,7 @@ namespace MoonWorks.Graphics
in ColorAttachmentInfo colorAttachmentInfoFour in ColorAttachmentInfo colorAttachmentInfoFour
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertValidDepthAttachment(depthStencilAttachmentInfo); AssertValidDepthAttachment(depthStencilAttachmentInfo);
AssertTextureNotNull(colorAttachmentInfoOne); AssertTextureNotNull(colorAttachmentInfoOne);
@ -494,6 +525,10 @@ namespace MoonWorks.Graphics
public void BindComputePipeline( public void BindComputePipeline(
ComputePipeline computePipeline ComputePipeline computePipeline
) { ) {
#if DEBUG
AssertNotSubmitted();
#endif
Refresh.Refresh_BindComputePipeline( Refresh.Refresh_BindComputePipeline(
Device.Handle, Device.Handle,
Handle, Handle,
@ -513,6 +548,7 @@ namespace MoonWorks.Graphics
Buffer buffer Buffer buffer
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertComputePipelineBound(); AssertComputePipelineBound();
AssertComputeBufferCount(1); AssertComputeBufferCount(1);
#endif #endif
@ -537,6 +573,7 @@ namespace MoonWorks.Graphics
Buffer bufferTwo Buffer bufferTwo
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertComputePipelineBound(); AssertComputePipelineBound();
AssertComputeBufferCount(2); AssertComputeBufferCount(2);
#endif #endif
@ -564,6 +601,7 @@ namespace MoonWorks.Graphics
Buffer bufferThree Buffer bufferThree
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertComputePipelineBound(); AssertComputePipelineBound();
AssertComputeBufferCount(3); AssertComputeBufferCount(3);
#endif #endif
@ -594,6 +632,7 @@ namespace MoonWorks.Graphics
Buffer bufferFour Buffer bufferFour
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertComputePipelineBound(); AssertComputePipelineBound();
AssertComputeBufferCount(4); AssertComputeBufferCount(4);
#endif #endif
@ -619,6 +658,7 @@ namespace MoonWorks.Graphics
in Span<Buffer> buffers in Span<Buffer> buffers
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertComputePipelineBound(); AssertComputePipelineBound();
AssertComputeBufferCount(buffers.Length); AssertComputeBufferCount(buffers.Length);
#endif #endif
@ -645,6 +685,7 @@ namespace MoonWorks.Graphics
Texture texture Texture texture
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertComputePipelineBound(); AssertComputePipelineBound();
AssertComputeTextureCount(1); AssertComputeTextureCount(1);
#endif #endif
@ -669,6 +710,7 @@ namespace MoonWorks.Graphics
Texture textureTwo Texture textureTwo
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertComputePipelineBound(); AssertComputePipelineBound();
AssertComputeTextureCount(2); AssertComputeTextureCount(2);
#endif #endif
@ -696,6 +738,7 @@ namespace MoonWorks.Graphics
Texture textureThree Texture textureThree
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertComputePipelineBound(); AssertComputePipelineBound();
AssertComputeTextureCount(3); AssertComputeTextureCount(3);
#endif #endif
@ -726,6 +769,7 @@ namespace MoonWorks.Graphics
Texture textureFour Texture textureFour
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertComputePipelineBound(); AssertComputePipelineBound();
AssertComputeTextureCount(4); AssertComputeTextureCount(4);
#endif #endif
@ -751,6 +795,7 @@ namespace MoonWorks.Graphics
in Span<Texture> textures in Span<Texture> textures
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertComputePipelineBound(); AssertComputePipelineBound();
AssertComputeTextureCount(textures.Length); AssertComputeTextureCount(textures.Length);
#endif #endif
@ -783,6 +828,7 @@ namespace MoonWorks.Graphics
uint computeParamOffset uint computeParamOffset
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertComputePipelineBound(); AssertComputePipelineBound();
if (groupCountX < 1 || groupCountY < 1 || groupCountZ < 1) if (groupCountX < 1 || groupCountY < 1 || groupCountZ < 1)
@ -809,6 +855,7 @@ namespace MoonWorks.Graphics
GraphicsPipeline graphicsPipeline GraphicsPipeline graphicsPipeline
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertRenderPassActive(); AssertRenderPassActive();
AssertRenderPassPipelineFormatMatch(graphicsPipeline); AssertRenderPassPipelineFormatMatch(graphicsPipeline);
@ -846,6 +893,7 @@ namespace MoonWorks.Graphics
public void SetViewport(in Viewport viewport) public void SetViewport(in Viewport viewport)
{ {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertRenderPassActive(); AssertRenderPassActive();
#endif #endif
@ -862,6 +910,7 @@ namespace MoonWorks.Graphics
public void SetScissor(in Rect scissor) public void SetScissor(in Rect scissor)
{ {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertRenderPassActive(); AssertRenderPassActive();
if (scissor.X < 0 || scissor.Y < 0 || scissor.W <= 0 || scissor.H <= 0) if (scissor.X < 0 || scissor.Y < 0 || scissor.W <= 0 || scissor.H <= 0)
@ -887,6 +936,7 @@ namespace MoonWorks.Graphics
uint firstBinding = 0 uint firstBinding = 0
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
#endif #endif
@ -918,6 +968,7 @@ namespace MoonWorks.Graphics
uint firstBinding = 0 uint firstBinding = 0
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
#endif #endif
@ -954,6 +1005,7 @@ namespace MoonWorks.Graphics
uint firstBinding = 0 uint firstBinding = 0
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
#endif #endif
@ -994,6 +1046,7 @@ namespace MoonWorks.Graphics
uint firstBinding = 0 uint firstBinding = 0
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
#endif #endif
@ -1030,6 +1083,7 @@ namespace MoonWorks.Graphics
uint firstBinding = 0 uint firstBinding = 0
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
#endif #endif
@ -1064,6 +1118,10 @@ namespace MoonWorks.Graphics
uint offset = 0 uint offset = 0
) )
{ {
#if DEBUG
AssertNotSubmitted();
#endif
Refresh.Refresh_BindIndexBuffer( Refresh.Refresh_BindIndexBuffer(
Device.Handle, Device.Handle,
Handle, Handle,
@ -1081,6 +1139,7 @@ namespace MoonWorks.Graphics
in TextureSamplerBinding textureSamplerBinding in TextureSamplerBinding textureSamplerBinding
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
AssertVertexSamplerCount(1); AssertVertexSamplerCount(1);
AssertTextureSamplerBindingNonNull(textureSamplerBinding); AssertTextureSamplerBindingNonNull(textureSamplerBinding);
@ -1111,6 +1170,7 @@ namespace MoonWorks.Graphics
in TextureSamplerBinding textureSamplerBindingTwo in TextureSamplerBinding textureSamplerBindingTwo
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
AssertVertexSamplerCount(2); AssertVertexSamplerCount(2);
AssertTextureSamplerBindingNonNull(textureSamplerBindingOne); AssertTextureSamplerBindingNonNull(textureSamplerBindingOne);
@ -1148,6 +1208,7 @@ namespace MoonWorks.Graphics
in TextureSamplerBinding textureSamplerBindingThree in TextureSamplerBinding textureSamplerBindingThree
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
AssertVertexSamplerCount(3); AssertVertexSamplerCount(3);
AssertTextureSamplerBindingNonNull(textureSamplerBindingOne); AssertTextureSamplerBindingNonNull(textureSamplerBindingOne);
@ -1191,6 +1252,7 @@ namespace MoonWorks.Graphics
in TextureSamplerBinding textureSamplerBindingFour in TextureSamplerBinding textureSamplerBindingFour
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
AssertVertexSamplerCount(4); AssertVertexSamplerCount(4);
AssertTextureSamplerBindingNonNull(textureSamplerBindingOne); AssertTextureSamplerBindingNonNull(textureSamplerBindingOne);
@ -1232,6 +1294,7 @@ namespace MoonWorks.Graphics
in Span<TextureSamplerBinding> textureSamplerBindings in Span<TextureSamplerBinding> textureSamplerBindings
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
AssertVertexSamplerCount(textureSamplerBindings.Length); AssertVertexSamplerCount(textureSamplerBindings.Length);
#endif #endif
@ -1266,6 +1329,7 @@ namespace MoonWorks.Graphics
in TextureSamplerBinding textureSamplerBinding in TextureSamplerBinding textureSamplerBinding
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
AssertFragmentSamplerCount(1); AssertFragmentSamplerCount(1);
AssertTextureSamplerBindingNonNull(textureSamplerBinding); AssertTextureSamplerBindingNonNull(textureSamplerBinding);
@ -1296,6 +1360,7 @@ namespace MoonWorks.Graphics
in TextureSamplerBinding textureSamplerBindingTwo in TextureSamplerBinding textureSamplerBindingTwo
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
AssertFragmentSamplerCount(2); AssertFragmentSamplerCount(2);
AssertTextureSamplerBindingNonNull(textureSamplerBindingOne); AssertTextureSamplerBindingNonNull(textureSamplerBindingOne);
@ -1333,6 +1398,7 @@ namespace MoonWorks.Graphics
in TextureSamplerBinding textureSamplerBindingThree in TextureSamplerBinding textureSamplerBindingThree
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
AssertFragmentSamplerCount(3); AssertFragmentSamplerCount(3);
AssertTextureSamplerBindingNonNull(textureSamplerBindingOne); AssertTextureSamplerBindingNonNull(textureSamplerBindingOne);
@ -1376,6 +1442,7 @@ namespace MoonWorks.Graphics
in TextureSamplerBinding textureSamplerBindingFour in TextureSamplerBinding textureSamplerBindingFour
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
AssertFragmentSamplerCount(4); AssertFragmentSamplerCount(4);
AssertTextureSamplerBindingNonNull(textureSamplerBindingOne); AssertTextureSamplerBindingNonNull(textureSamplerBindingOne);
@ -1417,6 +1484,7 @@ namespace MoonWorks.Graphics
in Span<TextureSamplerBinding> textureSamplerBindings in Span<TextureSamplerBinding> textureSamplerBindings
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
AssertFragmentSamplerCount(textureSamplerBindings.Length); AssertFragmentSamplerCount(textureSamplerBindings.Length);
#endif #endif
@ -1452,6 +1520,7 @@ namespace MoonWorks.Graphics
uint size uint size
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
if (currentGraphicsPipeline.VertexShaderInfo.UniformBufferSize == 0) if (currentGraphicsPipeline.VertexShaderInfo.UniformBufferSize == 0)
@ -1491,6 +1560,7 @@ namespace MoonWorks.Graphics
uint size uint size
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
if (currentGraphicsPipeline.FragmentShaderInfo.UniformBufferSize == 0) if (currentGraphicsPipeline.FragmentShaderInfo.UniformBufferSize == 0)
@ -1530,6 +1600,7 @@ namespace MoonWorks.Graphics
uint size uint size
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertComputePipelineBound(); AssertComputePipelineBound();
if (currentComputePipeline.ComputeShaderInfo.UniformBufferSize == 0) if (currentComputePipeline.ComputeShaderInfo.UniformBufferSize == 0)
@ -1579,6 +1650,7 @@ namespace MoonWorks.Graphics
) )
{ {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
#endif #endif
@ -1611,6 +1683,7 @@ namespace MoonWorks.Graphics
) )
{ {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
#endif #endif
@ -1640,6 +1713,7 @@ namespace MoonWorks.Graphics
) )
{ {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
#endif #endif
@ -1672,6 +1746,7 @@ namespace MoonWorks.Graphics
) )
{ {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
#endif #endif
@ -1693,6 +1768,10 @@ namespace MoonWorks.Graphics
/// </summary> /// </summary>
public void EndRenderPass() public void EndRenderPass()
{ {
#if DEBUG
AssertNotSubmitted();
#endif
Refresh.Refresh_EndRenderPass( Refresh.Refresh_EndRenderPass(
Device.Handle, Device.Handle,
Handle Handle
@ -1716,10 +1795,17 @@ namespace MoonWorks.Graphics
Window window Window window
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted();
if (!window.Claimed) if (!window.Claimed)
{ {
throw new System.InvalidOperationException("Cannot acquire swapchain texture, window has not been claimed!"); throw new System.InvalidOperationException("Cannot acquire swapchain texture, window has not been claimed!");
} }
if (swapchainTextureAcquired)
{
throw new System.InvalidOperationException("Cannot acquire two swapchain textures on the same command buffer!");
}
#endif #endif
var texturePtr = Refresh.Refresh_AcquireSwapchainTexture( var texturePtr = Refresh.Refresh_AcquireSwapchainTexture(
@ -1741,6 +1827,10 @@ namespace MoonWorks.Graphics
window.SwapchainTexture.Height = height; window.SwapchainTexture.Height = height;
window.SwapchainTexture.Format = window.SwapchainFormat; window.SwapchainTexture.Format = window.SwapchainFormat;
#if DEBUG
swapchainTextureAcquired = true;
#endif
return window.SwapchainTexture; return window.SwapchainTexture;
} }
@ -1804,6 +1894,7 @@ namespace MoonWorks.Graphics
) )
{ {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertRenderPassInactive("Cannot copy during render pass!"); AssertRenderPassInactive("Cannot copy during render pass!");
AssertNonEmptyCopy(dataLengthInBytes); AssertNonEmptyCopy(dataLengthInBytes);
AssertBufferBoundsCheck(buffer.Size, bufferOffsetInBytes, dataLengthInBytes); AssertBufferBoundsCheck(buffer.Size, bufferOffsetInBytes, dataLengthInBytes);
@ -1841,6 +1932,7 @@ namespace MoonWorks.Graphics
var dataOffsetInBytes = (int) startElement * elementSize; var dataOffsetInBytes = (int) startElement * elementSize;
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertRenderPassInactive("Cannot copy during render pass!"); AssertRenderPassInactive("Cannot copy during render pass!");
AssertNonEmptyCopy(dataLengthInBytes); AssertNonEmptyCopy(dataLengthInBytes);
AssertBufferBoundsCheck(buffer.Size, bufferOffsetInBytes, dataLengthInBytes); AssertBufferBoundsCheck(buffer.Size, bufferOffsetInBytes, dataLengthInBytes);
@ -1891,6 +1983,7 @@ namespace MoonWorks.Graphics
var offsetLengthInBytes = (uint) elementSize * bufferOffsetInElements; var offsetLengthInBytes = (uint) elementSize * bufferOffsetInElements;
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertRenderPassInactive("Cannot copy during render pass!"); AssertRenderPassInactive("Cannot copy during render pass!");
AssertNonEmptyCopy((uint) (elementSize * numElements)); AssertNonEmptyCopy((uint) (elementSize * numElements));
AssertBufferBoundsCheck(buffer.Size, offsetLengthInBytes, dataLengthInBytes); AssertBufferBoundsCheck(buffer.Size, offsetLengthInBytes, dataLengthInBytes);
@ -1934,6 +2027,7 @@ namespace MoonWorks.Graphics
var dataLengthInBytes = (uint) (data.Length * Marshal.SizeOf<T>()); var dataLengthInBytes = (uint) (data.Length * Marshal.SizeOf<T>());
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertRenderPassInactive("Cannot copy during render pass!"); AssertRenderPassInactive("Cannot copy during render pass!");
AssertTextureBoundsCheck(textureSlice.Size, dataLengthInBytes); AssertTextureBoundsCheck(textureSlice.Size, dataLengthInBytes);
#endif #endif
@ -1969,6 +2063,7 @@ namespace MoonWorks.Graphics
public void SetTextureData(in TextureSlice textureSlice, IntPtr dataPtr, uint dataLengthInBytes) public void SetTextureData(in TextureSlice textureSlice, IntPtr dataPtr, uint dataLengthInBytes)
{ {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertRenderPassInactive("Cannot copy during render pass!"); AssertRenderPassInactive("Cannot copy during render pass!");
AssertTextureBoundsCheck(textureSlice.Size, dataLengthInBytes); AssertTextureBoundsCheck(textureSlice.Size, dataLengthInBytes);
#endif #endif
@ -2008,6 +2103,7 @@ namespace MoonWorks.Graphics
uint uvStride) uint uvStride)
{ {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertRenderPassInactive("Cannot copy during render pass!"); AssertRenderPassInactive("Cannot copy during render pass!");
#endif #endif
@ -2044,6 +2140,7 @@ namespace MoonWorks.Graphics
) )
{ {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertRenderPassInactive("Cannot copy during render pass!"); AssertRenderPassInactive("Cannot copy during render pass!");
#endif #endif
@ -2071,6 +2168,7 @@ namespace MoonWorks.Graphics
) )
{ {
#if DEBUG #if DEBUG
AssertNotSubmitted();
AssertRenderPassInactive("Cannot copy during render pass!"); AssertRenderPassInactive("Cannot copy during render pass!");
AssertBufferBoundsCheck(buffer.Size, 0, textureSlice.Size); AssertBufferBoundsCheck(buffer.Size, 0, textureSlice.Size);
#endif #endif
@ -2277,6 +2375,14 @@ namespace MoonWorks.Graphics
throw new System.InvalidOperationException($"SetTextureData overflow! texture size {textureSizeInBytes}, data size {dataLengthInBytes}"); throw new System.InvalidOperationException($"SetTextureData overflow! texture size {textureSizeInBytes}, data size {dataLengthInBytes}");
} }
} }
private void AssertNotSubmitted()
{
if (Submitted)
{
throw new System.InvalidOperationException("Cannot add commands to a submitted command buffer!");
}
}
#endif #endif
} }
} }

View File

@ -0,0 +1,34 @@
using System;
using System.Collections.Concurrent;
namespace MoonWorks.Graphics
{
internal class CommandBufferPool
{
private GraphicsDevice GraphicsDevice;
private ConcurrentQueue<CommandBuffer> CommandBuffers = new ConcurrentQueue<CommandBuffer>();
public CommandBufferPool(GraphicsDevice graphicsDevice)
{
GraphicsDevice = graphicsDevice;
}
public CommandBuffer Obtain()
{
if (CommandBuffers.TryDequeue(out var commandBuffer))
{
return commandBuffer;
}
else
{
return new CommandBuffer(GraphicsDevice);
}
}
public void Return(CommandBuffer commandBuffer)
{
commandBuffer.Handle = IntPtr.Zero;
CommandBuffers.Enqueue(commandBuffer);
}
}
}

View File

@ -35,6 +35,7 @@ namespace MoonWorks.Graphics
private readonly HashSet<GCHandle> resources = new HashSet<GCHandle>(); private readonly HashSet<GCHandle> resources = new HashSet<GCHandle>();
private FencePool FencePool; private FencePool FencePool;
private CommandBufferPool CommandBufferPool;
internal GraphicsDevice( internal GraphicsDevice(
Backend preferredBackend, Backend preferredBackend,
@ -138,6 +139,7 @@ namespace MoonWorks.Graphics
LinearSampler = new Sampler(this, SamplerCreateInfo.LinearClamp); LinearSampler = new Sampler(this, SamplerCreateInfo.LinearClamp);
FencePool = new FencePool(this); FencePool = new FencePool(this);
CommandBufferPool = new CommandBufferPool(this);
} }
/// <summary> /// <summary>
@ -221,7 +223,12 @@ namespace MoonWorks.Graphics
/// <returns></returns> /// <returns></returns>
public CommandBuffer AcquireCommandBuffer() public CommandBuffer AcquireCommandBuffer()
{ {
return new CommandBuffer(this, Refresh.Refresh_AcquireCommandBuffer(Handle)); var commandBuffer = CommandBufferPool.Obtain();
commandBuffer.SetHandle(Refresh.Refresh_AcquireCommandBuffer(Handle));
#if DEBUG
commandBuffer.ResetStateTracking();
#endif
return commandBuffer;
} }
/// <summary> /// <summary>
@ -229,10 +236,23 @@ namespace MoonWorks.Graphics
/// </summary> /// </summary>
public void Submit(CommandBuffer commandBuffer) public void Submit(CommandBuffer commandBuffer)
{ {
#if DEBUG
if (commandBuffer.Submitted)
{
throw new System.InvalidOperationException("Command buffer already submitted!");
}
#endif
Refresh.Refresh_Submit( Refresh.Refresh_Submit(
Handle, Handle,
commandBuffer.Handle commandBuffer.Handle
); );
CommandBufferPool.Return(commandBuffer);
#if DEBUG
commandBuffer.Submitted = true;
#endif
} }
/// <summary> /// <summary>