2022-02-23 05:14:32 +00:00
using System ;
2022-12-14 03:01:40 +00:00
using System.Runtime.InteropServices ;
2021-01-20 03:33:27 +00:00
using RefreshCS ;
namespace MoonWorks.Graphics
{
2022-02-23 05:14:32 +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>
2024-01-18 20:27:34 +00:00
public class CommandBuffer
2022-02-23 05:14:32 +00:00
{
public GraphicsDevice Device { get ; }
2024-01-18 20:27:34 +00:00
public IntPtr Handle { get ; internal set ; }
2022-09-07 20:07:17 +00:00
2022-11-17 20:35:21 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
bool swapchainTextureAcquired ;
2022-09-29 22:22:50 +00:00
GraphicsPipeline currentGraphicsPipeline ;
ComputePipeline currentComputePipeline ;
bool renderPassActive ;
2024-01-16 07:11:28 +00:00
SampleCount colorAttachmentSampleCount ;
uint colorAttachmentCount ;
2022-11-17 20:35:21 +00:00
TextureFormat colorFormatOne ;
TextureFormat colorFormatTwo ;
TextureFormat colorFormatThree ;
TextureFormat colorFormatFour ;
2024-01-16 07:11:28 +00:00
bool hasDepthStencilAttachment ;
SampleCount depthStencilAttachmentSampleCount ;
2022-11-17 20:35:21 +00:00
TextureFormat depthStencilFormat ;
2024-01-18 20:27:34 +00:00
2024-02-23 08:06:04 +00:00
bool copyPassActive ;
bool computePassActive ;
2024-01-18 20:27:34 +00:00
internal bool Submitted ;
2022-11-17 20:35:21 +00:00
# endif
2022-02-23 05:14:32 +00:00
2024-01-18 20:27:34 +00:00
// called from CommandBufferPool
internal CommandBuffer ( GraphicsDevice device )
2022-02-23 05:14:32 +00:00
{
Device = device ;
2024-01-18 20:27:34 +00:00
Handle = IntPtr . Zero ;
#if DEBUG
ResetStateTracking ( ) ;
# endif
}
internal void SetHandle ( nint handle )
{
2022-02-23 05:14:32 +00:00
Handle = handle ;
2024-01-18 20:27:34 +00:00
}
2022-11-17 20:35:21 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
internal void ResetStateTracking ( )
{
swapchainTextureAcquired = false ;
2022-09-29 22:22:50 +00:00
currentGraphicsPipeline = null ;
currentComputePipeline = null ;
renderPassActive = false ;
2024-01-16 07:11:28 +00:00
colorAttachmentSampleCount = SampleCount . One ;
depthStencilAttachmentSampleCount = SampleCount . One ;
colorAttachmentCount = 0 ;
2022-11-17 20:35:21 +00:00
colorFormatOne = TextureFormat . R8G8B8A8 ;
colorFormatTwo = TextureFormat . R8G8B8A8 ;
colorFormatThree = TextureFormat . R8G8B8A8 ;
colorFormatFour = TextureFormat . R8G8B8A8 ;
depthStencilFormat = TextureFormat . D16 ;
2024-01-18 20:27:34 +00:00
2024-02-23 08:06:04 +00:00
copyPassActive = false ;
computePassActive = false ;
2024-01-18 20:27:34 +00:00
Submitted = false ;
2022-02-23 05:14:32 +00:00
}
2024-01-18 20:27:34 +00:00
# endif
2022-02-23 05:14:32 +00:00
2024-02-23 23:53:49 +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
AssertNotSubmitted ( ) ;
if ( ! window . 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
var texturePtr = Refresh . Refresh_AcquireSwapchainTexture (
Device . Handle ,
Handle ,
window . Handle ,
out var width ,
out var height
) ;
if ( texturePtr = = IntPtr . Zero )
{
return null ;
}
// 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
swapchainTextureAcquired = true ;
# endif
return window . SwapchainTexture ;
}
2022-11-17 20:35:21 +00:00
/// <summary>
/// Begins a render pass.
/// All render state, resource binding, and draw commands must be made within a render pass.
2024-02-23 08:06:04 +00:00
/// It is an error to call this during any kind of pass.
2022-11-17 20:35:21 +00:00
/// </summary>
/// <param name="colorAttachmentInfo">The color attachment to use in the render pass.</param>
public unsafe void BeginRenderPass (
in ColorAttachmentInfo colorAttachmentInfo
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 20:39:59 +00:00
AssertNotInPass ( "Cannot begin a render pass inside another pass!" ) ;
2022-11-17 20:35:21 +00:00
AssertTextureNotNull ( colorAttachmentInfo ) ;
AssertColorTarget ( colorAttachmentInfo ) ;
# endif
var refreshColorAttachmentInfos = stackalloc Refresh . ColorAttachmentInfo [ 1 ] ;
refreshColorAttachmentInfos [ 0 ] = colorAttachmentInfo . ToRefresh ( ) ;
Refresh . Refresh_BeginRenderPass (
Device . Handle ,
Handle ,
( IntPtr ) refreshColorAttachmentInfos ,
1 ,
IntPtr . Zero
) ;
#if DEBUG
renderPassActive = true ;
2024-01-16 07:11:28 +00:00
hasDepthStencilAttachment = false ;
colorAttachmentSampleCount = colorAttachmentInfo . Texture . SampleCount ;
colorAttachmentCount = 1 ;
2022-11-17 20:35:21 +00:00
colorFormatOne = colorAttachmentInfo . Texture . Format ;
# endif
}
2022-04-13 03:06:14 +00:00
2022-02-23 05:14:32 +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>
2022-11-17 20:35:21 +00:00
/// <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>
2022-02-23 05:14:32 +00:00
public unsafe void BeginRenderPass (
2022-11-17 20:35:21 +00:00
in ColorAttachmentInfo colorAttachmentInfoOne ,
in ColorAttachmentInfo colorAttachmentInfoTwo
) {
2022-02-25 05:34:36 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-11-17 20:35:21 +00:00
AssertTextureNotNull ( colorAttachmentInfoOne ) ;
AssertColorTarget ( colorAttachmentInfoOne ) ;
AssertTextureNotNull ( colorAttachmentInfoTwo ) ;
AssertColorTarget ( colorAttachmentInfoTwo ) ;
2024-01-16 07:11:28 +00:00
AssertSameSampleCount ( colorAttachmentInfoOne . Texture , colorAttachmentInfoTwo . Texture ) ;
2022-02-25 05:34:36 +00:00
# endif
2022-11-17 20:35:21 +00:00
var refreshColorAttachmentInfos = stackalloc Refresh . ColorAttachmentInfo [ 2 ] ;
refreshColorAttachmentInfos [ 0 ] = colorAttachmentInfoOne . ToRefresh ( ) ;
refreshColorAttachmentInfos [ 1 ] = colorAttachmentInfoTwo . ToRefresh ( ) ;
2022-02-25 05:34:36 +00:00
2022-11-17 20:35:21 +00:00
Refresh . Refresh_BeginRenderPass (
Device . Handle ,
Handle ,
( IntPtr ) refreshColorAttachmentInfos ,
2 ,
IntPtr . Zero
) ;
2022-02-25 05:34:36 +00:00
2022-11-17 20:35:21 +00:00
#if DEBUG
renderPassActive = true ;
2024-01-16 07:11:28 +00:00
hasDepthStencilAttachment = false ;
colorAttachmentSampleCount = colorAttachmentInfoOne . Texture . SampleCount ;
colorAttachmentCount = 2 ;
2022-11-17 20:35:21 +00:00
colorFormatOne = colorAttachmentInfoOne . Texture . Format ;
colorFormatTwo = colorAttachmentInfoTwo . Texture . Format ;
# endif
}
/// <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>
public unsafe void BeginRenderPass (
in ColorAttachmentInfo colorAttachmentInfoOne ,
in ColorAttachmentInfo colorAttachmentInfoTwo ,
in ColorAttachmentInfo colorAttachmentInfoThree
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-11-17 20:35:21 +00:00
AssertTextureNotNull ( colorAttachmentInfoOne ) ;
AssertColorTarget ( colorAttachmentInfoOne ) ;
2022-09-07 20:07:17 +00:00
2022-11-17 20:35:21 +00:00
AssertTextureNotNull ( colorAttachmentInfoTwo ) ;
AssertColorTarget ( colorAttachmentInfoTwo ) ;
AssertTextureNotNull ( colorAttachmentInfoThree ) ;
AssertColorTarget ( colorAttachmentInfoThree ) ;
2024-01-16 07:11:28 +00:00
AssertSameSampleCount ( colorAttachmentInfoOne . Texture , colorAttachmentInfoTwo . Texture ) ;
AssertSameSampleCount ( colorAttachmentInfoOne . Texture , colorAttachmentInfoThree . Texture ) ;
2022-11-17 20:35:21 +00:00
# endif
var refreshColorAttachmentInfos = stackalloc Refresh . ColorAttachmentInfo [ 3 ] ;
refreshColorAttachmentInfos [ 0 ] = colorAttachmentInfoOne . ToRefresh ( ) ;
refreshColorAttachmentInfos [ 1 ] = colorAttachmentInfoTwo . ToRefresh ( ) ;
refreshColorAttachmentInfos [ 2 ] = colorAttachmentInfoThree . ToRefresh ( ) ;
Refresh . Refresh_BeginRenderPass (
Device . Handle ,
Handle ,
( IntPtr ) refreshColorAttachmentInfos ,
3 ,
IntPtr . Zero
) ;
#if DEBUG
2022-09-07 20:07:17 +00:00
renderPassActive = true ;
2024-01-16 07:11:28 +00:00
hasDepthStencilAttachment = false ;
colorAttachmentSampleCount = colorAttachmentInfoOne . Texture . SampleCount ;
colorAttachmentCount = 3 ;
2022-11-17 20:35:21 +00:00
colorFormatOne = colorAttachmentInfoOne . Texture . Format ;
colorFormatTwo = colorAttachmentInfoTwo . Texture . Format ;
colorFormatThree = colorAttachmentInfoThree . Texture . Format ;
# endif
}
/// <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>
public unsafe void BeginRenderPass (
in ColorAttachmentInfo colorAttachmentInfoOne ,
in ColorAttachmentInfo colorAttachmentInfoTwo ,
in ColorAttachmentInfo colorAttachmentInfoThree ,
in ColorAttachmentInfo colorAttachmentInfoFour
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-11-17 20:35:21 +00:00
AssertTextureNotNull ( colorAttachmentInfoOne ) ;
AssertColorTarget ( colorAttachmentInfoOne ) ;
AssertTextureNotNull ( colorAttachmentInfoTwo ) ;
AssertColorTarget ( colorAttachmentInfoTwo ) ;
AssertTextureNotNull ( colorAttachmentInfoThree ) ;
AssertColorTarget ( colorAttachmentInfoThree ) ;
AssertTextureNotNull ( colorAttachmentInfoFour ) ;
AssertColorTarget ( colorAttachmentInfoFour ) ;
2024-01-16 07:11:28 +00:00
AssertSameSampleCount ( colorAttachmentInfoOne . Texture , colorAttachmentInfoTwo . Texture ) ;
AssertSameSampleCount ( colorAttachmentInfoOne . Texture , colorAttachmentInfoThree . Texture ) ;
AssertSameSampleCount ( colorAttachmentInfoOne . Texture , colorAttachmentInfoFour . Texture ) ;
2022-11-17 20:35:21 +00:00
# endif
var refreshColorAttachmentInfos = stackalloc Refresh . ColorAttachmentInfo [ 4 ] ;
refreshColorAttachmentInfos [ 0 ] = colorAttachmentInfoOne . ToRefresh ( ) ;
refreshColorAttachmentInfos [ 1 ] = colorAttachmentInfoTwo . ToRefresh ( ) ;
refreshColorAttachmentInfos [ 2 ] = colorAttachmentInfoThree . ToRefresh ( ) ;
refreshColorAttachmentInfos [ 3 ] = colorAttachmentInfoFour . ToRefresh ( ) ;
Refresh . Refresh_BeginRenderPass (
Device . Handle ,
Handle ,
( IntPtr ) refreshColorAttachmentInfos ,
4 ,
IntPtr . Zero
) ;
#if DEBUG
renderPassActive = true ;
2024-01-16 07:11:28 +00:00
hasDepthStencilAttachment = false ;
colorAttachmentSampleCount = colorAttachmentInfoOne . Texture . SampleCount ;
colorAttachmentCount = 4 ;
2022-11-17 20:35:21 +00:00
colorFormatOne = colorAttachmentInfoOne . Texture . Format ;
colorFormatTwo = colorAttachmentInfoTwo . Texture . Format ;
colorFormatThree = colorAttachmentInfoThree . Texture . Format ;
colorFormatFour = colorAttachmentInfoFour . Texture . Format ;
# endif
2022-02-23 05:14:32 +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>
2022-02-25 05:34:36 +00:00
/// <param name="depthStencilAttachmentInfo">The depth stencil attachment to use in the render pass.</param>
2022-02-23 05:14:32 +00:00
public unsafe void BeginRenderPass (
2022-11-17 20:35:21 +00:00
in DepthStencilAttachmentInfo depthStencilAttachmentInfo
) {
2022-02-25 05:34:36 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-11-09 18:49:53 +00:00
AssertValidDepthAttachment ( depthStencilAttachmentInfo ) ;
2022-02-25 05:34:36 +00:00
# endif
2022-11-17 20:35:21 +00:00
var refreshDepthStencilAttachmentInfo = depthStencilAttachmentInfo . ToRefresh ( ) ;
Refresh . Refresh_BeginRenderPass (
Device . Handle ,
Handle ,
( Refresh . ColorAttachmentInfo * ) IntPtr . Zero ,
0 ,
& refreshDepthStencilAttachmentInfo
) ;
2022-02-25 05:34:36 +00:00
2022-11-17 20:35:21 +00:00
#if DEBUG
renderPassActive = true ;
2024-01-16 07:11:28 +00:00
hasDepthStencilAttachment = true ;
depthStencilAttachmentSampleCount = depthStencilAttachmentInfo . Texture . SampleCount ;
2022-11-17 20:35:21 +00:00
depthStencilFormat = depthStencilAttachmentInfo . Texture . Format ;
# endif
}
/// <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>
public unsafe void BeginRenderPass (
in DepthStencilAttachmentInfo depthStencilAttachmentInfo ,
in ColorAttachmentInfo colorAttachmentInfo
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-11-17 20:35:21 +00:00
AssertValidDepthAttachment ( depthStencilAttachmentInfo ) ;
AssertTextureNotNull ( colorAttachmentInfo ) ;
AssertColorTarget ( colorAttachmentInfo ) ;
2024-01-16 07:11:28 +00:00
AssertSameSampleCount ( colorAttachmentInfo . Texture , depthStencilAttachmentInfo . Texture ) ;
2022-11-17 20:35:21 +00:00
# endif
var refreshColorAttachmentInfos = stackalloc Refresh . ColorAttachmentInfo [ 1 ] ;
refreshColorAttachmentInfos [ 0 ] = colorAttachmentInfo . ToRefresh ( ) ;
2022-02-25 05:34:36 +00:00
var refreshDepthStencilAttachmentInfo = depthStencilAttachmentInfo . ToRefresh ( ) ;
2022-11-17 20:35:21 +00:00
Refresh . Refresh_BeginRenderPass (
Device . Handle ,
Handle ,
refreshColorAttachmentInfos ,
1 ,
& refreshDepthStencilAttachmentInfo
) ;
#if DEBUG
renderPassActive = true ;
2024-01-16 07:11:28 +00:00
hasDepthStencilAttachment = true ;
colorAttachmentSampleCount = colorAttachmentInfo . Texture . SampleCount ;
colorAttachmentCount = 1 ;
depthStencilAttachmentSampleCount = depthStencilAttachmentInfo . Texture . SampleCount ;
2022-11-17 20:35:21 +00:00
colorFormatOne = colorAttachmentInfo . Texture . Format ;
depthStencilFormat = depthStencilAttachmentInfo . Texture . Format ;
# endif
}
/// <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>
public unsafe void BeginRenderPass (
in DepthStencilAttachmentInfo depthStencilAttachmentInfo ,
in ColorAttachmentInfo colorAttachmentInfoOne ,
in ColorAttachmentInfo colorAttachmentInfoTwo
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-11-17 20:35:21 +00:00
AssertValidDepthAttachment ( depthStencilAttachmentInfo ) ;
AssertTextureNotNull ( colorAttachmentInfoOne ) ;
AssertColorTarget ( colorAttachmentInfoOne ) ;
AssertTextureNotNull ( colorAttachmentInfoTwo ) ;
AssertColorTarget ( colorAttachmentInfoTwo ) ;
2024-01-16 07:11:28 +00:00
AssertSameSampleCount ( colorAttachmentInfoOne . Texture , colorAttachmentInfoTwo . Texture ) ;
AssertSameSampleCount ( colorAttachmentInfoOne . Texture , depthStencilAttachmentInfo . Texture ) ;
2022-11-17 20:35:21 +00:00
# endif
var refreshColorAttachmentInfos = stackalloc Refresh . ColorAttachmentInfo [ 2 ] ;
refreshColorAttachmentInfos [ 0 ] = colorAttachmentInfoOne . ToRefresh ( ) ;
refreshColorAttachmentInfos [ 1 ] = colorAttachmentInfoTwo . ToRefresh ( ) ;
var refreshDepthStencilAttachmentInfo = depthStencilAttachmentInfo . ToRefresh ( ) ;
Refresh . Refresh_BeginRenderPass (
Device . Handle ,
Handle ,
refreshColorAttachmentInfos ,
2 ,
& refreshDepthStencilAttachmentInfo
) ;
#if DEBUG
renderPassActive = true ;
2024-01-16 07:11:28 +00:00
hasDepthStencilAttachment = true ;
colorAttachmentSampleCount = colorAttachmentInfoOne . Texture . SampleCount ;
colorAttachmentCount = 2 ;
2022-11-17 20:35:21 +00:00
colorFormatOne = colorAttachmentInfoOne . Texture . Format ;
colorFormatTwo = colorAttachmentInfoTwo . Texture . Format ;
depthStencilFormat = depthStencilAttachmentInfo . Texture . Format ;
# endif
}
/// <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>
public unsafe void BeginRenderPass (
in DepthStencilAttachmentInfo depthStencilAttachmentInfo ,
in ColorAttachmentInfo colorAttachmentInfoOne ,
in ColorAttachmentInfo colorAttachmentInfoTwo ,
in ColorAttachmentInfo colorAttachmentInfoThree
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-11-17 20:35:21 +00:00
AssertValidDepthAttachment ( depthStencilAttachmentInfo ) ;
AssertTextureNotNull ( colorAttachmentInfoOne ) ;
AssertColorTarget ( colorAttachmentInfoOne ) ;
AssertTextureNotNull ( colorAttachmentInfoTwo ) ;
AssertColorTarget ( colorAttachmentInfoTwo ) ;
AssertTextureNotNull ( colorAttachmentInfoThree ) ;
AssertColorTarget ( colorAttachmentInfoThree ) ;
2024-01-16 07:11:28 +00:00
AssertSameSampleCount ( colorAttachmentInfoOne . Texture , colorAttachmentInfoTwo . Texture ) ;
AssertSameSampleCount ( colorAttachmentInfoOne . Texture , colorAttachmentInfoTwo . Texture ) ;
AssertSameSampleCount ( colorAttachmentInfoOne . Texture , depthStencilAttachmentInfo . Texture ) ;
2022-11-17 20:35:21 +00:00
# endif
var refreshColorAttachmentInfos = stackalloc Refresh . ColorAttachmentInfo [ 3 ] ;
refreshColorAttachmentInfos [ 0 ] = colorAttachmentInfoOne . ToRefresh ( ) ;
refreshColorAttachmentInfos [ 1 ] = colorAttachmentInfoTwo . ToRefresh ( ) ;
refreshColorAttachmentInfos [ 2 ] = colorAttachmentInfoThree . ToRefresh ( ) ;
var refreshDepthStencilAttachmentInfo = depthStencilAttachmentInfo . ToRefresh ( ) ;
Refresh . Refresh_BeginRenderPass (
Device . Handle ,
Handle ,
refreshColorAttachmentInfos ,
3 ,
& refreshDepthStencilAttachmentInfo
) ;
#if DEBUG
renderPassActive = true ;
2024-01-16 07:11:28 +00:00
hasDepthStencilAttachment = true ;
colorAttachmentSampleCount = colorAttachmentInfoOne . Texture . SampleCount ;
colorAttachmentCount = 3 ;
2022-11-17 20:35:21 +00:00
colorFormatOne = colorAttachmentInfoOne . Texture . Format ;
colorFormatTwo = colorAttachmentInfoTwo . Texture . Format ;
colorFormatThree = colorAttachmentInfoThree . Texture . Format ;
depthStencilFormat = depthStencilAttachmentInfo . Texture . Format ;
# endif
}
/// <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>
public unsafe void BeginRenderPass (
in DepthStencilAttachmentInfo depthStencilAttachmentInfo ,
in ColorAttachmentInfo colorAttachmentInfoOne ,
in ColorAttachmentInfo colorAttachmentInfoTwo ,
in ColorAttachmentInfo colorAttachmentInfoThree ,
in ColorAttachmentInfo colorAttachmentInfoFour
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-11-17 20:35:21 +00:00
AssertValidDepthAttachment ( depthStencilAttachmentInfo ) ;
AssertTextureNotNull ( colorAttachmentInfoOne ) ;
AssertColorTarget ( colorAttachmentInfoOne ) ;
AssertTextureNotNull ( colorAttachmentInfoTwo ) ;
AssertColorTarget ( colorAttachmentInfoTwo ) ;
AssertTextureNotNull ( colorAttachmentInfoThree ) ;
AssertColorTarget ( colorAttachmentInfoThree ) ;
AssertTextureNotNull ( colorAttachmentInfoFour ) ;
AssertColorTarget ( colorAttachmentInfoFour ) ;
2024-01-16 07:11:28 +00:00
AssertSameSampleCount ( colorAttachmentInfoOne . Texture , colorAttachmentInfoTwo . Texture ) ;
AssertSameSampleCount ( colorAttachmentInfoOne . Texture , colorAttachmentInfoThree . Texture ) ;
AssertSameSampleCount ( colorAttachmentInfoOne . Texture , colorAttachmentInfoFour . Texture ) ;
AssertSameSampleCount ( colorAttachmentInfoOne . Texture , depthStencilAttachmentInfo . Texture ) ;
2022-11-17 20:35:21 +00:00
# endif
var refreshColorAttachmentInfos = stackalloc Refresh . ColorAttachmentInfo [ 4 ] ;
refreshColorAttachmentInfos [ 0 ] = colorAttachmentInfoOne . ToRefresh ( ) ;
refreshColorAttachmentInfos [ 1 ] = colorAttachmentInfoTwo . ToRefresh ( ) ;
refreshColorAttachmentInfos [ 2 ] = colorAttachmentInfoThree . ToRefresh ( ) ;
refreshColorAttachmentInfos [ 3 ] = colorAttachmentInfoFour . ToRefresh ( ) ;
var refreshDepthStencilAttachmentInfo = depthStencilAttachmentInfo . ToRefresh ( ) ;
2022-09-07 20:07:17 +00:00
2022-11-17 20:35:21 +00:00
Refresh . Refresh_BeginRenderPass (
Device . Handle ,
Handle ,
refreshColorAttachmentInfos ,
4 ,
& refreshDepthStencilAttachmentInfo
) ;
#if DEBUG
2022-09-07 20:07:17 +00:00
renderPassActive = true ;
2024-01-16 07:11:28 +00:00
hasDepthStencilAttachment = true ;
colorAttachmentSampleCount = colorAttachmentInfoOne . Texture . SampleCount ;
colorAttachmentCount = 4 ;
2022-11-17 20:35:21 +00:00
colorFormatOne = colorAttachmentInfoOne . Texture . Format ;
colorFormatTwo = colorAttachmentInfoTwo . Texture . Format ;
colorFormatThree = colorAttachmentInfoThree . Texture . Format ;
colorFormatFour = colorAttachmentInfoFour . Texture . Format ;
depthStencilFormat = depthStencilAttachmentInfo . Texture . Format ;
# endif
2022-02-23 05:14:32 +00:00
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds a graphics pipeline so that rendering work may be performed.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="graphicsPipeline">The graphics pipeline to bind.</param>
public void BindGraphicsPipeline (
GraphicsPipeline graphicsPipeline
2022-11-17 20:35:21 +00:00
) {
2024-01-18 20:27:34 +00:00
#if DEBUG
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertRenderPassActive ( ) ;
AssertRenderPassPipelineFormatMatch ( graphicsPipeline ) ;
if ( colorAttachmentCount > 0 )
{
if ( graphicsPipeline . SampleCount ! = colorAttachmentSampleCount )
{
throw new System . InvalidOperationException ( $"Sample count mismatch! Graphics pipeline sample count: {graphicsPipeline.SampleCount}, Color attachment sample count: {colorAttachmentSampleCount}" ) ;
}
}
if ( hasDepthStencilAttachment )
{
if ( graphicsPipeline . SampleCount ! = depthStencilAttachmentSampleCount )
{
throw new System . InvalidOperationException ( $"Sample count mismatch! Graphics pipeline sample count: {graphicsPipeline.SampleCount}, Depth stencil attachment sample count: {depthStencilAttachmentSampleCount}" ) ;
}
}
2024-01-18 20:27:34 +00:00
# endif
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindGraphicsPipeline (
2022-02-23 05:14:32 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
graphicsPipeline . Handle
2022-02-23 05:14:32 +00:00
) ;
2022-09-07 20:07:17 +00:00
2022-11-17 20:35:21 +00:00
#if DEBUG
2024-02-23 23:53:49 +00:00
currentGraphicsPipeline = graphicsPipeline ;
2022-11-17 20:35:21 +00:00
# endif
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Sets the viewport. Only valid during a render pass.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
public void SetViewport ( in Viewport viewport )
{
2022-11-17 20:35:21 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertRenderPassActive ( ) ;
2022-11-17 20:35:21 +00:00
# endif
2024-02-23 23:53:49 +00:00
Refresh . Refresh_SetViewport (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
viewport . ToRefresh ( )
2022-11-17 20:35:21 +00:00
) ;
2022-02-23 05:14:32 +00:00
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Sets the scissor area. Only valid during a render pass.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
public void SetScissor ( in Rect scissor )
{
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertRenderPassActive ( ) ;
2022-09-07 20:07:17 +00:00
2024-02-23 23:53:49 +00:00
if ( scissor . X < 0 | | scissor . Y < 0 | | scissor . W < = 0 | | scissor . H < = 0 )
{
throw new System . ArgumentOutOfRangeException ( "Scissor position cannot be negative and dimensions must be positive!" ) ;
}
# endif
2022-09-07 20:07:17 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_SetScissor (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
scissor . ToRefresh ( )
2022-11-17 20:35:21 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds vertex buffers to be used by subsequent draw calls.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="bufferBinding">Buffer to bind and associated offset.</param>
/// <param name="firstBinding">The index of the first vertex input binding whose state is updated by the command.</param>
public unsafe void BindVertexBuffers (
in BufferBinding bufferBinding ,
uint firstBinding = 0
2022-11-17 20:35:21 +00:00
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertGraphicsPipelineBound ( ) ;
2022-11-17 20:35:21 +00:00
# endif
2024-02-23 23:53:49 +00:00
var bufferPtrs = stackalloc IntPtr [ 1 ] ;
var offsets = stackalloc ulong [ 1 ] ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
bufferPtrs [ 0 ] = bufferBinding . Buffer . Handle ;
offsets [ 0 ] = bufferBinding . Offset ;
Refresh . Refresh_BindVertexBuffers (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
firstBinding ,
1 ,
( IntPtr ) bufferPtrs ,
( IntPtr ) offsets
2022-11-17 20:35:21 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds vertex buffers to be used by subsequent draw calls.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="bufferBindingOne">Buffer to bind and associated offset.</param>
/// <param name="bufferBindingTwo">Buffer to bind and associated offset.</param>
/// <param name="firstBinding">The index of the first vertex input binding whose state is updated by the command.</param>
public unsafe void BindVertexBuffers (
in BufferBinding bufferBindingOne ,
in BufferBinding bufferBindingTwo ,
uint firstBinding = 0
2022-11-17 20:35:21 +00:00
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertGraphicsPipelineBound ( ) ;
2022-11-17 20:35:21 +00:00
# endif
2024-02-23 23:53:49 +00:00
var bufferPtrs = stackalloc IntPtr [ 2 ] ;
var offsets = stackalloc ulong [ 2 ] ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
bufferPtrs [ 0 ] = bufferBindingOne . Buffer . Handle ;
bufferPtrs [ 1 ] = bufferBindingTwo . Buffer . Handle ;
offsets [ 0 ] = bufferBindingOne . Offset ;
offsets [ 1 ] = bufferBindingTwo . Offset ;
Refresh . Refresh_BindVertexBuffers (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
firstBinding ,
2 ,
( IntPtr ) bufferPtrs ,
( IntPtr ) offsets
2022-11-17 20:35:21 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds vertex buffers to be used by subsequent draw calls.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="bufferBindingOne">Buffer to bind and associated offset.</param>
/// <param name="bufferBindingTwo">Buffer to bind and associated offset.</param>
/// <param name="bufferBindingThree">Buffer to bind and associated offset.</param>
/// <param name="firstBinding">The index of the first vertex input binding whose state is updated by the command.</param>
public unsafe void BindVertexBuffers (
in BufferBinding bufferBindingOne ,
in BufferBinding bufferBindingTwo ,
in BufferBinding bufferBindingThree ,
uint firstBinding = 0
2022-11-17 20:35:21 +00:00
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertGraphicsPipelineBound ( ) ;
2022-09-07 20:07:17 +00:00
# endif
2024-02-23 23:53:49 +00:00
var bufferPtrs = stackalloc IntPtr [ 3 ] ;
var offsets = stackalloc ulong [ 3 ] ;
2022-02-23 05:14:32 +00:00
2024-02-23 23:53:49 +00:00
bufferPtrs [ 0 ] = bufferBindingOne . Buffer . Handle ;
bufferPtrs [ 1 ] = bufferBindingTwo . Buffer . Handle ;
bufferPtrs [ 2 ] = bufferBindingThree . Buffer . Handle ;
2022-02-23 05:14:32 +00:00
2024-02-23 23:53:49 +00:00
offsets [ 0 ] = bufferBindingOne . Offset ;
offsets [ 1 ] = bufferBindingTwo . Offset ;
offsets [ 2 ] = bufferBindingThree . Offset ;
Refresh . Refresh_BindVertexBuffers (
2022-02-23 05:14:32 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
firstBinding ,
3 ,
( IntPtr ) bufferPtrs ,
( IntPtr ) offsets
) ;
2022-02-23 05:14:32 +00:00
}
2022-11-17 20:35:21 +00:00
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds vertex buffers to be used by subsequent draw calls.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="bufferBindingOne">Buffer to bind and associated offset.</param>
/// <param name="bufferBindingTwo">Buffer to bind and associated offset.</param>
/// <param name="bufferBindingThree">Buffer to bind and associated offset.</param>
/// <param name="bufferBindingFour">Buffer to bind and associated offset.</param>
/// <param name="firstBinding">The index of the first vertex input binding whose state is updated by the command.</param>
public unsafe void BindVertexBuffers (
in BufferBinding bufferBindingOne ,
in BufferBinding bufferBindingTwo ,
in BufferBinding bufferBindingThree ,
in BufferBinding bufferBindingFour ,
uint firstBinding = 0
2022-11-17 20:35:21 +00:00
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertGraphicsPipelineBound ( ) ;
2022-11-17 20:35:21 +00:00
# endif
2024-02-23 23:53:49 +00:00
var bufferPtrs = stackalloc IntPtr [ 4 ] ;
var offsets = stackalloc ulong [ 4 ] ;
2024-02-23 08:06:04 +00:00
2024-02-23 23:53:49 +00:00
bufferPtrs [ 0 ] = bufferBindingOne . Buffer . Handle ;
bufferPtrs [ 1 ] = bufferBindingTwo . Buffer . Handle ;
bufferPtrs [ 2 ] = bufferBindingThree . Buffer . Handle ;
bufferPtrs [ 3 ] = bufferBindingFour . Buffer . Handle ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
offsets [ 0 ] = bufferBindingOne . Offset ;
offsets [ 1 ] = bufferBindingTwo . Offset ;
offsets [ 2 ] = bufferBindingThree . Offset ;
offsets [ 3 ] = bufferBindingFour . Offset ;
Refresh . Refresh_BindVertexBuffers (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
firstBinding ,
4 ,
( IntPtr ) bufferPtrs ,
( IntPtr ) offsets
2022-11-17 20:35:21 +00:00
) ;
}
2022-02-23 05:14:32 +00:00
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds vertex buffers to be used by subsequent draw calls.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="bufferBindings">Spawn of buffers to bind and their associated offsets.</param>
/// <param name="firstBinding">The index of the first vertex input binding whose state is updated by the command.</param>
public unsafe void BindVertexBuffers (
in Span < BufferBinding > bufferBindings ,
uint firstBinding = 0
2022-11-17 20:35:21 +00:00
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertGraphicsPipelineBound ( ) ;
2022-11-17 20:35:21 +00:00
# endif
2022-09-07 20:07:17 +00:00
2024-02-23 23:53:49 +00:00
var bufferPtrs = stackalloc IntPtr [ bufferBindings . Length ] ;
var offsets = stackalloc ulong [ bufferBindings . Length ] ;
2024-02-23 08:06:04 +00:00
2024-02-23 23:53:49 +00:00
for ( var i = 0 ; i < bufferBindings . Length ; i + = 1 )
{
bufferPtrs [ i ] = bufferBindings [ i ] . Buffer . Handle ;
offsets [ i ] = bufferBindings [ i ] . Offset ;
}
2022-09-07 20:07:17 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindVertexBuffers (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
firstBinding ,
( uint ) bufferBindings . Length ,
( IntPtr ) bufferPtrs ,
( IntPtr ) offsets
2022-11-17 20:35:21 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds an index buffer to be used by subsequent draw calls.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="indexBuffer">The index buffer to bind.</param>
/// <param name="indexElementSize">The size in bytes of the index buffer elements.</param>
/// <param name="offset">The offset index for the buffer.</param>
public void BindIndexBuffer (
GpuBuffer indexBuffer ,
IndexElementSize indexElementSize ,
uint offset = 0
)
{
2022-11-17 20:35:21 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-11-17 20:35:21 +00:00
# endif
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindIndexBuffer (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
indexBuffer . Handle ,
offset ,
( Refresh . IndexElementSize ) indexElementSize
2022-11-17 20:35:21 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds samplers to be used by the vertex shader.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="textureSamplerBindings">The texture-sampler to bind.</param>
public unsafe void BindVertexSamplers (
in TextureSamplerBinding textureSamplerBinding
2022-11-17 20:35:21 +00:00
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertGraphicsPipelineBound ( ) ;
AssertVertexSamplerCount ( 1 ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBinding ) ;
AssertTextureBindingUsageFlags ( textureSamplerBinding . Texture ) ;
2022-11-17 20:35:21 +00:00
# endif
2024-02-23 23:53:49 +00:00
var texturePtrs = stackalloc IntPtr [ 1 ] ;
var samplerPtrs = stackalloc IntPtr [ 1 ] ;
2024-02-23 08:06:04 +00:00
2024-02-23 23:53:49 +00:00
texturePtrs [ 0 ] = textureSamplerBinding . Texture . Handle ;
samplerPtrs [ 0 ] = textureSamplerBinding . Sampler . Handle ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindVertexSamplers (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
2024-02-23 08:06:04 +00:00
( IntPtr ) texturePtrs ,
2024-02-23 23:53:49 +00:00
( IntPtr ) samplerPtrs
2022-11-17 20:35:21 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds samplers to be used by the vertex shader.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="textureSamplerBindingOne">The first texture-sampler to bind.</param>
/// <param name="textureSamplerBindingTwo">The second texture-sampler to bind.</param>
public unsafe void BindVertexSamplers (
in TextureSamplerBinding textureSamplerBindingOne ,
in TextureSamplerBinding textureSamplerBindingTwo
2022-11-17 20:35:21 +00:00
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertGraphicsPipelineBound ( ) ;
AssertVertexSamplerCount ( 2 ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingOne ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingTwo ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingOne . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingTwo . Texture ) ;
2022-09-07 20:07:17 +00:00
# endif
2024-02-23 23:53:49 +00:00
var texturePtrs = stackalloc IntPtr [ 2 ] ;
var samplerPtrs = stackalloc IntPtr [ 2 ] ;
2022-02-23 05:14:32 +00:00
2024-02-23 23:53:49 +00:00
texturePtrs [ 0 ] = textureSamplerBindingOne . Texture . Handle ;
texturePtrs [ 1 ] = textureSamplerBindingTwo . Texture . Handle ;
2022-02-23 05:14:32 +00:00
2024-02-23 23:53:49 +00:00
samplerPtrs [ 0 ] = textureSamplerBindingOne . Sampler . Handle ;
samplerPtrs [ 1 ] = textureSamplerBindingTwo . Sampler . Handle ;
Refresh . Refresh_BindVertexSamplers (
2022-02-23 05:14:32 +00:00
Device . Handle ,
Handle ,
2024-02-23 08:06:04 +00:00
( IntPtr ) texturePtrs ,
2024-02-23 23:53:49 +00:00
( IntPtr ) samplerPtrs
2022-02-23 05:14:32 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds samplers to be used by the vertex shader.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="textureSamplerBindingOne">The first texture-sampler to bind.</param>
/// <param name="textureSamplerBindingTwo">The second texture-sampler to bind.</param>
/// <param name="textureSamplerBindingThree">The third texture-sampler to bind.</param>
public unsafe void BindVertexSamplers (
in TextureSamplerBinding textureSamplerBindingOne ,
in TextureSamplerBinding textureSamplerBindingTwo ,
in TextureSamplerBinding textureSamplerBindingThree
2022-11-17 20:35:21 +00:00
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertGraphicsPipelineBound ( ) ;
AssertVertexSamplerCount ( 3 ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingOne ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingTwo ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingThree ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingOne . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingTwo . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingThree . Texture ) ;
2022-09-07 20:07:17 +00:00
# endif
2024-02-23 23:53:49 +00:00
var texturePtrs = stackalloc IntPtr [ 3 ] ;
var samplerPtrs = stackalloc IntPtr [ 3 ] ;
texturePtrs [ 0 ] = textureSamplerBindingOne . Texture . Handle ;
texturePtrs [ 1 ] = textureSamplerBindingTwo . Texture . Handle ;
texturePtrs [ 2 ] = textureSamplerBindingThree . Texture . Handle ;
samplerPtrs [ 0 ] = textureSamplerBindingOne . Sampler . Handle ;
samplerPtrs [ 1 ] = textureSamplerBindingTwo . Sampler . Handle ;
samplerPtrs [ 2 ] = textureSamplerBindingThree . Sampler . Handle ;
Refresh . Refresh_BindVertexSamplers (
2022-02-23 05:14:32 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
2024-02-23 18:43:39 +00:00
) ;
}
2022-02-23 05:14:32 +00:00
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds samplers to be used by the vertex shader.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="textureSamplerBindingOne">The first texture-sampler to bind.</param>
/// <param name="textureSamplerBindingTwo">The second texture-sampler to bind.</param>
/// <param name="textureSamplerBindingThree">The third texture-sampler to bind.</param>
/// <param name="textureSamplerBindingThree">The fourth texture-sampler to bind.</param>
public unsafe void BindVertexSamplers (
in TextureSamplerBinding textureSamplerBindingOne ,
in TextureSamplerBinding textureSamplerBindingTwo ,
in TextureSamplerBinding textureSamplerBindingThree ,
in TextureSamplerBinding textureSamplerBindingFour
2022-11-17 20:35:21 +00:00
) {
2022-11-09 18:49:53 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertGraphicsPipelineBound ( ) ;
AssertVertexSamplerCount ( 4 ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingOne ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingTwo ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingThree ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingFour ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingOne . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingTwo . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingThree . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingFour . Texture ) ;
# endif
2022-11-09 18:49:53 +00:00
2024-02-23 23:53:49 +00:00
var texturePtrs = stackalloc IntPtr [ 4 ] ;
var samplerPtrs = stackalloc IntPtr [ 4 ] ;
2024-01-16 07:11:28 +00:00
2024-02-23 23:53:49 +00:00
texturePtrs [ 0 ] = textureSamplerBindingOne . Texture . Handle ;
texturePtrs [ 1 ] = textureSamplerBindingTwo . Texture . Handle ;
texturePtrs [ 2 ] = textureSamplerBindingThree . Texture . Handle ;
texturePtrs [ 3 ] = textureSamplerBindingFour . Texture . Handle ;
2022-11-09 18:49:53 +00:00
2024-02-23 23:53:49 +00:00
samplerPtrs [ 0 ] = textureSamplerBindingOne . Sampler . Handle ;
samplerPtrs [ 1 ] = textureSamplerBindingTwo . Sampler . Handle ;
samplerPtrs [ 2 ] = textureSamplerBindingThree . Sampler . Handle ;
samplerPtrs [ 3 ] = textureSamplerBindingFour . Sampler . Handle ;
Refresh . Refresh_BindVertexSamplers (
2022-02-23 05:14:32 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
2022-02-23 05:14:32 +00:00
) ;
}
2022-03-04 22:14:22 +00:00
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds samplers to be used by the vertex shader.
2022-03-04 22:14:22 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="textureSamplerBindings">The texture-sampler pairs to bind.</param>
public unsafe void BindVertexSamplers (
in Span < TextureSamplerBinding > textureSamplerBindings
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertGraphicsPipelineBound ( ) ;
AssertVertexSamplerCount ( textureSamplerBindings . Length ) ;
2022-09-07 20:07:17 +00:00
# endif
2024-02-23 23:53:49 +00:00
var texturePtrs = stackalloc IntPtr [ textureSamplerBindings . Length ] ;
var samplerPtrs = stackalloc IntPtr [ textureSamplerBindings . Length ] ;
2022-03-04 21:21:52 +00:00
2024-02-23 23:53:49 +00:00
for ( var i = 0 ; i < textureSamplerBindings . Length ; i + = 1 )
{
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-02-23 23:53:49 +00:00
AssertTextureSamplerBindingNonNull ( textureSamplerBindings [ i ] ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindings [ i ] . Texture ) ;
# endif
2022-12-14 00:09:32 +00:00
2024-02-23 23:53:49 +00:00
texturePtrs [ i ] = textureSamplerBindings [ i ] . Texture . Handle ;
samplerPtrs [ i ] = textureSamplerBindings [ i ] . Sampler . Handle ;
2022-12-14 00:09:32 +00:00
}
2022-09-07 20:07:17 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindVertexSamplers (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
2022-11-17 20:35:21 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds samplers to be used by the fragment shader.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="textureSamplerBinding">The texture-sampler to bind.</param>
public unsafe void BindFragmentSamplers (
in TextureSamplerBinding textureSamplerBinding
2022-11-17 20:35:21 +00:00
) {
2022-12-29 03:18:36 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-12-29 03:18:36 +00:00
AssertGraphicsPipelineBound ( ) ;
2024-02-23 23:53:49 +00:00
AssertFragmentSamplerCount ( 1 ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBinding ) ;
AssertTextureBindingUsageFlags ( textureSamplerBinding . Texture ) ;
2022-12-29 03:18:36 +00:00
# endif
2024-02-23 23:53:49 +00:00
var texturePtrs = stackalloc IntPtr [ 1 ] ;
var samplerPtrs = stackalloc IntPtr [ 1 ] ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
texturePtrs [ 0 ] = textureSamplerBinding . Texture . Handle ;
samplerPtrs [ 0 ] = textureSamplerBinding . Sampler . Handle ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindFragmentSamplers (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
2022-11-17 20:35:21 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds samplers to be used by the fragment shader.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="textureSamplerBindingOne">The first texture-sampler to bind.</param>
/// <param name="textureSamplerBindingTwo">The second texture-sampler to bind.</param>
public unsafe void BindFragmentSamplers (
in TextureSamplerBinding textureSamplerBindingOne ,
in TextureSamplerBinding textureSamplerBindingTwo
2022-11-17 20:35:21 +00:00
) {
2022-12-29 03:18:36 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-12-29 03:18:36 +00:00
AssertGraphicsPipelineBound ( ) ;
2024-02-23 23:53:49 +00:00
AssertFragmentSamplerCount ( 2 ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingOne ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingTwo ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingOne . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingTwo . Texture ) ;
2022-12-29 03:18:36 +00:00
# endif
2024-02-23 23:53:49 +00:00
var texturePtrs = stackalloc IntPtr [ 2 ] ;
var samplerPtrs = stackalloc IntPtr [ 2 ] ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
texturePtrs [ 0 ] = textureSamplerBindingOne . Texture . Handle ;
texturePtrs [ 1 ] = textureSamplerBindingTwo . Texture . Handle ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
samplerPtrs [ 0 ] = textureSamplerBindingOne . Sampler . Handle ;
samplerPtrs [ 1 ] = textureSamplerBindingTwo . Sampler . Handle ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindFragmentSamplers (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
2022-11-17 20:35:21 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds samplers to be used by the fragment shader.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="textureSamplerBindingOne">The first texture-sampler to bind.</param>
/// <param name="textureSamplerBindingTwo">The second texture-sampler to bind.</param>
/// <param name="textureSamplerBindingThree">The third texture-sampler to bind.</param>
public unsafe void BindFragmentSamplers (
in TextureSamplerBinding textureSamplerBindingOne ,
in TextureSamplerBinding textureSamplerBindingTwo ,
in TextureSamplerBinding textureSamplerBindingThree
2022-11-17 20:35:21 +00:00
) {
2022-12-29 03:18:36 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-12-29 03:18:36 +00:00
AssertGraphicsPipelineBound ( ) ;
2024-02-23 23:53:49 +00:00
AssertFragmentSamplerCount ( 3 ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingOne ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingTwo ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingThree ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingOne . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingTwo . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingThree . Texture ) ;
2022-12-29 03:18:36 +00:00
# endif
2024-02-23 23:53:49 +00:00
var texturePtrs = stackalloc IntPtr [ 3 ] ;
var samplerPtrs = stackalloc IntPtr [ 3 ] ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
texturePtrs [ 0 ] = textureSamplerBindingOne . Texture . Handle ;
texturePtrs [ 1 ] = textureSamplerBindingTwo . Texture . Handle ;
texturePtrs [ 2 ] = textureSamplerBindingThree . Texture . Handle ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
samplerPtrs [ 0 ] = textureSamplerBindingOne . Sampler . Handle ;
samplerPtrs [ 1 ] = textureSamplerBindingTwo . Sampler . Handle ;
samplerPtrs [ 2 ] = textureSamplerBindingThree . Sampler . Handle ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindFragmentSamplers (
2022-03-04 21:21:52 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
2022-03-04 21:21:52 +00:00
) ;
}
2022-02-23 05:14:32 +00:00
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds samplers to be used by the fragment shader.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="textureSamplerBindingOne">The first texture-sampler to bind.</param>
/// <param name="textureSamplerBindingTwo">The second texture-sampler to bind.</param>
/// <param name="textureSamplerBindingThree">The third texture-sampler to bind.</param>
/// <param name="textureSamplerBindingFour">The fourth texture-sampler to bind.</param>
public unsafe void BindFragmentSamplers (
in TextureSamplerBinding textureSamplerBindingOne ,
in TextureSamplerBinding textureSamplerBindingTwo ,
in TextureSamplerBinding textureSamplerBindingThree ,
in TextureSamplerBinding textureSamplerBindingFour
2022-11-17 20:35:21 +00:00
) {
2022-12-29 03:18:36 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-12-29 03:18:36 +00:00
AssertGraphicsPipelineBound ( ) ;
2024-02-23 23:53:49 +00:00
AssertFragmentSamplerCount ( 4 ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingOne ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingTwo ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingThree ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingFour ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingOne . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingTwo . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingThree . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingFour . Texture ) ;
# endif
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
var texturePtrs = stackalloc IntPtr [ 4 ] ;
var samplerPtrs = stackalloc IntPtr [ 4 ] ;
2022-02-23 05:14:32 +00:00
2024-02-23 23:53:49 +00:00
texturePtrs [ 0 ] = textureSamplerBindingOne . Texture . Handle ;
texturePtrs [ 1 ] = textureSamplerBindingTwo . Texture . Handle ;
texturePtrs [ 2 ] = textureSamplerBindingThree . Texture . Handle ;
texturePtrs [ 3 ] = textureSamplerBindingFour . Texture . Handle ;
samplerPtrs [ 0 ] = textureSamplerBindingOne . Sampler . Handle ;
samplerPtrs [ 1 ] = textureSamplerBindingTwo . Sampler . Handle ;
samplerPtrs [ 2 ] = textureSamplerBindingThree . Sampler . Handle ;
samplerPtrs [ 3 ] = textureSamplerBindingFour . Sampler . Handle ;
Refresh . Refresh_BindFragmentSamplers (
2022-02-23 05:14:32 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
2022-02-23 05:14:32 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds samplers to be used by the fragment shader.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="textureSamplerBindings">The texture-sampler pairs to bind.</param>
public unsafe void BindFragmentSamplers (
in Span < TextureSamplerBinding > textureSamplerBindings
2022-11-17 20:35:21 +00:00
) {
2022-12-29 03:18:36 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-12-29 03:18:36 +00:00
AssertGraphicsPipelineBound ( ) ;
2024-02-23 23:53:49 +00:00
AssertFragmentSamplerCount ( textureSamplerBindings . Length ) ;
2022-12-29 03:18:36 +00:00
# endif
2024-02-23 23:53:49 +00:00
var texturePtrs = stackalloc IntPtr [ textureSamplerBindings . Length ] ;
var samplerPtrs = stackalloc IntPtr [ textureSamplerBindings . Length ] ;
2022-02-23 05:14:32 +00:00
2024-02-23 23:53:49 +00:00
for ( var i = 0 ; i < textureSamplerBindings . Length ; i + = 1 )
2022-02-23 05:14:32 +00:00
{
2024-02-23 23:53:49 +00:00
#if DEBUG
AssertTextureSamplerBindingNonNull ( textureSamplerBindings [ i ] ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindings [ i ] . Texture ) ;
# endif
texturePtrs [ i ] = textureSamplerBindings [ i ] . Texture . Handle ;
samplerPtrs [ i ] = textureSamplerBindings [ i ] . Sampler . Handle ;
2022-02-23 05:14:32 +00:00
}
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindFragmentSamplers (
2022-02-23 05:14:32 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
2022-02-23 05:14:32 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Pushes vertex shader uniforms to the device.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <returns>A starting offset value to be used with draw calls.</returns>
public unsafe void PushVertexShaderUniforms (
void * uniformsPtr ,
uint size
) {
2024-01-18 20:27:34 +00:00
#if DEBUG
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertGraphicsPipelineBound ( ) ;
if ( currentGraphicsPipeline . VertexShaderInfo . UniformBufferSize = = 0 )
{
throw new InvalidOperationException ( "The current vertex shader does not take a uniform buffer!" ) ;
}
if ( currentGraphicsPipeline . VertexShaderInfo . UniformBufferSize ! = size )
{
throw new InvalidOperationException ( "Vertex uniform data size mismatch!" ) ;
}
2024-01-18 20:27:34 +00:00
# endif
2024-02-23 23:53:49 +00:00
Refresh . Refresh_PushVertexShaderUniforms (
2022-02-23 05:14:32 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
( IntPtr ) uniformsPtr ,
size
2022-02-23 05:14:32 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Pushes vertex shader uniforms to the device.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <returns>A starting offset value to be used with draw calls.</returns>
public unsafe void PushVertexShaderUniforms < T > (
in T uniforms
) where T : unmanaged
{
fixed ( T * uniformsPtr = & uniforms )
{
PushVertexShaderUniforms ( uniformsPtr , ( uint ) Marshal . SizeOf < T > ( ) ) ;
}
}
/// <summary>
/// Pushes fragment shader uniforms to the device.
/// </summary>
/// <returns>A starting offset to be used with draw calls.</returns>
public unsafe void PushFragmentShaderUniforms (
void * uniformsPtr ,
uint size
2022-11-17 20:35:21 +00:00
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-09-07 20:07:17 +00:00
AssertGraphicsPipelineBound ( ) ;
2024-02-23 23:53:49 +00:00
if ( currentGraphicsPipeline . FragmentShaderInfo . UniformBufferSize = = 0 )
{
throw new InvalidOperationException ( "The current fragment shader does not take a uniform buffer!" ) ;
}
2022-09-07 20:07:17 +00:00
2024-02-23 23:53:49 +00:00
if ( currentGraphicsPipeline . FragmentShaderInfo . UniformBufferSize ! = size )
{
throw new InvalidOperationException ( "Fragment uniform data size mismatch!" ) ;
}
# endif
2022-09-07 20:07:17 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_PushFragmentShaderUniforms (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
( IntPtr ) uniformsPtr ,
size
2022-11-17 20:35:21 +00:00
) ;
}
2022-02-23 05:14:32 +00:00
2022-11-17 20:35:21 +00:00
/// <summary>
2024-02-23 23:53:49 +00:00
/// Pushes fragment shader uniforms to the device.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <returns>A starting offset to be used with draw calls.</returns>
public unsafe void PushFragmentShaderUniforms < T > (
in T uniforms
) where T : unmanaged
{
fixed ( T * uniformsPtr = & uniforms )
{
PushFragmentShaderUniforms ( uniformsPtr , ( uint ) Marshal . SizeOf < T > ( ) ) ;
}
}
/// <summary>
/// Draws using instanced rendering.
/// </summary>
/// <param name="baseVertex">The starting index offset for the vertex buffer.</param>
/// <param name="startIndex">The starting index offset for the index buffer.</param>
/// <param name="primitiveCount">The number of primitives to draw.</param>
/// <param name="instanceCount">The number of instances to draw.</param>
public void DrawInstancedPrimitives (
uint baseVertex ,
uint startIndex ,
uint primitiveCount ,
uint instanceCount
)
{
2022-11-08 19:29:05 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-11-17 20:35:21 +00:00
AssertGraphicsPipelineBound ( ) ;
2022-11-08 19:29:05 +00:00
# endif
2024-02-23 23:53:49 +00:00
Refresh . Refresh_DrawInstancedPrimitives (
Device . Handle ,
Handle ,
baseVertex ,
startIndex ,
primitiveCount ,
instanceCount
) ;
}
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
/// <summary>
/// Draws using a vertex buffer and an index buffer.
/// </summary>
/// <param name="baseVertex">The starting index offset for the vertex buffer.</param>
/// <param name="startIndex">The starting index offset for the index buffer.</param>
/// <param name="primitiveCount">The number of primitives to draw.</param>
public void DrawIndexedPrimitives (
uint baseVertex ,
uint startIndex ,
uint primitiveCount
)
{
#if DEBUG
AssertNotSubmitted ( ) ;
AssertGraphicsPipelineBound ( ) ;
# endif
2022-02-23 05:14:32 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_DrawIndexedPrimitives (
2022-02-23 05:14:32 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
baseVertex ,
startIndex ,
primitiveCount
2022-02-23 05:14:32 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Draws using a vertex buffer.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="vertexStart"></param>
/// <param name="primitiveCount"></param>
public void DrawPrimitives (
uint vertexStart ,
uint primitiveCount
)
{
2022-11-17 20:35:21 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-11-17 20:35:21 +00:00
AssertGraphicsPipelineBound ( ) ;
# endif
2024-02-23 23:53:49 +00:00
Refresh . Refresh_DrawPrimitives (
Device . Handle ,
Handle ,
vertexStart ,
primitiveCount
) ;
}
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
/// <summary>
/// Similar to DrawPrimitives, but parameters are set from a buffer.
/// </summary>
/// <param name="buffer">The draw parameters buffer.</param>
/// <param name="offsetInBytes">The offset to start reading from the draw parameters buffer.</param>
/// <param name="drawCount">The number of draw parameter sets that should be read from the buffer.</param>
/// <param name="stride">The byte stride between sets of draw parameters.</param>
/// <param name="vertexParamOffset">An offset value obtained from PushVertexShaderUniforms. If no uniforms are required then use 0.</param>
/// <param name="fragmentParamOffset">An offset value obtained from PushFragmentShaderUniforms. If no uniforms are required the use 0.</param>
public void DrawPrimitivesIndirect (
GpuBuffer buffer ,
uint offsetInBytes ,
uint drawCount ,
uint stride
)
{
#if DEBUG
AssertNotSubmitted ( ) ;
AssertGraphicsPipelineBound ( ) ;
# endif
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_DrawPrimitivesIndirect (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
buffer . Handle ,
offsetInBytes ,
drawCount ,
stride
2022-11-17 20:35:21 +00:00
) ;
2022-11-16 01:53:30 +00:00
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Ends the current render pass.
/// This must be called before beginning another render pass or submitting the command buffer.
2022-11-16 01:53:30 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
public void EndRenderPass ( )
{
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-11-17 20:35:21 +00:00
# endif
2022-09-07 20:07:17 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_EndRenderPass (
Device . Handle ,
Handle
) ;
2022-09-07 20:07:17 +00:00
2024-02-23 23:53:49 +00:00
#if DEBUG
currentGraphicsPipeline = null ;
renderPassActive = false ;
# endif
}
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
/// <summary>
/// Blits a texture to another texture with the specified filter.
///
/// This operation cannot be performed inside any pass.
/// </summary>
public void Blit (
Texture source ,
Texture destination ,
Filter filter
) {
var sampler = filter = = Filter . Linear ? Device . LinearSampler : Device . PointSampler ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
BeginRenderPass ( new ColorAttachmentInfo ( destination ) ) ;
BindGraphicsPipeline ( Device . BlitPipeline ) ;
BindFragmentSamplers ( new TextureSamplerBinding ( source , sampler ) ) ;
DrawPrimitives ( 0 , 2 ) ;
EndRenderPass ( ) ;
}
public void BeginComputePass ( )
{
#if DEBUG
AssertNotSubmitted ( ) ;
AssertNotInPass ( "Cannot begin compute pass while in another pass!" ) ;
computePassActive = true ;
# endif
Refresh . Refresh_BeginComputePass (
2022-11-17 20:35:21 +00:00
Device . Handle ,
2024-02-23 23:53:49 +00:00
Handle
2022-11-17 20:35:21 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds a compute pipeline so that compute work may be dispatched.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="computePipeline">The compute pipeline to bind.</param>
public void BindComputePipeline (
ComputePipeline computePipeline
2022-11-17 20:35:21 +00:00
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertInComputePass ( "Cannot bind compute pipeline outside of compute pass!" ) ;
2022-09-07 20:07:17 +00:00
# endif
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindComputePipeline (
Device . Handle ,
Handle ,
computePipeline . Handle
) ;
2022-02-23 05:14:32 +00:00
2022-11-08 19:29:05 +00:00
#if DEBUG
2024-02-23 23:53:49 +00:00
currentComputePipeline = computePipeline ;
2022-11-08 19:29:05 +00:00
# endif
2024-02-23 23:53:49 +00:00
}
2022-03-17 21:42:43 +00:00
2024-02-23 23:53:49 +00:00
/// <summary>
/// Binds a buffer to be used in the compute shader.
/// </summary>
/// <param name="buffer">A buffer to bind.</param>
public unsafe void BindComputeBuffers (
GpuBuffer buffer
) {
#if DEBUG
AssertNotSubmitted ( ) ;
AssertInComputePass ( "Cannot bind compute buffers outside of compute pass!" ) ;
AssertComputePipelineBound ( ) ;
AssertComputeBufferCount ( 1 ) ;
# endif
2022-02-23 05:14:32 +00:00
2024-02-23 23:53:49 +00:00
var bufferPtrs = stackalloc IntPtr [ 1 ] ;
bufferPtrs [ 0 ] = buffer . Handle ;
Refresh . Refresh_BindComputeBuffers (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
( IntPtr ) bufferPtrs
2022-11-17 20:35:21 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds buffers to be used in the compute shader.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="bufferOne">A buffer to bind.</param>
/// <param name="bufferTwo">A buffer to bind.</param>
public unsafe void BindComputeBuffers (
GpuBuffer bufferOne ,
GpuBuffer bufferTwo
2022-11-17 20:35:21 +00:00
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertInComputePass ( "Cannot bind compute buffers outside of compute pass!" ) ;
AssertComputePipelineBound ( ) ;
AssertComputeBufferCount ( 2 ) ;
2022-11-17 20:35:21 +00:00
# endif
2024-02-23 23:53:49 +00:00
var bufferPtrs = stackalloc IntPtr [ 2 ] ;
bufferPtrs [ 0 ] = bufferOne . Handle ;
bufferPtrs [ 1 ] = bufferTwo . Handle ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindComputeBuffers (
Device . Handle ,
Handle ,
( IntPtr ) bufferPtrs
) ;
}
/// <summary>
/// Binds buffers to be used in the compute shader.
/// </summary>
/// <param name="bufferOne">A buffer to bind.</param>
/// <param name="bufferTwo">A buffer to bind.</param>
/// <param name="bufferThree">A buffer to bind.</param>
public unsafe void BindComputeBuffers (
GpuBuffer bufferOne ,
GpuBuffer bufferTwo ,
GpuBuffer bufferThree
) {
#if DEBUG
AssertNotSubmitted ( ) ;
AssertInComputePass ( "Cannot bind compute buffers outside of compute pass!" ) ;
AssertComputePipelineBound ( ) ;
AssertComputeBufferCount ( 3 ) ;
# endif
var bufferPtrs = stackalloc IntPtr [ 3 ] ;
bufferPtrs [ 0 ] = bufferOne . Handle ;
bufferPtrs [ 1 ] = bufferTwo . Handle ;
bufferPtrs [ 2 ] = bufferThree . Handle ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindComputeBuffers (
2022-02-23 05:14:32 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
( IntPtr ) bufferPtrs
2022-02-23 05:14:32 +00:00
) ;
}
2022-11-16 01:53:30 +00:00
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds buffers to be used in the compute shader.
2022-11-16 01:53:30 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="bufferOne">A buffer to bind.</param>
/// <param name="bufferTwo">A buffer to bind.</param>
/// <param name="bufferThree">A buffer to bind.</param>
/// <param name="bufferFour">A buffer to bind.</param>
public unsafe void BindComputeBuffers (
GpuBuffer bufferOne ,
GpuBuffer bufferTwo ,
GpuBuffer bufferThree ,
GpuBuffer bufferFour
2022-11-17 20:35:21 +00:00
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertInComputePass ( "Cannot bind compute buffers outside of compute pass!" ) ;
AssertComputePipelineBound ( ) ;
AssertComputeBufferCount ( 4 ) ;
2022-11-17 20:35:21 +00:00
# endif
2024-02-23 23:53:49 +00:00
var bufferPtrs = stackalloc IntPtr [ 4 ] ;
bufferPtrs [ 0 ] = bufferOne . Handle ;
bufferPtrs [ 1 ] = bufferTwo . Handle ;
bufferPtrs [ 2 ] = bufferThree . Handle ;
bufferPtrs [ 3 ] = bufferFour . Handle ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindComputeBuffers (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
( IntPtr ) bufferPtrs
2022-11-17 20:35:21 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds buffers to be used in the compute shader.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="buffers">A Span of buffers to bind.</param>
public unsafe void BindComputeBuffers (
in Span < GpuBuffer > buffers
2022-11-17 20:35:21 +00:00
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertInComputePass ( "Cannot bind compute buffers outside of compute pass!" ) ;
AssertComputePipelineBound ( ) ;
AssertComputeBufferCount ( buffers . Length ) ;
2022-11-17 20:35:21 +00:00
# endif
2024-02-23 23:53:49 +00:00
var bufferPtrs = stackalloc IntPtr [ buffers . Length ] ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
for ( var i = 0 ; i < buffers . Length ; i + = 1 )
{
bufferPtrs [ i ] = buffers [ i ] . Handle ;
}
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindComputeBuffers (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
( IntPtr ) bufferPtrs
2022-11-17 20:35:21 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds a texture to be used in the compute shader.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="binding">A texture-level pair to bind.</param>
public unsafe void BindComputeTextures (
TextureLevelBinding binding
2022-11-17 20:35:21 +00:00
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertInComputePass ( "Cannot bind compute textures outside of compute pass!" ) ;
AssertComputePipelineBound ( ) ;
AssertComputeTextureCount ( 1 ) ;
2022-11-17 20:35:21 +00:00
# endif
2024-02-23 23:53:49 +00:00
var texturePtrs = stackalloc IntPtr [ 1 ] ;
texturePtrs [ 0 ] = binding . Texture . Handle ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
var mipLevels = stackalloc uint [ 1 ] ;
mipLevels [ 0 ] = binding . MipLevel ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindComputeTextures (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs ,
2024-02-23 23:53:49 +00:00
( IntPtr ) mipLevels
2022-11-17 20:35:21 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds textures to be used in the compute shader.
2022-11-17 20:35:21 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="bindingOne">A texture-level pair to bind.</param>
/// <param name="bindingTwo">A texture-level pair to bind.</param>
public unsafe void BindComputeTextures (
TextureLevelBinding bindingOne ,
TextureLevelBinding bindingTwo
2022-11-17 20:35:21 +00:00
) {
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertInComputePass ( "Cannot bind compute textures outside of compute pass!" ) ;
AssertComputePipelineBound ( ) ;
AssertComputeTextureCount ( 2 ) ;
2022-11-17 20:35:21 +00:00
# endif
2024-02-23 23:53:49 +00:00
var texturePtrs = stackalloc IntPtr [ 2 ] ;
texturePtrs [ 0 ] = bindingOne . Texture . Handle ;
texturePtrs [ 1 ] = bindingTwo . Texture . Handle ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
var mipLevels = stackalloc uint [ 2 ] ;
mipLevels [ 0 ] = bindingOne . MipLevel ;
mipLevels [ 1 ] = bindingTwo . MipLevel ;
2022-11-17 20:35:21 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindComputeTextures (
2022-11-17 20:35:21 +00:00
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs ,
2024-02-23 23:53:49 +00:00
( IntPtr ) mipLevels
2022-11-17 20:35:21 +00:00
) ;
2022-11-16 01:53:30 +00:00
}
2022-02-23 05:14:32 +00:00
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds textures to be used in the compute shader.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="bindingOne">A texture-level pair to bind.</param>
/// <param name="bindingTwo">A texture-level pair to bind.</param>
/// <param name="bindingThree">A texture-level pair to bind.</param>
public unsafe void BindComputeTextures (
TextureLevelBinding bindingOne ,
TextureLevelBinding bindingTwo ,
TextureLevelBinding bindingThree
2023-02-24 00:59:34 +00:00
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertInComputePass ( "Cannot bind compute textures outside of compute pass!" ) ;
AssertComputePipelineBound ( ) ;
AssertComputeTextureCount ( 3 ) ;
# endif
2022-09-07 20:07:17 +00:00
2024-02-23 23:53:49 +00:00
var texturePtrs = stackalloc IntPtr [ 3 ] ;
texturePtrs [ 0 ] = bindingOne . Texture . Handle ;
texturePtrs [ 1 ] = bindingTwo . Texture . Handle ;
texturePtrs [ 2 ] = bindingThree . Texture . Handle ;
2024-02-23 08:06:04 +00:00
2024-02-23 23:53:49 +00:00
var mipLevels = stackalloc uint [ 3 ] ;
mipLevels [ 0 ] = bindingOne . MipLevel ;
mipLevels [ 1 ] = bindingTwo . MipLevel ;
mipLevels [ 2 ] = bindingThree . MipLevel ;
2022-11-08 19:29:05 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindComputeTextures (
2023-02-24 00:59:34 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
( IntPtr ) texturePtrs ,
( IntPtr ) mipLevels
2023-02-24 00:59:34 +00:00
) ;
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds textures to be used in the compute shader.
2023-02-24 00:59:34 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="bindingOne">A texture-level pair to bind.</param>
/// <param name="bindingTwo">A texture-level pair to bind.</param>
/// <param name="bindingThree">A texture-level pair to bind.</param>
/// <param name="bindingFour">A texture-level pair to bind.</param>
public unsafe void BindComputeTextures (
TextureLevelBinding bindingOne ,
TextureLevelBinding bindingTwo ,
TextureLevelBinding bindingThree ,
TextureLevelBinding bindingFour
) {
#if DEBUG
AssertNotSubmitted ( ) ;
AssertInComputePass ( "Cannot bind compute textures outside of compute pass!" ) ;
AssertComputePipelineBound ( ) ;
AssertComputeTextureCount ( 4 ) ;
# endif
var texturePtrs = stackalloc IntPtr [ 4 ] ;
texturePtrs [ 0 ] = bindingOne . Texture . Handle ;
texturePtrs [ 1 ] = bindingTwo . Texture . Handle ;
texturePtrs [ 2 ] = bindingThree . Texture . Handle ;
texturePtrs [ 3 ] = bindingFour . Texture . Handle ;
var mipLevels = stackalloc uint [ 4 ] ;
mipLevels [ 0 ] = bindingOne . MipLevel ;
mipLevels [ 1 ] = bindingTwo . MipLevel ;
mipLevels [ 2 ] = bindingThree . MipLevel ;
mipLevels [ 3 ] = bindingFour . MipLevel ;
Refresh . Refresh_BindComputeTextures (
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs ,
( IntPtr ) mipLevels
) ;
2022-02-23 05:14:32 +00:00
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Binds textures to be used in the compute shader.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="bindings">A set of texture-level pairs to bind.</param>
public unsafe void BindComputeTextures (
in Span < TextureLevelBinding > bindings
2023-02-24 00:59:34 +00:00
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertInComputePass ( "Cannot bind compute textures outside of compute pass!" ) ;
AssertComputePipelineBound ( ) ;
AssertComputeTextureCount ( bindings . Length ) ;
# endif
2022-09-07 20:07:17 +00:00
2024-02-23 23:53:49 +00:00
var texturePtrs = stackalloc IntPtr [ bindings . Length ] ;
var mipLevels = stackalloc uint [ bindings . Length ] ;
2024-02-23 08:06:04 +00:00
2024-02-23 23:53:49 +00:00
for ( var i = 0 ; i < bindings . Length ; i + = 1 )
2024-02-23 08:06:04 +00:00
{
2024-02-23 23:53:49 +00:00
texturePtrs [ i ] = bindings [ i ] . Texture . Handle ;
mipLevels [ i ] = bindings [ i ] . MipLevel ;
2024-02-23 08:06:04 +00:00
}
2023-02-24 00:59:34 +00:00
2024-02-23 23:53:49 +00:00
Refresh . Refresh_BindComputeTextures (
2023-02-24 00:59:34 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
( IntPtr ) texturePtrs ,
( IntPtr ) mipLevels
2023-02-24 00:59:34 +00:00
) ;
}
2022-02-23 05:14:32 +00:00
/// <summary>
/// Pushes compute shader uniforms to the device.
/// </summary>
/// <returns>A starting offset to be used with dispatch calls.</returns>
2024-02-23 08:06:04 +00:00
public unsafe void PushComputeShaderUniforms (
2023-02-24 00:59:34 +00:00
void * uniformsPtr ,
uint size
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2022-09-07 20:07:17 +00:00
AssertComputePipelineBound ( ) ;
if ( currentComputePipeline . ComputeShaderInfo . UniformBufferSize = = 0 )
{
throw new System . InvalidOperationException ( "The current compute shader does not take a uniform buffer!" ) ;
}
2024-02-23 08:06:04 +00:00
if ( currentComputePipeline . ComputeShaderInfo . UniformBufferSize ! = size )
{
throw new InvalidOperationException ( "Compute uniform data size mismatch!" ) ;
}
2022-09-07 20:07:17 +00:00
# endif
2024-02-23 08:06:04 +00:00
Refresh . Refresh_PushComputeShaderUniforms (
2023-02-24 00:59:34 +00:00
Device . Handle ,
Handle ,
( IntPtr ) uniformsPtr ,
size
) ;
}
/// <summary>
/// Pushes compute shader uniforms to the device.
/// </summary>
/// <returns>A starting offset to be used with dispatch calls.</returns>
2024-02-23 08:06:04 +00:00
public unsafe void PushComputeShaderUniforms < T > (
2023-02-24 00:59:34 +00:00
in T uniforms
) where T : unmanaged
{
2022-11-17 20:35:21 +00:00
fixed ( T * uniformsPtr = & uniforms )
2022-02-23 05:14:32 +00:00
{
2024-02-23 08:06:04 +00:00
PushComputeShaderUniforms ( uniformsPtr , ( uint ) Marshal . SizeOf < T > ( ) ) ;
2022-02-23 05:14:32 +00:00
}
}
/// <summary>
2024-02-23 23:53:49 +00:00
/// Dispatches compute work.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 23:53:49 +00:00
/// <param name="groupCountX"></param>
/// <param name="groupCountY"></param>
/// <param name="groupCountZ"></param>
/// <param name="computeParamOffset"></param>
public void DispatchCompute (
uint groupCountX ,
uint groupCountY ,
uint groupCountZ
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 23:53:49 +00:00
AssertInComputePass ( "Cannot dispatch compute outside of compute pass!" ) ;
AssertComputePipelineBound ( ) ;
2022-02-23 05:14:32 +00:00
2024-02-23 23:53:49 +00:00
if ( groupCountX < 1 | | groupCountY < 1 | | groupCountZ < 1 )
{
throw new ArgumentException ( "All dimensions for the compute work group must be >= 1!" ) ;
}
2022-09-07 20:07:17 +00:00
# endif
2024-02-23 23:53:49 +00:00
Refresh . Refresh_DispatchCompute (
2022-08-25 19:32:49 +00:00
Device . Handle ,
Handle ,
2024-02-23 23:53:49 +00:00
groupCountX ,
groupCountY ,
groupCountZ
2022-08-25 19:32:49 +00:00
) ;
}
2024-02-23 23:53:49 +00:00
public void EndComputePass ( )
2022-02-23 05:14:32 +00:00
{
2024-01-18 20:27:34 +00:00
#if DEBUG
2024-02-23 23:53:49 +00:00
AssertInComputePass ( "Cannot end compute pass while not in a compute pass!" ) ;
computePassActive = false ;
2024-01-18 20:27:34 +00:00
# endif
2024-02-23 23:53:49 +00:00
Refresh . Refresh_EndComputePass (
2022-02-23 05:14:32 +00:00
Device . Handle ,
Handle
) ;
}
2024-02-23 08:06:04 +00:00
// Copy Pass
2022-02-23 06:16:06 +00:00
2023-04-05 19:40:34 +00:00
/// <summary>
2024-02-23 08:06:04 +00:00
/// 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.
2023-04-05 19:40:34 +00:00
/// </summary>
2024-02-23 08:06:04 +00:00
public void BeginCopyPass ( )
2023-04-05 19:40:34 +00:00
{
2024-02-23 08:06:04 +00:00
#if DEBUG
AssertNotSubmitted ( ) ;
AssertNotInPass ( "Cannot begin copy pass while in another pass!" ) ;
copyPassActive = true ;
# endif
Refresh . Refresh_BeginCopyPass (
Device . Handle ,
Handle
2023-04-05 19:40:34 +00:00
) ;
}
2022-02-23 05:14:32 +00:00
/// <summary>
2024-02-23 23:40:01 +00:00
/// Uploads data from a TransferBuffer to a TextureSlice.
2024-02-23 08:06:04 +00:00
/// This copy occurs on the GPU timeline.
///
2024-02-23 23:40:01 +00:00
/// Overwriting the contents of the TransferBuffer before the command buffer
2024-02-23 08:06:04 +00:00
/// has finished execution will cause undefined behavior.
///
/// You MAY assume that the copy has finished for subsequent commands.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 08:06:04 +00:00
public void UploadToTexture (
2024-02-23 18:43:39 +00:00
TransferBuffer transferBuffer ,
2024-02-23 08:06:04 +00:00
in TextureSlice textureSlice ,
in BufferImageCopy copyParams
2022-02-23 05:14:32 +00:00
)
{
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 08:06:04 +00:00
AssertInCopyPass ( "Cannot upload to texture outside of copy pass!" ) ;
2024-02-23 18:43:39 +00:00
AssertBufferBoundsCheck ( transferBuffer . Size , copyParams . BufferOffset , textureSlice . Size ) ;
2022-09-07 20:07:17 +00:00
# endif
2024-02-23 08:06:04 +00:00
Refresh . Refresh_UploadToTexture (
2022-02-23 05:14:32 +00:00
Device . Handle ,
Handle ,
2024-02-23 18:43:39 +00:00
transferBuffer . Handle ,
2024-02-23 08:06:04 +00:00
textureSlice . ToRefreshTextureSlice ( ) ,
copyParams . ToRefresh ( )
2022-02-23 05:14:32 +00:00
) ;
}
/// <summary>
2024-02-23 08:06:04 +00:00
/// Uploads the contents of an entire buffer to a texture with no mips.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 08:06:04 +00:00
public void UploadToTexture (
2024-02-23 18:43:39 +00:00
TransferBuffer transferBuffer ,
2024-02-23 08:06:04 +00:00
Texture texture
) {
UploadToTexture (
2024-02-23 18:43:39 +00:00
transferBuffer ,
2024-02-23 08:06:04 +00:00
new TextureSlice ( texture ) ,
new BufferImageCopy ( 0 , 0 , 0 )
) ;
}
2023-08-07 17:12:46 +00:00
2024-02-23 08:06:04 +00:00
/// <summary>
2024-02-23 23:40:01 +00:00
/// Uploads data from a TransferBuffer to a GpuBuffer.
2024-02-23 08:06:04 +00:00
/// This copy occurs on the GPU timeline.
///
2024-02-23 23:40:01 +00:00
/// Overwriting the contents of the TransferBuffer before the command buffer
2024-02-23 08:06:04 +00:00
/// has finished execution will cause undefined behavior.
///
/// You MAY assume that the copy has finished for subsequent commands.
/// </summary>
public void UploadToBuffer (
2024-02-23 18:43:39 +00:00
TransferBuffer transferBuffer ,
2024-02-23 08:06:04 +00:00
GpuBuffer gpuBuffer ,
in BufferCopy copyParams
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 08:06:04 +00:00
AssertInCopyPass ( "Cannot upload to texture outside of copy pass!" ) ;
2024-02-23 18:43:39 +00:00
AssertBufferBoundsCheck ( transferBuffer . Size , copyParams . SrcOffset , copyParams . Size ) ;
AssertBufferBoundsCheck ( gpuBuffer . Size , copyParams . DstOffset , copyParams . Size ) ;
2022-09-07 20:07:17 +00:00
# endif
2024-02-23 08:06:04 +00:00
Refresh . Refresh_UploadToBuffer (
Device . Handle ,
Handle ,
2024-02-23 18:43:39 +00:00
transferBuffer . Handle ,
2024-02-23 08:06:04 +00:00
gpuBuffer . Handle ,
copyParams . ToRefresh ( )
) ;
2022-02-23 05:14:32 +00:00
}
2023-04-05 19:40:34 +00:00
/// <summary>
2024-02-23 23:40:01 +00:00
/// Copies the entire contents of a TransferBuffer to a GpuBuffer.
2023-04-05 19:40:34 +00:00
/// </summary>
2024-02-23 08:06:04 +00:00
public void UploadToBuffer (
2024-02-23 18:43:39 +00:00
TransferBuffer transferBuffer ,
2024-02-23 08:06:04 +00:00
GpuBuffer gpuBuffer
) {
UploadToBuffer (
2024-02-23 18:43:39 +00:00
transferBuffer ,
2024-02-23 08:06:04 +00:00
gpuBuffer ,
2024-02-23 18:43:39 +00:00
new BufferCopy ( 0 , 0 , transferBuffer . Size )
2024-02-23 08:06:04 +00:00
) ;
2023-04-05 19:40:34 +00:00
}
2024-02-23 08:06:04 +00:00
/// <summary>
2024-02-23 23:40:01 +00:00
/// 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
) 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
)
) ;
}
/// <summary>
/// Downloads data from a Texture to a TransferBuffer.
2024-02-23 08:06:04 +00:00
/// This copy occurs on the GPU timeline.
///
2024-02-23 23:40:01 +00:00
/// You MAY NOT assume that the data in the TransferBuffer is
2024-02-23 08:06:04 +00:00
/// fully copied until the command buffer has finished execution.
/// </summary>
public void DownloadFromTexture (
in TextureSlice textureSlice ,
2024-02-23 18:43:39 +00:00
TransferBuffer transferBuffer ,
2024-02-23 08:06:04 +00:00
in BufferImageCopy copyParams
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 08:06:04 +00:00
AssertInCopyPass ( "Cannot download from texture outside of copy pass!" ) ;
2024-02-23 18:43:39 +00:00
AssertBufferBoundsCheck ( transferBuffer . Size , copyParams . BufferOffset , textureSlice . Size ) ;
2022-09-07 20:07:17 +00:00
# endif
2024-02-23 08:06:04 +00:00
Refresh . Refresh_DownloadFromTexture (
2022-03-04 18:00:29 +00:00
Device . Handle ,
Handle ,
2024-02-23 08:06:04 +00:00
textureSlice . ToRefreshTextureSlice ( ) ,
2024-02-23 18:43:39 +00:00
transferBuffer . Handle ,
2024-02-23 08:06:04 +00:00
copyParams . ToRefresh ( )
2022-03-04 18:00:29 +00:00
) ;
}
2022-02-23 05:14:32 +00:00
/// <summary>
2024-02-23 23:40:01 +00:00
/// Downloads the contents of a Texture with no mips into a TransferBuffer.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 08:06:04 +00:00
public void DownloadFromTexture (
Texture texture ,
2024-02-23 18:43:39 +00:00
TransferBuffer transferBuffer
2024-02-23 08:06:04 +00:00
) {
DownloadFromTexture (
new TextureSlice ( texture ) ,
2024-02-23 18:43:39 +00:00
transferBuffer ,
2024-02-23 08:06:04 +00:00
new BufferImageCopy ( 0 , 0 , 0 )
) ;
2022-02-23 05:14:32 +00:00
}
2023-04-05 19:40:34 +00:00
/// <summary>
2024-02-23 23:40:01 +00:00
/// Downloads data from a GpuBuffer to a TransferBuffer.
2024-02-23 08:06:04 +00:00
/// This copy occurs on the GPU timeline.
///
2024-02-23 23:40:01 +00:00
/// You MAY NOT assume that the data in the TransferBuffer is
2024-02-23 08:06:04 +00:00
/// fully copied until the command buffer has finished execution.
2023-04-05 19:40:34 +00:00
/// </summary>
2024-02-23 08:06:04 +00:00
public void DownloadFromBuffer (
GpuBuffer gpuBuffer ,
2024-02-23 18:43:39 +00:00
TransferBuffer transferBuffer ,
2024-02-23 08:06:04 +00:00
in BufferCopy copyParams
) {
#if DEBUG
AssertNotSubmitted ( ) ;
AssertInCopyPass ( "Cannot download from texture outside of copy pass!" ) ;
2024-02-23 18:43:39 +00:00
AssertBufferBoundsCheck ( transferBuffer . Size , copyParams . DstOffset , copyParams . Size ) ;
2024-02-23 08:06:04 +00:00
# endif
Refresh . Refresh_DownloadFromBuffer (
Device . Handle ,
Handle ,
gpuBuffer . Handle ,
2024-02-23 18:43:39 +00:00
transferBuffer . Handle ,
2024-02-23 08:06:04 +00:00
copyParams . ToRefresh ( )
) ;
2023-04-05 19:40:34 +00:00
}
2024-02-23 18:43:39 +00:00
/// <summary>
2024-02-23 23:40:01 +00:00
/// Downloads data from a GpuBuffer to a TransferBuffer.
2024-02-23 18:43:39 +00:00
/// This copy occurs on the GPU timeline.
///
2024-02-23 23:40:01 +00:00
/// You MAY NOT assume that the data in the TransferBuffer is
2024-02-23 18:43:39 +00:00
/// fully copied until the command buffer has finished execution.
/// </summary>
public void DownloadFromBuffer (
GpuBuffer gpuBuffer ,
TransferBuffer transferBuffer
) {
DownloadFromBuffer (
gpuBuffer ,
transferBuffer ,
new BufferCopy ( 0 , 0 , gpuBuffer . Size )
) ;
}
2022-02-23 05:14:32 +00:00
/// <summary>
2024-02-23 08:06:04 +00:00
/// 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.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 08:06:04 +00:00
public void CopyTextureToTexture (
in TextureSlice source ,
in TextureSlice destination
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 08:06:04 +00:00
AssertInCopyPass ( "Cannot download from texture outside of copy pass!" ) ;
2024-02-23 18:43:39 +00:00
AssertTextureBoundsCheck ( destination . Size , source . Size ) ;
2022-09-07 20:07:17 +00:00
# endif
2024-02-23 08:06:04 +00:00
Refresh . Refresh_CopyTextureToTexture (
Device . Handle ,
Handle ,
source . ToRefreshTextureSlice ( ) ,
destination . ToRefreshTextureSlice ( )
) ;
2022-02-23 05:14:32 +00:00
}
2023-04-05 19:40:34 +00:00
/// <summary>
2024-02-23 08:06:04 +00:00
/// Copies the contents of an entire Texture with no mips to another Texture with no mips.
/// The textures must have the same dimensions.
2023-04-05 19:40:34 +00:00
/// </summary>
2024-02-23 08:06:04 +00:00
public void CopyTextureToTexture (
Texture source ,
Texture destination
) {
CopyTextureToTexture (
new TextureSlice ( source ) ,
new TextureSlice ( destination )
) ;
2023-04-05 19:40:34 +00:00
}
2022-02-23 06:16:06 +00:00
/// <summary>
2024-02-23 08:06:04 +00:00
/// Copies the contents of a Texture to a GpuBuffer.
/// This copy occurs on the GPU timeline.
///
/// You MAY assume that the copy has finished in subsequent commands.
2022-02-23 06:16:06 +00:00
/// </summary>
2024-02-23 08:06:04 +00:00
public void CopyTextureToBuffer (
in TextureSlice textureSlice ,
GpuBuffer buffer ,
in BufferImageCopy copyParams
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 08:06:04 +00:00
AssertInCopyPass ( "Cannot download from texture outside of copy pass!" ) ;
2024-02-23 18:43:39 +00:00
AssertBufferBoundsCheck ( buffer . Size , copyParams . BufferOffset , textureSlice . Size ) ;
2022-09-07 20:07:17 +00:00
# endif
2024-02-23 08:06:04 +00:00
Refresh . Refresh_CopyTextureToBuffer (
2022-02-23 06:16:06 +00:00
Device . Handle ,
Handle ,
textureSlice . ToRefreshTextureSlice ( ) ,
2024-02-23 08:06:04 +00:00
buffer . Handle ,
copyParams . ToRefresh ( )
2022-02-23 06:16:06 +00:00
) ;
}
2022-02-23 05:14:32 +00:00
/// <summary>
2024-02-23 08:06:04 +00:00
/// Copies the entire contents of a Texture to a GpuBuffer.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 08:06:04 +00:00
public void CopyTextureToBuffer (
Texture texture ,
GpuBuffer buffer
) {
CopyTextureToBuffer (
new TextureSlice ( texture ) ,
buffer ,
new BufferImageCopy ( 0 , 0 , 0 )
) ;
2022-02-23 05:14:32 +00:00
}
2022-08-02 21:04:12 +00:00
/// <summary>
2024-02-23 08:06:04 +00:00
/// Copies the contents of a GpuBuffer to a Texture.
/// This copy occurs on the GPU timeline.
///
/// You MAY assume that the copy has finished in subsequent commands.
2022-08-02 21:04:12 +00:00
/// </summary>
2024-02-23 08:06:04 +00:00
public void CopyBufferToTexture (
2024-02-23 18:43:39 +00:00
GpuBuffer gpuBuffer ,
2024-02-23 08:06:04 +00:00
in TextureSlice textureSlice ,
in BufferImageCopy copyParams
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 08:06:04 +00:00
AssertInCopyPass ( "Cannot download from texture outside of copy pass!" ) ;
2024-02-23 18:43:39 +00:00
AssertBufferBoundsCheck ( gpuBuffer . Size , copyParams . BufferOffset , textureSlice . Size ) ;
2022-09-07 20:07:17 +00:00
# endif
2024-02-23 08:06:04 +00:00
Refresh . Refresh_CopyBufferToTexture (
2022-08-02 21:04:12 +00:00
Device . Handle ,
Handle ,
2024-02-23 18:43:39 +00:00
gpuBuffer . Handle ,
2024-02-23 08:06:04 +00:00
textureSlice . ToRefreshTextureSlice ( ) ,
copyParams . ToRefresh ( )
2022-08-02 21:04:12 +00:00
) ;
}
2022-02-23 05:14:32 +00:00
/// <summary>
2024-02-23 08:06:04 +00:00
/// Copies the entire contents of a Texture with no mips to a GpuBuffer.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 08:06:04 +00:00
public void CopyBufferToTexture (
GpuBuffer buffer ,
Texture texture
) {
CopyBufferToTexture (
buffer ,
new TextureSlice ( texture ) ,
new BufferImageCopy ( 0 , 0 , 0 )
) ;
}
/// <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
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 08:06:04 +00:00
AssertInCopyPass ( "Cannot download from texture outside of copy pass!" ) ;
2024-02-23 18:43:39 +00:00
AssertBufferBoundsCheck ( source . Size , copyParams . SrcOffset , copyParams . Size ) ;
AssertBufferBoundsCheck ( destination . Size , copyParams . DstOffset , copyParams . Size ) ;
2022-09-07 20:07:17 +00:00
# endif
2024-02-23 08:06:04 +00:00
Refresh . Refresh_CopyBufferToBuffer (
2022-02-23 05:14:32 +00:00
Device . Handle ,
Handle ,
2024-02-23 08:06:04 +00:00
source . Handle ,
destination . Handle ,
copyParams . ToRefresh ( )
2022-02-23 05:14:32 +00:00
) ;
}
/// <summary>
2024-02-23 08:06:04 +00:00
/// Copies the entire contents of a GpuBuffer to another GpuBuffer.
2022-02-23 05:14:32 +00:00
/// </summary>
2024-02-23 08:06:04 +00:00
public void CopyBufferToBuffer (
GpuBuffer source ,
GpuBuffer destination
) {
CopyBufferToBuffer (
source ,
destination ,
new BufferCopy ( 0 , 0 , source . Size )
) ;
}
public void EndCopyPass ( )
2022-02-23 05:14:32 +00:00
{
2022-09-07 20:07:17 +00:00
#if DEBUG
2024-01-18 20:27:34 +00:00
AssertNotSubmitted ( ) ;
2024-02-23 08:06:04 +00:00
AssertInCopyPass ( "Cannot end copy pass while not in a copy pass!" ) ;
copyPassActive = false ;
2022-09-07 20:07:17 +00:00
# endif
2024-02-23 08:06:04 +00:00
Refresh . Refresh_EndCopyPass (
2022-02-23 05:14:32 +00:00
Device . Handle ,
2024-02-23 08:06:04 +00:00
Handle
2022-02-23 05:14:32 +00:00
) ;
}
2022-09-07 20:07:17 +00:00
#if DEBUG
private void AssertRenderPassActive ( string message = "No active render pass!" )
{
if ( ! renderPassActive )
{
throw new System . InvalidOperationException ( message ) ;
}
}
private void AssertRenderPassInactive ( string message = "Render pass is active!" )
{
if ( renderPassActive )
{
throw new System . InvalidCastException ( message ) ;
}
}
private void AssertGraphicsPipelineBound ( string message = "No graphics pipeline is bound!" )
{
if ( currentGraphicsPipeline = = null )
{
throw new System . InvalidOperationException ( message ) ;
}
}
2022-11-17 20:35:21 +00:00
private void AssertRenderPassPipelineFormatMatch ( GraphicsPipeline graphicsPipeline )
{
for ( var i = 0 ; i < graphicsPipeline . AttachmentInfo . ColorAttachmentDescriptions . Length ; i + = 1 )
{
TextureFormat format ;
if ( i = = 0 )
{
format = colorFormatOne ;
}
else if ( i = = 1 )
{
format = colorFormatTwo ;
}
else if ( i = = 2 )
{
format = colorFormatThree ;
}
else
{
format = colorFormatFour ;
}
var pipelineFormat = graphicsPipeline . AttachmentInfo . ColorAttachmentDescriptions [ i ] . Format ;
if ( pipelineFormat ! = format )
{
throw new System . InvalidOperationException ( $"Color texture format mismatch! Pipeline expects {pipelineFormat}, render pass attachment is {format}" ) ;
}
}
2022-11-29 21:06:03 +00:00
if ( graphicsPipeline . AttachmentInfo . HasDepthStencilAttachment )
2022-11-17 20:35:21 +00:00
{
2022-11-29 21:06:03 +00:00
var pipelineDepthFormat = graphicsPipeline . AttachmentInfo . DepthStencilFormat ;
2024-01-16 07:11:28 +00:00
if ( ! hasDepthStencilAttachment )
{
throw new System . InvalidOperationException ( "Pipeline expects depth attachment!" ) ;
}
2022-11-29 21:06:03 +00:00
if ( pipelineDepthFormat ! = depthStencilFormat )
{
throw new System . InvalidOperationException ( $"Depth texture format mismatch! Pipeline expects {pipelineDepthFormat}, render pass attachment is {depthStencilFormat}" ) ;
}
2022-11-17 20:35:21 +00:00
}
}
private void AssertVertexSamplerCount ( int count )
{
if ( currentGraphicsPipeline . VertexShaderInfo . SamplerBindingCount ! = count )
{
throw new System . InvalidOperationException ( $"Vertex sampler expected {currentGraphicsPipeline.VertexShaderInfo.SamplerBindingCount} samplers, but received {count}" ) ;
}
}
private void AssertFragmentSamplerCount ( int count )
{
if ( currentGraphicsPipeline . FragmentShaderInfo . SamplerBindingCount ! = count )
{
throw new System . InvalidOperationException ( $"Fragment sampler expected {currentGraphicsPipeline.FragmentShaderInfo.SamplerBindingCount} samplers, but received {count}" ) ;
}
}
2022-09-07 20:07:17 +00:00
private void AssertComputePipelineBound ( string message = "No compute pipeline is bound!" )
{
if ( currentComputePipeline = = null )
{
throw new System . InvalidOperationException ( message ) ;
}
}
2022-11-08 19:29:05 +00:00
2022-11-17 20:35:21 +00:00
private void AssertComputeBufferCount ( int count )
2022-11-08 19:29:05 +00:00
{
2022-11-17 20:35:21 +00:00
if ( currentComputePipeline . ComputeShaderInfo . BufferBindingCount ! = count )
2022-11-08 19:29:05 +00:00
{
2022-11-17 20:35:21 +00:00
throw new System . InvalidOperationException ( $"Compute pipeline expects {currentComputePipeline.ComputeShaderInfo.BufferBindingCount} buffers, but received {count}" ) ;
2022-11-08 19:29:05 +00:00
}
2022-11-17 20:35:21 +00:00
}
2022-11-08 19:29:05 +00:00
2022-11-17 20:35:21 +00:00
private void AssertComputeTextureCount ( int count )
{
if ( currentComputePipeline . ComputeShaderInfo . ImageBindingCount ! = count )
2022-11-08 19:29:05 +00:00
{
2022-11-17 20:35:21 +00:00
throw new System . InvalidOperationException ( $"Compute pipeline expects {currentComputePipeline.ComputeShaderInfo.ImageBindingCount} textures, but received {count}" ) ;
2022-11-08 19:29:05 +00:00
}
2022-11-17 20:35:21 +00:00
}
2022-11-08 19:29:05 +00:00
2022-11-17 20:35:21 +00:00
private void AssertTextureNotNull ( ColorAttachmentInfo colorAttachmentInfo )
{
if ( colorAttachmentInfo . Texture = = null | | colorAttachmentInfo . Texture . Handle = = IntPtr . Zero )
2022-11-08 19:29:05 +00:00
{
2022-11-17 20:35:21 +00:00
throw new System . ArgumentException ( "Render pass color attachment Texture cannot be null!" ) ;
}
}
2022-11-08 19:29:05 +00:00
2022-11-17 20:35:21 +00:00
private void AssertColorTarget ( ColorAttachmentInfo colorAttachmentInfo )
{
if ( ( colorAttachmentInfo . Texture . UsageFlags & TextureUsageFlags . ColorTarget ) = = 0 )
{
throw new System . ArgumentException ( "Render pass color attachment UsageFlags must include TextureUsageFlags.ColorTarget!" ) ;
}
}
2022-11-09 18:49:53 +00:00
2024-01-16 07:11:28 +00:00
private void AssertSameSampleCount ( Texture a , Texture b )
2022-11-17 20:35:21 +00:00
{
2024-01-16 07:11:28 +00:00
if ( a . SampleCount ! = b . SampleCount )
2022-11-17 20:35:21 +00:00
{
2024-01-16 07:11:28 +00:00
throw new System . ArgumentException ( "All attachments in a render pass must have the same SampleCount!" ) ;
2022-11-08 19:29:05 +00:00
}
}
2022-11-09 18:49:53 +00:00
private void AssertValidDepthAttachment ( DepthStencilAttachmentInfo depthStencilAttachmentInfo )
2022-11-08 19:29:05 +00:00
{
if ( depthStencilAttachmentInfo . Texture = = null | |
depthStencilAttachmentInfo . Texture . Handle = = IntPtr . Zero )
{
throw new System . ArgumentException ( "Render pass depth stencil attachment Texture cannot be null!" ) ;
}
if ( ( depthStencilAttachmentInfo . Texture . UsageFlags & TextureUsageFlags . DepthStencilTarget ) = = 0 )
{
throw new System . ArgumentException ( "Render pass depth stencil attachment UsageFlags must include TextureUsageFlags.DepthStencilTarget!" ) ;
}
}
private void AssertTextureSamplerBindingNonNull ( in TextureSamplerBinding binding )
{
if ( binding . Texture = = null | | binding . Texture . Handle = = IntPtr . Zero )
{
throw new NullReferenceException ( "Texture binding must not be null!" ) ;
}
if ( binding . Sampler = = null | | binding . Sampler . Handle = = IntPtr . Zero )
{
throw new NullReferenceException ( "Sampler binding must not be null!" ) ;
}
}
private void AssertTextureBindingUsageFlags ( Texture texture )
{
if ( ( texture . UsageFlags & TextureUsageFlags . Sampler ) = = 0 )
{
throw new System . ArgumentException ( "The bound Texture's UsageFlags must include TextureUsageFlags.Sampler!" ) ;
}
}
2023-08-07 17:12:46 +00:00
private void AssertNonEmptyCopy ( uint dataLengthInBytes )
{
if ( dataLengthInBytes = = 0 )
{
throw new System . InvalidOperationException ( "SetBufferData must have a length greater than 0 bytes!" ) ;
}
}
2024-01-16 06:19:59 +00:00
private void AssertBufferBoundsCheck ( uint bufferLengthInBytes , uint offsetInBytes , uint copyLengthInBytes )
{
if ( copyLengthInBytes > bufferLengthInBytes + offsetInBytes )
{
throw new System . InvalidOperationException ( $"SetBufferData overflow! buffer length {bufferLengthInBytes}, offset {offsetInBytes}, copy length {copyLengthInBytes}" ) ;
}
}
private void AssertTextureBoundsCheck ( uint textureSizeInBytes , uint dataLengthInBytes )
{
if ( dataLengthInBytes > textureSizeInBytes )
{
throw new System . InvalidOperationException ( $"SetTextureData overflow! texture size {textureSizeInBytes}, data size {dataLengthInBytes}" ) ;
}
}
2024-01-18 20:27:34 +00:00
2024-02-23 08:06:04 +00:00
private void AssertNotInPass ( string message )
{
if ( renderPassActive | | copyPassActive | | computePassActive )
{
throw new System . InvalidOperationException ( message ) ;
}
}
private void AssertInRenderPass ( string message )
{
if ( ! renderPassActive )
{
throw new System . InvalidOperationException ( message ) ;
}
}
private void AssertInCopyPass ( string message )
{
if ( ! copyPassActive )
{
throw new System . InvalidOperationException ( message ) ;
}
}
2024-02-23 18:43:39 +00:00
private void AssertInComputePass ( string message )
{
if ( ! computePassActive )
{
throw new System . InvalidOperationException ( message ) ;
}
}
2024-01-18 20:27:34 +00:00
private void AssertNotSubmitted ( )
{
if ( Submitted )
{
throw new System . InvalidOperationException ( "Cannot add commands to a submitted command buffer!" ) ;
}
}
2022-09-07 20:07:17 +00:00
# endif
2022-02-23 05:14:32 +00:00
}
2021-01-20 03:33:27 +00:00
}