MoonWorks/src/Graphics/CommandBuffer.cs

1125 lines
36 KiB
C#
Raw Normal View History

2024-06-04 17:20:07 +00:00
using System;
using System.Runtime.InteropServices;
2024-06-04 23:04:19 +00:00
using SDL2;
2024-06-04 17:20:07 +00:00
using SDL2_gpuCS;
2024-06-04 17:20:07 +00:00
namespace MoonWorks.Graphics;
2024-06-04 17:20:07 +00:00
/// <summary>
/// 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.
/// </summary>
public class CommandBuffer
{
public GraphicsDevice Device { get; }
public IntPtr Handle { get; internal set; }
2022-02-23 05:14:32 +00:00
2024-02-23 23:53:49 +00:00
#if DEBUG
2024-06-04 17:20:07 +00:00
bool swapchainTextureAcquired;
2024-02-23 23:53:49 +00:00
2024-06-04 17:20:07 +00:00
ComputePipeline currentComputePipeline;
2024-02-23 23:53:49 +00:00
2024-06-04 23:04:19 +00:00
bool renderPassActive;
2024-06-04 17:20:07 +00:00
bool copyPassActive;
bool computePassActive;
2024-02-23 23:53:49 +00:00
2024-06-04 17:20:07 +00:00
internal bool Submitted;
2024-02-23 23:53:49 +00:00
#endif
2024-06-04 17:20:07 +00:00
// called from CommandBufferPool
internal CommandBuffer(GraphicsDevice device)
{
Device = device;
Handle = IntPtr.Zero;
2024-02-23 23:53:49 +00:00
#if DEBUG
2024-06-04 17:20:07 +00:00
ResetStateTracking();
#endif
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
internal void SetHandle(nint handle)
{
Handle = handle;
}
#if DEBUG
2024-06-04 17:20:07 +00:00
internal void ResetStateTracking()
{
swapchainTextureAcquired = false;
currentComputePipeline = null;
2024-06-04 23:04:19 +00:00
renderPassActive = false;
2024-06-04 17:20:07 +00:00
copyPassActive = false;
computePassActive = false;
Submitted = false;
}
#endif
2024-06-04 17:20:07 +00:00
/// <summary>
/// Acquires a swapchain texture.
/// This texture will be presented to the given window when the command buffer is submitted.
/// Can return null if the swapchain is unavailable. The user should ALWAYS handle the case where this occurs.
/// If null is returned, presentation will not occur.
/// It is an error to acquire two swapchain textures from the same window in one command buffer.
/// It is an error to dispose the swapchain texture. If you do this your game WILL crash. DO NOT DO THIS.
/// </summary>
public Texture AcquireSwapchainTexture(
Window window
) {
#if DEBUG
2024-06-04 17:20:07 +00:00
AssertNotSubmitted();
2024-06-04 17:20:07 +00:00
if (!window.Claimed)
{
throw new System.InvalidOperationException("Cannot acquire swapchain texture, window has not been claimed!");
}
2024-06-04 17:20:07 +00:00
if (swapchainTextureAcquired)
{
throw new System.InvalidOperationException("Cannot acquire two swapchain textures on the same command buffer!");
}
#endif
2024-06-04 17:20:07 +00:00
var texturePtr = SDL_Gpu.SDL_GpuAcquireSwapchainTexture(
Handle,
window.Handle,
out var width,
out var height
);
2024-06-04 17:20:07 +00:00
if (texturePtr == IntPtr.Zero)
{
return null;
2022-02-23 05:14:32 +00:00
}
2024-06-04 17:20:07 +00:00
// Override the texture properties to avoid allocating a new texture instance!
window.SwapchainTexture.Handle = texturePtr;
window.SwapchainTexture.Width = width;
window.SwapchainTexture.Height = height;
window.SwapchainTexture.Format = window.SwapchainFormat;
#if DEBUG
2024-06-04 17:20:07 +00:00
swapchainTextureAcquired = true;
#endif
2024-06-04 17:20:07 +00:00
return window.SwapchainTexture;
}
2024-06-04 17:20:07 +00:00
/// <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 during any kind of pass.
/// </summary>
/// <param name="colorAttachmentInfo">The color attachment to use in the render pass.</param>
2024-06-04 23:04:19 +00:00
public unsafe RenderPass BeginRenderPass(
2024-06-04 17:20:07 +00:00
in ColorAttachmentInfo colorAttachmentInfo
) {
#if DEBUG
2024-06-04 17:20:07 +00:00
AssertNotSubmitted();
AssertNotInPass("Cannot begin a render pass inside another pass!");
AssertTextureNotNull(colorAttachmentInfo);
AssertColorTarget(colorAttachmentInfo);
#endif
2024-06-04 23:04:19 +00:00
var sdlColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[1];
sdlColorAttachmentInfos[0] = colorAttachmentInfo.ToSDL();
2024-06-04 23:04:19 +00:00
var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass(
2024-06-04 17:20:07 +00:00
Handle,
2024-06-04 23:04:19 +00:00
sdlColorAttachmentInfos,
2024-06-04 17:20:07 +00:00
1,
2024-06-04 23:04:19 +00:00
(SDL_Gpu.DepthStencilAttachmentInfo*) nint.Zero
2024-06-04 17:20:07 +00:00
);
2024-06-04 23:04:19 +00:00
var renderPass = Device.RenderPassPool.Obtain();
renderPass.SetHandle(renderPassHandle);
#if DEBUG
2024-06-04 17:20:07 +00:00
renderPassActive = true;
2024-06-04 23:04:19 +00:00
renderPass.colorAttachmentCount = 1;
renderPass.colorAttachmentSampleCount = colorAttachmentInfo.TextureSlice.Texture.SampleCount;
renderPass.colorFormatOne = colorAttachmentInfo.TextureSlice.Texture.Format;
renderPass.hasDepthStencilAttachment = false;
#endif
2024-06-04 23:04:19 +00:00
return renderPass;
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
/// <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="colorAttachmentInfoOne">The first color attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfoTwo">The second color attachment to use in the render pass.</param>
2024-06-04 23:04:19 +00:00
public unsafe RenderPass BeginRenderPass(
2024-06-04 17:20:07 +00:00
in ColorAttachmentInfo colorAttachmentInfoOne,
in ColorAttachmentInfo colorAttachmentInfoTwo
) {
#if DEBUG
2024-06-04 17:20:07 +00:00
AssertNotSubmitted();
2024-06-04 23:04:19 +00:00
AssertNotInPass("Cannot begin a render pass inside another pass!");
2024-06-04 17:20:07 +00:00
AssertTextureNotNull(colorAttachmentInfoOne);
AssertColorTarget(colorAttachmentInfoOne);
2024-06-04 17:20:07 +00:00
AssertTextureNotNull(colorAttachmentInfoTwo);
AssertColorTarget(colorAttachmentInfoTwo);
2024-06-04 17:20:07 +00:00
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoTwo.TextureSlice.Texture);
#endif
2024-06-04 23:04:19 +00:00
var sdlColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[2];
sdlColorAttachmentInfos[0] = colorAttachmentInfoOne.ToSDL();
sdlColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToSDL();
2024-06-04 23:04:19 +00:00
var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass(
2024-06-04 17:20:07 +00:00
Handle,
2024-06-04 23:04:19 +00:00
sdlColorAttachmentInfos,
2024-06-04 17:20:07 +00:00
2,
2024-06-04 23:04:19 +00:00
(SDL_Gpu.DepthStencilAttachmentInfo*) nint.Zero
2024-06-04 17:20:07 +00:00
);
2024-06-04 23:04:19 +00:00
var renderPass = Device.RenderPassPool.Obtain();
renderPass.SetHandle(renderPassHandle);
#if DEBUG
2024-06-04 17:20:07 +00:00
renderPassActive = true;
2024-06-04 23:04:19 +00:00
renderPass.colorAttachmentCount = 2;
renderPass.colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount;
renderPass.colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format;
renderPass.colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format;
renderPass.hasDepthStencilAttachment = false;
#endif
2024-06-04 23:04:19 +00:00
return renderPass;
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
/// <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="colorAttachmentInfoOne">The first color attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfoTwo">The second color attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfoThree">The third color attachment to use in the render pass.</param>
2024-06-04 23:04:19 +00:00
public unsafe RenderPass BeginRenderPass(
2024-06-04 17:20:07 +00:00
in ColorAttachmentInfo colorAttachmentInfoOne,
in ColorAttachmentInfo colorAttachmentInfoTwo,
in ColorAttachmentInfo colorAttachmentInfoThree
) {
#if DEBUG
2024-06-04 17:20:07 +00:00
AssertNotSubmitted();
2024-06-04 23:04:19 +00:00
AssertNotInPass("Cannot begin a render pass inside another pass!");
2024-06-04 17:20:07 +00:00
AssertTextureNotNull(colorAttachmentInfoOne);
AssertColorTarget(colorAttachmentInfoOne);
2024-06-04 17:20:07 +00:00
AssertTextureNotNull(colorAttachmentInfoTwo);
AssertColorTarget(colorAttachmentInfoTwo);
2024-06-04 17:20:07 +00:00
AssertTextureNotNull(colorAttachmentInfoThree);
AssertColorTarget(colorAttachmentInfoThree);
2024-06-04 17:20:07 +00:00
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoTwo.TextureSlice.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoThree.TextureSlice.Texture);
#endif
2024-06-04 23:04:19 +00:00
var sdlColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[3];
sdlColorAttachmentInfos[0] = colorAttachmentInfoOne.ToSDL();
sdlColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToSDL();
sdlColorAttachmentInfos[2] = colorAttachmentInfoThree.ToSDL();
2024-06-04 23:04:19 +00:00
var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass(
2024-06-04 17:20:07 +00:00
Handle,
2024-06-04 23:04:19 +00:00
sdlColorAttachmentInfos,
2024-06-04 17:20:07 +00:00
3,
2024-06-04 23:04:19 +00:00
(SDL_Gpu.DepthStencilAttachmentInfo*) nint.Zero
2024-06-04 17:20:07 +00:00
);
2024-06-04 23:04:19 +00:00
var renderPass = Device.RenderPassPool.Obtain();
renderPass.SetHandle(renderPassHandle);
#if DEBUG
2024-06-04 17:20:07 +00:00
renderPassActive = true;
2024-06-04 23:04:19 +00:00
renderPass.colorAttachmentCount = 3;
renderPass.colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount;
renderPass.colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format;
renderPass.colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format;
renderPass.colorFormatThree = colorAttachmentInfoThree.TextureSlice.Texture.Format;
renderPass.hasDepthStencilAttachment = false;
#endif
2024-06-04 23:04:19 +00:00
return renderPass;
2024-06-04 17:20:07 +00:00
}
2022-02-23 05:14:32 +00:00
2024-06-04 17:20:07 +00:00
/// <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="colorAttachmentInfoOne">The first color attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfoTwo">The second color attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfoThree">The third color attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfoFour">The four color attachment to use in the render pass.</param>
2024-06-04 23:04:19 +00:00
public unsafe RenderPass BeginRenderPass(
2024-06-04 17:20:07 +00:00
in ColorAttachmentInfo colorAttachmentInfoOne,
in ColorAttachmentInfo colorAttachmentInfoTwo,
in ColorAttachmentInfo colorAttachmentInfoThree,
in ColorAttachmentInfo colorAttachmentInfoFour
) {
#if DEBUG
AssertNotSubmitted();
AssertTextureNotNull(colorAttachmentInfoOne);
AssertColorTarget(colorAttachmentInfoOne);
AssertTextureNotNull(colorAttachmentInfoTwo);
AssertColorTarget(colorAttachmentInfoTwo);
AssertTextureNotNull(colorAttachmentInfoThree);
AssertColorTarget(colorAttachmentInfoThree);
AssertTextureNotNull(colorAttachmentInfoFour);
AssertColorTarget(colorAttachmentInfoFour);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoTwo.TextureSlice.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoThree.TextureSlice.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoFour.TextureSlice.Texture);
#endif
2024-06-04 23:04:19 +00:00
var sdlColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[4];
sdlColorAttachmentInfos[0] = colorAttachmentInfoOne.ToSDL();
sdlColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToSDL();
sdlColorAttachmentInfos[2] = colorAttachmentInfoThree.ToSDL();
sdlColorAttachmentInfos[3] = colorAttachmentInfoFour.ToSDL();
2024-06-04 17:20:07 +00:00
2024-06-04 23:04:19 +00:00
var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass(
2024-06-04 17:20:07 +00:00
Handle,
2024-06-04 23:04:19 +00:00
sdlColorAttachmentInfos,
2024-06-04 17:20:07 +00:00
4,
2024-06-04 23:04:19 +00:00
(SDL_Gpu.DepthStencilAttachmentInfo*) nint.Zero
2024-06-04 17:20:07 +00:00
);
2024-06-04 23:04:19 +00:00
var renderPass = Device.RenderPassPool.Obtain();
renderPass.SetHandle(renderPassHandle);
2024-06-04 17:20:07 +00:00
#if DEBUG
renderPassActive = true;
2024-06-04 23:04:19 +00:00
renderPass.colorAttachmentCount = 3;
renderPass.colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount;
renderPass.colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format;
renderPass.colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format;
renderPass.colorFormatThree = colorAttachmentInfoThree.TextureSlice.Texture.Format;
renderPass.colorFormatFour = colorAttachmentInfoFour.TextureSlice.Texture.Format;
renderPass.hasDepthStencilAttachment = false;
#endif
2024-06-04 23:04:19 +00:00
return renderPass;
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
/// <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="depthStencilAttachmentInfo">The depth stencil attachment to use in the render pass.</param>
2024-06-04 23:04:19 +00:00
public unsafe RenderPass BeginRenderPass(
2024-06-04 17:20:07 +00:00
in DepthStencilAttachmentInfo depthStencilAttachmentInfo
) {
#if DEBUG
2024-06-04 17:20:07 +00:00
AssertNotSubmitted();
AssertValidDepthAttachment(depthStencilAttachmentInfo);
#endif
2024-06-04 23:04:19 +00:00
var sdlDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToSDL();
2024-06-04 23:04:19 +00:00
var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass(
2024-06-04 17:20:07 +00:00
Handle,
2024-06-04 23:04:19 +00:00
(SDL_Gpu.ColorAttachmentInfo*) nint.Zero,
2024-06-04 17:20:07 +00:00
0,
2024-06-04 23:04:19 +00:00
&sdlDepthStencilAttachmentInfo
2024-06-04 17:20:07 +00:00
);
2022-02-23 05:14:32 +00:00
2024-06-04 23:04:19 +00:00
var renderPass = Device.RenderPassPool.Obtain();
renderPass.SetHandle(renderPassHandle);
#if DEBUG
2024-06-04 17:20:07 +00:00
renderPassActive = true;
2024-06-04 23:04:19 +00:00
renderPass.hasDepthStencilAttachment = true;
renderPass.depthStencilAttachmentSampleCount = depthStencilAttachmentInfo.TextureSlice.Texture.SampleCount;
renderPass.depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format;
2024-02-23 23:53:49 +00:00
#endif
2024-06-04 23:04:19 +00:00
return renderPass;
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
/// <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="depthStencilAttachmentInfo">The depth stencil attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfo">The color attachment to use in the render pass.</param>
2024-06-04 23:04:19 +00:00
public unsafe RenderPass BeginRenderPass(
2024-06-04 17:20:07 +00:00
in DepthStencilAttachmentInfo depthStencilAttachmentInfo,
in ColorAttachmentInfo colorAttachmentInfo
) {
#if DEBUG
2024-06-04 17:20:07 +00:00
AssertNotSubmitted();
AssertValidDepthAttachment(depthStencilAttachmentInfo);
2024-02-23 23:53:49 +00:00
2024-06-04 17:20:07 +00:00
AssertTextureNotNull(colorAttachmentInfo);
AssertColorTarget(colorAttachmentInfo);
AssertSameSampleCount(colorAttachmentInfo.TextureSlice.Texture, depthStencilAttachmentInfo.TextureSlice.Texture);
#endif
2024-06-04 23:04:19 +00:00
var sdlColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[1];
sdlColorAttachmentInfos[0] = colorAttachmentInfo.ToSDL();
2024-06-04 23:04:19 +00:00
var sdlDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToSDL();
2024-06-04 23:04:19 +00:00
var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass(
2024-06-04 17:20:07 +00:00
Handle,
2024-06-04 23:04:19 +00:00
sdlColorAttachmentInfos,
2024-06-04 17:20:07 +00:00
1,
2024-06-04 23:04:19 +00:00
&sdlDepthStencilAttachmentInfo
2024-06-04 17:20:07 +00:00
);
2022-02-23 05:14:32 +00:00
2024-06-04 23:04:19 +00:00
var renderPass = Device.RenderPassPool.Obtain();
renderPass.SetHandle(renderPassHandle);
#if DEBUG
2024-06-04 17:20:07 +00:00
renderPassActive = true;
2024-06-04 23:04:19 +00:00
renderPass.hasDepthStencilAttachment = true;
renderPass.colorAttachmentCount = 1;
renderPass.colorAttachmentSampleCount = colorAttachmentInfo.TextureSlice.Texture.SampleCount;
renderPass.colorFormatOne = colorAttachmentInfo.TextureSlice.Texture.Format;
renderPass.depthStencilAttachmentSampleCount = depthStencilAttachmentInfo.TextureSlice.Texture.SampleCount;
renderPass.depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format;
#endif
2024-06-04 23:04:19 +00:00
return renderPass;
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
/// <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="depthStencilAttachmentInfo">The depth stencil attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfoOne">The first color attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfoTwo">The second color attachment to use in the render pass.</param>
2024-06-04 23:04:19 +00:00
public unsafe RenderPass BeginRenderPass(
2024-06-04 17:20:07 +00:00
in DepthStencilAttachmentInfo depthStencilAttachmentInfo,
in ColorAttachmentInfo colorAttachmentInfoOne,
in ColorAttachmentInfo colorAttachmentInfoTwo
) {
#if DEBUG
2024-06-04 17:20:07 +00:00
AssertNotSubmitted();
AssertValidDepthAttachment(depthStencilAttachmentInfo);
2024-06-04 17:20:07 +00:00
AssertTextureNotNull(colorAttachmentInfoOne);
AssertColorTarget(colorAttachmentInfoOne);
2024-06-04 17:20:07 +00:00
AssertTextureNotNull(colorAttachmentInfoTwo);
AssertColorTarget(colorAttachmentInfoTwo);
2024-06-04 17:20:07 +00:00
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoTwo.TextureSlice.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, depthStencilAttachmentInfo.TextureSlice.Texture);
#endif
2024-06-04 23:04:19 +00:00
var sdlColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[2];
sdlColorAttachmentInfos[0] = colorAttachmentInfoOne.ToSDL();
sdlColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToSDL();
2024-06-04 23:04:19 +00:00
var sdlDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToSDL();
2024-06-04 23:04:19 +00:00
var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass(
2024-06-04 17:20:07 +00:00
Handle,
2024-06-04 23:04:19 +00:00
sdlColorAttachmentInfos,
2024-06-04 17:20:07 +00:00
2,
2024-06-04 23:04:19 +00:00
&sdlDepthStencilAttachmentInfo
2024-06-04 17:20:07 +00:00
);
2024-02-23 23:53:49 +00:00
2024-06-04 23:04:19 +00:00
var renderPass = Device.RenderPassPool.Obtain();
renderPass.SetHandle(renderPassHandle);
#if DEBUG
2024-06-04 17:20:07 +00:00
renderPassActive = true;
2024-06-04 23:04:19 +00:00
renderPass.hasDepthStencilAttachment = true;
renderPass.colorAttachmentCount = 2;
renderPass.colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format;
renderPass.colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format;
renderPass.colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount;
renderPass.depthStencilAttachmentSampleCount = depthStencilAttachmentInfo.TextureSlice.Texture.SampleCount;
renderPass.depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format;
#endif
2024-06-04 23:04:19 +00:00
return renderPass;
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
/// <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="depthStencilAttachmentInfo">The depth stencil attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfoOne">The first color attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfoTwo">The second color attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfoThree">The third color attachment to use in the render pass.</param>
2024-06-04 23:04:19 +00:00
public unsafe RenderPass BeginRenderPass(
2024-06-04 17:20:07 +00:00
in DepthStencilAttachmentInfo depthStencilAttachmentInfo,
in ColorAttachmentInfo colorAttachmentInfoOne,
in ColorAttachmentInfo colorAttachmentInfoTwo,
in ColorAttachmentInfo colorAttachmentInfoThree
) {
#if DEBUG
AssertNotSubmitted();
AssertValidDepthAttachment(depthStencilAttachmentInfo);
AssertTextureNotNull(colorAttachmentInfoOne);
AssertColorTarget(colorAttachmentInfoOne);
AssertTextureNotNull(colorAttachmentInfoTwo);
AssertColorTarget(colorAttachmentInfoTwo);
AssertTextureNotNull(colorAttachmentInfoThree);
AssertColorTarget(colorAttachmentInfoThree);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoTwo.TextureSlice.Texture);
2024-06-04 23:04:19 +00:00
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoThree.TextureSlice.Texture);
2024-06-04 17:20:07 +00:00
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, depthStencilAttachmentInfo.TextureSlice.Texture);
#endif
2024-06-04 23:04:19 +00:00
var sdlColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[3];
sdlColorAttachmentInfos[0] = colorAttachmentInfoOne.ToSDL();
sdlColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToSDL();
sdlColorAttachmentInfos[2] = colorAttachmentInfoThree.ToSDL();
2024-06-04 17:20:07 +00:00
2024-06-04 23:04:19 +00:00
var sdlDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToSDL();
2024-06-04 17:20:07 +00:00
2024-06-04 23:04:19 +00:00
var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass(
2024-06-04 17:20:07 +00:00
Handle,
2024-06-04 23:04:19 +00:00
sdlColorAttachmentInfos,
2024-06-04 17:20:07 +00:00
3,
2024-06-04 23:04:19 +00:00
&sdlDepthStencilAttachmentInfo
2024-06-04 17:20:07 +00:00
);
2024-06-04 23:04:19 +00:00
var renderPass = Device.RenderPassPool.Obtain();
renderPass.SetHandle(renderPassHandle);
2024-06-04 17:20:07 +00:00
#if DEBUG
renderPassActive = true;
2024-06-04 23:04:19 +00:00
renderPass.hasDepthStencilAttachment = true;
renderPass.colorAttachmentCount = 3;
renderPass.colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount;
renderPass.colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format;
renderPass.colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format;
renderPass.colorFormatThree = colorAttachmentInfoThree.TextureSlice.Texture.Format;
renderPass.depthStencilAttachmentSampleCount = depthStencilAttachmentInfo.TextureSlice.Texture.SampleCount;
renderPass.depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format;
2024-02-23 23:53:49 +00:00
#endif
2024-06-04 23:04:19 +00:00
return renderPass;
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
/// <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="depthStencilAttachmentInfo">The depth stencil attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfoOne">The first color attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfoTwo">The second color attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfoThree">The third color attachment to use in the render pass.</param>
/// <param name="colorAttachmentInfoFour">The four color attachment to use in the render pass.</param>
2024-06-04 23:04:19 +00:00
public unsafe RenderPass BeginRenderPass(
2024-06-04 17:20:07 +00:00
in DepthStencilAttachmentInfo depthStencilAttachmentInfo,
in ColorAttachmentInfo colorAttachmentInfoOne,
in ColorAttachmentInfo colorAttachmentInfoTwo,
in ColorAttachmentInfo colorAttachmentInfoThree,
in ColorAttachmentInfo colorAttachmentInfoFour
) {
#if DEBUG
AssertNotSubmitted();
AssertValidDepthAttachment(depthStencilAttachmentInfo);
AssertTextureNotNull(colorAttachmentInfoOne);
AssertColorTarget(colorAttachmentInfoOne);
AssertTextureNotNull(colorAttachmentInfoTwo);
AssertColorTarget(colorAttachmentInfoTwo);
AssertTextureNotNull(colorAttachmentInfoThree);
AssertColorTarget(colorAttachmentInfoThree);
AssertTextureNotNull(colorAttachmentInfoFour);
AssertColorTarget(colorAttachmentInfoFour);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoTwo.TextureSlice.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoThree.TextureSlice.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, colorAttachmentInfoFour.TextureSlice.Texture);
AssertSameSampleCount(colorAttachmentInfoOne.TextureSlice.Texture, depthStencilAttachmentInfo.TextureSlice.Texture);
#endif
2024-06-04 23:04:19 +00:00
var sdlColorAttachmentInfos = stackalloc SDL_Gpu.ColorAttachmentInfo[4];
sdlColorAttachmentInfos[0] = colorAttachmentInfoOne.ToSDL();
sdlColorAttachmentInfos[1] = colorAttachmentInfoTwo.ToSDL();
sdlColorAttachmentInfos[2] = colorAttachmentInfoThree.ToSDL();
sdlColorAttachmentInfos[3] = colorAttachmentInfoFour.ToSDL();
2024-06-04 17:20:07 +00:00
2024-06-04 23:04:19 +00:00
var sdlDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToSDL();
2024-06-04 17:20:07 +00:00
2024-06-04 23:04:19 +00:00
var renderPassHandle = SDL_Gpu.SDL_GpuBeginRenderPass(
2024-06-04 17:20:07 +00:00
Handle,
2024-06-04 23:04:19 +00:00
sdlColorAttachmentInfos,
2024-06-04 17:20:07 +00:00
4,
2024-06-04 23:04:19 +00:00
&sdlDepthStencilAttachmentInfo
2024-06-04 17:20:07 +00:00
);
2022-02-23 05:14:32 +00:00
2024-06-04 23:04:19 +00:00
var renderPass = Device.RenderPassPool.Obtain();
renderPass.SetHandle(renderPassHandle);
2024-02-23 23:53:49 +00:00
#if DEBUG
2024-06-04 23:04:19 +00:00
renderPassActive = true;
renderPass.hasDepthStencilAttachment = true;
renderPass.colorAttachmentCount = 4;
renderPass.colorAttachmentSampleCount = colorAttachmentInfoOne.TextureSlice.Texture.SampleCount;
renderPass.colorFormatOne = colorAttachmentInfoOne.TextureSlice.Texture.Format;
renderPass.colorFormatTwo = colorAttachmentInfoTwo.TextureSlice.Texture.Format;
renderPass.colorFormatThree = colorAttachmentInfoThree.TextureSlice.Texture.Format;
renderPass.colorFormatFour = colorAttachmentInfoFour.TextureSlice.Texture.Format;
renderPass.depthStencilAttachmentSampleCount = depthStencilAttachmentInfo.TextureSlice.Texture.SampleCount;
renderPass.depthStencilFormat = depthStencilAttachmentInfo.TextureSlice.Texture.Format;
2024-02-23 23:53:49 +00:00
#endif
2024-06-04 23:04:19 +00:00
return renderPass;
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
/// <summary>
/// Ends the current render pass.
/// This must be called before beginning another render pass or submitting the command buffer.
/// </summary>
2024-06-04 23:04:19 +00:00
public void EndRenderPass(RenderPass renderPass)
2024-06-04 17:20:07 +00:00
{
#if DEBUG
2024-06-04 17:20:07 +00:00
AssertNotSubmitted();
2024-06-04 23:04:19 +00:00
AssertRenderPassActive();
renderPassActive = false;
renderPass.active = false;
#endif
2024-06-04 23:04:19 +00:00
SDL_Gpu.SDL_GpuEndRenderPass(
renderPass.Handle
2024-06-04 17:20:07 +00:00
);
2024-06-04 23:04:19 +00:00
Device.RenderPassPool.Return(renderPass);
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
/// <summary>
/// Blits a texture to another texture with the specified filter.
///
/// This operation cannot be performed inside any pass.
/// </summary>
2024-06-04 23:04:19 +00:00
/// <param name="cycle">If true, the destination texture will cycle if bound.</param>
2024-06-04 17:20:07 +00:00
public void Blit(
2024-06-04 23:04:19 +00:00
in TextureRegion source,
in TextureRegion destination,
2024-06-04 17:20:07 +00:00
Filter filter,
2024-06-04 23:04:19 +00:00
bool cycle
2024-06-04 17:20:07 +00:00
) {
2024-06-04 23:04:19 +00:00
SDL_Gpu.SDL_GpuBlit(
Handle,
source.ToSDL(),
destination.ToSDL(),
(SDL_Gpu.Filter) filter,
Conversions.BoolToInt(cycle)
);
2024-06-04 17:20:07 +00:00
}
2024-02-23 23:53:49 +00:00
2024-06-05 00:24:25 +00:00
public unsafe ComputePass BeginComputePass(
in StorageTextureReadWriteBinding readWriteTextureBinding
) {
2024-02-23 23:53:49 +00:00
#if DEBUG
2024-06-04 17:20:07 +00:00
AssertNotSubmitted();
AssertNotInPass("Cannot begin compute pass while in another pass!");
computePassActive = true;
2024-02-23 23:53:49 +00:00
#endif
2024-06-05 00:24:25 +00:00
var sdlTextureBinding = readWriteTextureBinding.ToSDL();
2022-02-23 05:14:32 +00:00
2024-06-05 00:24:25 +00:00
var computePassHandle = SDL_Gpu.SDL_GpuBeginComputePass(
2024-06-04 17:20:07 +00:00
Handle,
2024-06-05 00:24:25 +00:00
&sdlTextureBinding,
1,
(SDL_Gpu.StorageBufferReadWriteBinding*) nint.Size,
0
2024-06-04 17:20:07 +00:00
);
2024-06-05 00:24:25 +00:00
var computePass = Device.ComputePassPool.Obtain();
computePass.SetHandle(computePassHandle);
#if DEBUG
2024-06-05 00:24:25 +00:00
computePass.active = true;
#endif
2024-06-05 00:24:25 +00:00
return computePass;
2024-06-04 17:20:07 +00:00
}
2024-06-05 00:24:25 +00:00
public unsafe ComputePass BeginComputePass(
in StorageBufferReadWriteBinding readWriteBufferBinding
2024-06-04 17:20:07 +00:00
) {
#if DEBUG
AssertNotSubmitted();
2024-06-05 00:24:25 +00:00
AssertNotInPass("Cannot begin compute pass while in another pass!");
computePassActive = true;
2024-06-04 17:20:07 +00:00
#endif
2024-06-05 00:24:25 +00:00
var sdlBufferBinding = readWriteBufferBinding.ToSDL();
2024-06-04 17:20:07 +00:00
2024-06-05 00:24:25 +00:00
var computePassHandle = SDL_Gpu.SDL_GpuBeginComputePass(
2024-06-04 17:20:07 +00:00
Handle,
2024-06-05 00:24:25 +00:00
(SDL_Gpu.StorageTextureReadWriteBinding*) nint.Zero,
0,
&sdlBufferBinding,
1
2024-06-04 17:20:07 +00:00
);
2024-06-05 00:24:25 +00:00
var computePass = Device.ComputePassPool.Obtain();
computePass.SetHandle(computePassHandle);
2024-06-04 17:20:07 +00:00
#if DEBUG
2024-06-05 00:24:25 +00:00
computePass.active = true;
2024-06-04 17:20:07 +00:00
#endif
2024-06-05 00:24:25 +00:00
return computePass;
2024-06-04 17:20:07 +00:00
}
2024-06-05 00:24:25 +00:00
public unsafe ComputePass BeginComputePass(
in StorageTextureReadWriteBinding readWriteTextureBinding,
in StorageBufferReadWriteBinding readWriteBufferBinding
2024-06-04 17:20:07 +00:00
) {
#if DEBUG
2024-06-04 17:20:07 +00:00
AssertNotSubmitted();
2024-06-05 00:24:25 +00:00
AssertNotInPass("Cannot begin compute pass while in another pass!");
computePassActive = true;
#endif
2024-06-05 00:24:25 +00:00
var sdlTextureBinding = readWriteTextureBinding.ToSDL();
var sdlBufferBinding = readWriteBufferBinding.ToSDL();
2024-06-05 00:24:25 +00:00
var computePassHandle = SDL_Gpu.SDL_GpuBeginComputePass(
2024-06-04 17:20:07 +00:00
Handle,
2024-06-05 00:24:25 +00:00
&sdlTextureBinding,
1,
&sdlBufferBinding,
1
2024-06-04 17:20:07 +00:00
);
2024-06-05 00:24:25 +00:00
var computePass = Device.ComputePassPool.Obtain();
computePass.SetHandle(computePassHandle);
2023-02-24 00:59:34 +00:00
2024-02-23 23:53:49 +00:00
#if DEBUG
2024-06-05 00:24:25 +00:00
computePass.active = true;
#endif
2024-06-05 00:24:25 +00:00
return computePass;
2024-06-04 17:20:07 +00:00
}
2023-02-24 00:59:34 +00:00
2024-06-05 00:24:25 +00:00
public void EndComputePass(ComputePass computePass)
2024-06-04 17:20:07 +00:00
{
#if DEBUG
AssertNotSubmitted();
AssertInComputePass("Cannot end compute pass while not in a compute pass!");
computePassActive = false;
2024-06-05 00:24:25 +00:00
computePass.active = false;
#endif
2024-06-05 00:24:25 +00:00
SDL_Gpu.SDL_GpuEndComputePass(
computePass.Handle
2024-06-04 17:20:07 +00:00
);
}
2022-02-23 05:14:32 +00:00
2024-06-04 17:20:07 +00:00
// Copy Pass
2022-02-23 06:16:06 +00:00
2024-06-04 17:20:07 +00:00
/// <summary>
/// Begins a copy pass.
/// All copy commands must be made within a copy pass.
/// It is an error to call this during any kind of pass.
/// </summary>
public void BeginCopyPass()
{
2024-02-23 08:06:04 +00:00
#if DEBUG
2024-06-04 17:20:07 +00:00
AssertNotSubmitted();
AssertNotInPass("Cannot begin copy pass while in another pass!");
copyPassActive = true;
2024-02-23 08:06:04 +00:00
#endif
2024-06-04 17:20:07 +00:00
Refresh.Refresh_BeginCopyPass(
Device.Handle,
Handle
);
}
2024-03-01 23:03:14 +00:00
2024-06-04 17:20:07 +00:00
/// <summary>
/// Uploads data from a TransferBuffer to a TextureSlice.
/// This copy occurs on the GPU timeline.
///
/// Overwriting the contents of the TransferBuffer before the command buffer
/// has finished execution will cause undefined behavior.
///
/// You MAY assume that the copy has finished for subsequent commands.
/// </summary>
/// <param name="writeOption">Specifies data dependency behavior.</param>
public void UploadToTexture(
TransferBuffer transferBuffer,
in TextureRegion textureRegion,
in BufferImageCopy copyParams,
WriteOptions writeOption
)
{
#if DEBUG
2024-06-04 17:20:07 +00:00
AssertNotSubmitted();
AssertInCopyPass("Cannot upload to texture outside of copy pass!");
AssertBufferBoundsCheck(transferBuffer.Size, copyParams.BufferOffset, textureRegion.Size);
#endif
2024-06-04 17:20:07 +00:00
Refresh.Refresh_UploadToTexture(
Device.Handle,
Handle,
transferBuffer.Handle,
textureRegion.ToRefreshTextureRegion(),
copyParams.ToRefresh(),
(Refresh.WriteOptions) writeOption
);
}
2022-02-23 05:14:32 +00:00
2024-06-04 17:20:07 +00:00
/// <summary>
/// Uploads the contents of an entire buffer to a texture with no mips.
/// </summary>
public void UploadToTexture(
TransferBuffer transferBuffer,
Texture texture,
WriteOptions writeOption
) {
UploadToTexture(
transferBuffer,
new TextureRegion(texture),
new BufferImageCopy(0, 0, 0),
writeOption
);
}
2024-06-04 17:20:07 +00:00
/// <summary>
/// Uploads data from a TransferBuffer to a GpuBuffer.
/// This copy occurs on the GPU timeline.
///
/// Overwriting the contents of the TransferBuffer before the command buffer
/// has finished execution will cause undefined behavior.
///
/// You MAY assume that the copy has finished for subsequent commands.
/// </summary>
public void UploadToBuffer(
TransferBuffer transferBuffer,
GpuBuffer gpuBuffer,
in BufferCopy copyParams,
WriteOptions option
) {
#if DEBUG
AssertNotSubmitted();
AssertInCopyPass("Cannot upload to texture outside of copy pass!");
AssertBufferBoundsCheck(transferBuffer.Size, copyParams.SrcOffset, copyParams.Size);
AssertBufferBoundsCheck(gpuBuffer.Size, copyParams.DstOffset, copyParams.Size);
#endif
Refresh.Refresh_UploadToBuffer(
Device.Handle,
Handle,
transferBuffer.Handle,
gpuBuffer.Handle,
copyParams.ToRefresh(),
(Refresh.WriteOptions) option
);
}
2024-06-04 17:20:07 +00:00
/// <summary>
/// Copies the entire contents of a TransferBuffer to a GpuBuffer.
/// </summary>
public void UploadToBuffer(
TransferBuffer transferBuffer,
GpuBuffer gpuBuffer,
WriteOptions option
) {
UploadToBuffer(
transferBuffer,
gpuBuffer,
new BufferCopy(0, 0, transferBuffer.Size),
option
);
}
2022-02-23 05:14:32 +00:00
2024-06-04 17:20:07 +00:00
/// <summary>
/// Copies data element-wise into from a TransferBuffer to a GpuBuffer.
/// </summary>
public void UploadToBuffer<T>(
TransferBuffer transferBuffer,
GpuBuffer gpuBuffer,
uint sourceStartElement,
uint destinationStartElement,
uint numElements,
WriteOptions option
) where T : unmanaged
{
var elementSize = Marshal.SizeOf<T>();
var dataLengthInBytes = (uint) (elementSize * numElements);
var srcOffsetInBytes = (uint) (elementSize * sourceStartElement);
var dstOffsetInBytes = (uint) (elementSize * destinationStartElement);
UploadToBuffer(
transferBuffer,
gpuBuffer,
new BufferCopy(
srcOffsetInBytes,
dstOffsetInBytes,
dataLengthInBytes
),
option
);
}
2024-06-04 17:20:07 +00:00
/// <summary>
/// Copies the contents of a TextureSlice to another TextureSlice.
/// The slices must have the same dimensions.
/// This copy occurs on the GPU timeline.
///
/// You MAY assume that the copy has finished in subsequent commands.
/// </summary>
public void CopyTextureToTexture(
in TextureRegion source,
in TextureRegion destination,
WriteOptions option
) {
#if DEBUG
AssertNotSubmitted();
AssertInCopyPass("Cannot download from texture outside of copy pass!");
AssertTextureBoundsCheck(destination.Size, source.Size);
#endif
Refresh.Refresh_CopyTextureToTexture(
Device.Handle,
Handle,
source.ToRefreshTextureRegion(),
destination.ToRefreshTextureRegion(),
(Refresh.WriteOptions) option
);
}
2024-02-23 23:40:01 +00:00
2024-06-04 17:20:07 +00:00
/// <summary>
/// Copies the contents of an entire Texture with no mips to another Texture with no mips.
/// The textures must have the same dimensions.
/// </summary>
public void CopyTextureToTexture(
Texture source,
Texture destination,
WriteOptions option
) {
CopyTextureToTexture(
new TextureRegion(source),
new TextureRegion(destination),
option
);
}
2024-06-04 17:20:07 +00:00
/// <summary>
/// Copies data from a GpuBuffer to another GpuBuffer.
/// This copy occurs on the GPU timeline.
///
/// You MAY assume that the copy has finished in subsequent commands.
/// </summary>
public void CopyBufferToBuffer(
GpuBuffer source,
GpuBuffer destination,
in BufferCopy copyParams,
WriteOptions option
) {
#if DEBUG
AssertNotSubmitted();
AssertInCopyPass("Cannot download from texture outside of copy pass!");
AssertBufferBoundsCheck(source.Size, copyParams.SrcOffset, copyParams.Size);
AssertBufferBoundsCheck(destination.Size, copyParams.DstOffset, copyParams.Size);
#endif
Refresh.Refresh_CopyBufferToBuffer(
Device.Handle,
Handle,
source.Handle,
destination.Handle,
copyParams.ToRefresh(),
(Refresh.WriteOptions) option
);
}
2022-02-23 05:14:32 +00:00
2024-06-04 17:20:07 +00:00
/// <summary>
/// Copies the entire contents of a GpuBuffer to another GpuBuffer.
/// </summary>
public void CopyBufferToBuffer(
GpuBuffer source,
GpuBuffer destination,
WriteOptions option
) {
CopyBufferToBuffer(
source,
destination,
new BufferCopy(0, 0, source.Size),
option
);
}
2024-06-04 17:20:07 +00:00
public void EndCopyPass()
{
#if DEBUG
2024-06-04 17:20:07 +00:00
AssertNotSubmitted();
AssertInCopyPass("Cannot end copy pass while not in a copy pass!");
copyPassActive = false;
#endif
2024-06-04 17:20:07 +00:00
Refresh.Refresh_EndCopyPass(
Device.Handle,
Handle
);
}
2024-02-23 08:06:04 +00:00
#if DEBUG
2024-06-04 17:20:07 +00:00
private void AssertRenderPassActive(string message = "No active render pass!")
{
if (!renderPassActive)
{
throw new System.InvalidOperationException(message);
2022-02-23 05:14:32 +00:00
}
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
private void AssertComputePipelineBound(string message = "No compute pipeline is bound!")
{
if (currentComputePipeline == null)
{
2024-06-04 17:20:07 +00:00
throw new System.InvalidOperationException(message);
}
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
private void AssertComputeBufferCount(int count)
{
if (currentComputePipeline.ComputeShaderInfo.BufferBindingCount != count)
{
2024-06-04 17:20:07 +00:00
throw new System.InvalidOperationException($"Compute pipeline expects {currentComputePipeline.ComputeShaderInfo.BufferBindingCount} buffers, but received {count}");
}
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
private void AssertComputeTextureCount(int count)
{
if (currentComputePipeline.ComputeShaderInfo.ImageBindingCount != count)
{
2024-06-04 17:20:07 +00:00
throw new System.InvalidOperationException($"Compute pipeline expects {currentComputePipeline.ComputeShaderInfo.ImageBindingCount} textures, but received {count}");
}
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
private void AssertTextureNotNull(ColorAttachmentInfo colorAttachmentInfo)
{
if (colorAttachmentInfo.TextureSlice.Texture == null || colorAttachmentInfo.TextureSlice.Texture.Handle == IntPtr.Zero)
{
2024-06-04 17:20:07 +00:00
throw new System.ArgumentException("Render pass color attachment Texture cannot be null!");
}
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
private void AssertColorTarget(ColorAttachmentInfo colorAttachmentInfo)
{
if ((colorAttachmentInfo.TextureSlice.Texture.UsageFlags & TextureUsageFlags.ColorTarget) == 0)
{
2024-06-04 17:20:07 +00:00
throw new System.ArgumentException("Render pass color attachment UsageFlags must include TextureUsageFlags.ColorTarget!");
}
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
private void AssertSameSampleCount(Texture a, Texture b)
{
if (a.SampleCount != b.SampleCount)
{
2024-06-04 17:20:07 +00:00
throw new System.ArgumentException("All attachments in a render pass must have the same SampleCount!");
}
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
private void AssertValidDepthAttachment(DepthStencilAttachmentInfo depthStencilAttachmentInfo)
{
if (depthStencilAttachmentInfo.TextureSlice.Texture == null ||
depthStencilAttachmentInfo.TextureSlice.Texture.Handle == IntPtr.Zero)
{
2024-06-04 17:20:07 +00:00
throw new System.ArgumentException("Render pass depth stencil attachment Texture cannot be null!");
}
2024-06-04 17:20:07 +00:00
if ((depthStencilAttachmentInfo.TextureSlice.Texture.UsageFlags & TextureUsageFlags.DepthStencilTarget) == 0)
{
2024-06-04 17:20:07 +00:00
throw new System.ArgumentException("Render pass depth stencil attachment UsageFlags must include TextureUsageFlags.DepthStencilTarget!");
}
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
private void AssertNonEmptyCopy(uint dataLengthInBytes)
{
if (dataLengthInBytes == 0)
{
2024-06-04 17:20:07 +00:00
throw new System.InvalidOperationException("SetBufferData must have a length greater than 0 bytes!");
}
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
private void AssertBufferBoundsCheck(uint bufferLengthInBytes, uint offsetInBytes, uint copyLengthInBytes)
{
if (copyLengthInBytes > bufferLengthInBytes + offsetInBytes)
{
2024-06-04 17:20:07 +00:00
throw new System.InvalidOperationException($"SetBufferData overflow! buffer length {bufferLengthInBytes}, offset {offsetInBytes}, copy length {copyLengthInBytes}");
}
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
private void AssertTextureBoundsCheck(uint textureSizeInBytes, uint dataLengthInBytes)
{
if (dataLengthInBytes > textureSizeInBytes)
{
2024-06-04 17:20:07 +00:00
throw new System.InvalidOperationException($"SetTextureData overflow! texture size {textureSizeInBytes}, data size {dataLengthInBytes}");
}
2024-06-04 17:20:07 +00:00
}
2024-06-04 17:20:07 +00:00
private void AssertNotInPass(string message)
{
if (renderPassActive || copyPassActive || computePassActive)
2024-02-23 08:06:04 +00:00
{
2024-06-04 17:20:07 +00:00
throw new System.InvalidOperationException(message);
2024-02-23 08:06:04 +00:00
}
2024-06-04 17:20:07 +00:00
}
2024-02-23 08:06:04 +00:00
2024-06-04 17:20:07 +00:00
private void AssertInCopyPass(string message)
{
if (!copyPassActive)
2024-02-23 08:06:04 +00:00
{
2024-06-04 17:20:07 +00:00
throw new System.InvalidOperationException(message);
2024-02-23 08:06:04 +00:00
}
2024-06-04 17:20:07 +00:00
}
2024-02-23 08:06:04 +00:00
2024-06-04 17:20:07 +00:00
private void AssertInComputePass(string message)
{
if (!computePassActive)
2024-02-23 18:43:39 +00:00
{
2024-06-04 17:20:07 +00:00
throw new System.InvalidOperationException(message);
2024-02-23 18:43:39 +00:00
}
2024-06-04 17:20:07 +00:00
}
2024-02-23 18:43:39 +00:00
2024-06-04 17:20:07 +00:00
private void AssertNotSubmitted()
{
if (Submitted)
{
2024-06-04 17:20:07 +00:00
throw new System.InvalidOperationException("Cannot add commands to a submitted command buffer!");
}
2022-02-23 05:14:32 +00:00
}
2024-06-04 17:20:07 +00:00
#endif
}