2022-02-23 05:14:32 +00:00
using System ;
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>
public struct CommandBuffer
{
public GraphicsDevice Device { get ; }
2022-09-07 20:07:17 +00:00
public IntPtr Handle { get ; }
2022-11-17 20:35:21 +00:00
#if DEBUG
2022-09-29 22:22:50 +00:00
GraphicsPipeline currentGraphicsPipeline ;
ComputePipeline currentComputePipeline ;
bool renderPassActive ;
2022-11-09 18:49:53 +00:00
SampleCount currentSampleCount ;
2022-11-17 20:35:21 +00:00
TextureFormat colorFormatOne ;
TextureFormat colorFormatTwo ;
TextureFormat colorFormatThree ;
TextureFormat colorFormatFour ;
TextureFormat depthStencilFormat ;
# endif
2022-02-23 05:14:32 +00:00
// called from RefreshDevice
internal CommandBuffer ( GraphicsDevice device , IntPtr handle )
{
Device = device ;
Handle = handle ;
2022-11-17 20:35:21 +00:00
#if DEBUG
2022-09-29 22:22:50 +00:00
currentGraphicsPipeline = null ;
currentComputePipeline = null ;
renderPassActive = false ;
2022-11-09 18:49:53 +00:00
currentSampleCount = SampleCount . One ;
2022-11-17 20:35:21 +00:00
colorFormatOne = TextureFormat . R8G8B8A8 ;
colorFormatTwo = TextureFormat . R8G8B8A8 ;
colorFormatThree = TextureFormat . R8G8B8A8 ;
colorFormatFour = TextureFormat . R8G8B8A8 ;
depthStencilFormat = TextureFormat . D16 ;
# endif
2022-02-23 05:14:32 +00:00
}
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.
/// It is an error to call this after calling BeginRenderPass but before calling EndRenderPass.
/// </summary>
/// <param name="colorAttachmentInfo">The color attachment to use in the render pass.</param>
public unsafe void BeginRenderPass (
in ColorAttachmentInfo colorAttachmentInfo
) {
#if DEBUG
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 ;
currentSampleCount = colorAttachmentInfo . SampleCount ;
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
2022-11-17 20:35:21 +00:00
AssertTextureNotNull ( colorAttachmentInfoOne ) ;
AssertColorTarget ( colorAttachmentInfoOne ) ;
AssertTextureNotNull ( colorAttachmentInfoTwo ) ;
AssertColorTarget ( colorAttachmentInfoTwo ) ;
AssertSameSampleCount ( colorAttachmentInfoOne , colorAttachmentInfoTwo ) ;
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 ;
currentSampleCount = colorAttachmentInfoOne . SampleCount ;
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
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 ) ;
AssertSameSampleCount ( colorAttachmentInfoOne , colorAttachmentInfoTwo ) ;
AssertSameSampleCount ( colorAttachmentInfoOne , colorAttachmentInfoThree ) ;
# 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 ;
2022-11-17 20:35:21 +00:00
currentSampleCount = colorAttachmentInfoOne . SampleCount ;
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
AssertTextureNotNull ( colorAttachmentInfoOne ) ;
AssertColorTarget ( colorAttachmentInfoOne ) ;
AssertTextureNotNull ( colorAttachmentInfoTwo ) ;
AssertColorTarget ( colorAttachmentInfoTwo ) ;
AssertTextureNotNull ( colorAttachmentInfoThree ) ;
AssertColorTarget ( colorAttachmentInfoThree ) ;
AssertTextureNotNull ( colorAttachmentInfoFour ) ;
AssertColorTarget ( colorAttachmentInfoFour ) ;
AssertSameSampleCount ( colorAttachmentInfoOne , colorAttachmentInfoTwo ) ;
AssertSameSampleCount ( colorAttachmentInfoOne , colorAttachmentInfoThree ) ;
AssertSameSampleCount ( colorAttachmentInfoOne , colorAttachmentInfoFour ) ;
# 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 ;
currentSampleCount = colorAttachmentInfoOne . SampleCount ;
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
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 ;
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
AssertValidDepthAttachment ( depthStencilAttachmentInfo ) ;
AssertTextureNotNull ( colorAttachmentInfo ) ;
AssertColorTarget ( colorAttachmentInfo ) ;
# 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 ;
currentSampleCount = colorAttachmentInfo . SampleCount ;
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
AssertValidDepthAttachment ( depthStencilAttachmentInfo ) ;
AssertTextureNotNull ( colorAttachmentInfoOne ) ;
AssertColorTarget ( colorAttachmentInfoOne ) ;
AssertTextureNotNull ( colorAttachmentInfoTwo ) ;
AssertColorTarget ( colorAttachmentInfoTwo ) ;
AssertSameSampleCount ( colorAttachmentInfoOne , colorAttachmentInfoTwo ) ;
# 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 ;
currentSampleCount = colorAttachmentInfoOne . SampleCount ;
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
AssertValidDepthAttachment ( depthStencilAttachmentInfo ) ;
AssertTextureNotNull ( colorAttachmentInfoOne ) ;
AssertColorTarget ( colorAttachmentInfoOne ) ;
AssertTextureNotNull ( colorAttachmentInfoTwo ) ;
AssertColorTarget ( colorAttachmentInfoTwo ) ;
AssertTextureNotNull ( colorAttachmentInfoThree ) ;
AssertColorTarget ( colorAttachmentInfoThree ) ;
AssertSameSampleCount ( colorAttachmentInfoOne , colorAttachmentInfoTwo ) ;
AssertSameSampleCount ( colorAttachmentInfoOne , colorAttachmentInfoTwo ) ;
# 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 ;
currentSampleCount = colorAttachmentInfoOne . SampleCount ;
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
AssertValidDepthAttachment ( depthStencilAttachmentInfo ) ;
AssertTextureNotNull ( colorAttachmentInfoOne ) ;
AssertColorTarget ( colorAttachmentInfoOne ) ;
AssertTextureNotNull ( colorAttachmentInfoTwo ) ;
AssertColorTarget ( colorAttachmentInfoTwo ) ;
AssertTextureNotNull ( colorAttachmentInfoThree ) ;
AssertColorTarget ( colorAttachmentInfoThree ) ;
AssertTextureNotNull ( colorAttachmentInfoFour ) ;
AssertColorTarget ( colorAttachmentInfoFour ) ;
AssertSameSampleCount ( colorAttachmentInfoOne , colorAttachmentInfoTwo ) ;
AssertSameSampleCount ( colorAttachmentInfoOne , colorAttachmentInfoThree ) ;
AssertSameSampleCount ( colorAttachmentInfoOne , colorAttachmentInfoFour ) ;
# 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 ;
2022-11-17 20:35:21 +00:00
currentSampleCount = colorAttachmentInfoOne . SampleCount ;
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>
/// Binds a compute pipeline so that compute work may be dispatched.
/// </summary>
/// <param name="computePipeline">The compute pipeline to bind.</param>
public void BindComputePipeline (
ComputePipeline computePipeline
2022-11-17 20:35:21 +00:00
) {
2022-02-23 05:14:32 +00:00
Refresh . Refresh_BindComputePipeline (
Device . Handle ,
Handle ,
computePipeline . Handle
) ;
2022-09-07 20:07:17 +00:00
2022-11-17 20:35:21 +00:00
#if DEBUG
2022-09-07 20:07:17 +00:00
currentComputePipeline = computePipeline ;
2022-11-17 20:35:21 +00:00
# endif
}
/// <summary>
/// Binds a buffer to be used in the compute shader.
/// </summary>
/// <param name="buffer">A buffer to bind.</param>
public unsafe void BindComputeBuffers (
Buffer buffer
) {
#if DEBUG
AssertComputePipelineBound ( ) ;
AssertComputeBufferCount ( 1 ) ;
# endif
var bufferPtrs = stackalloc IntPtr [ 1 ] ;
bufferPtrs [ 0 ] = buffer . Handle ;
Refresh . Refresh_BindComputeBuffers (
Device . Handle ,
Handle ,
( IntPtr ) bufferPtrs
) ;
2022-02-23 05:14:32 +00:00
}
/// <summary>
/// Binds buffers to be used in the compute shader.
/// </summary>
2022-11-17 20:35:21 +00:00
/// <param name="bufferOne">A buffer to bind.</param>
/// <param name="bufferTwo">A buffer to bind.</param>
2022-02-23 05:14:32 +00:00
public unsafe void BindComputeBuffers (
2022-11-17 20:35:21 +00:00
Buffer bufferOne ,
Buffer bufferTwo
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertComputePipelineBound ( ) ;
2022-11-17 20:35:21 +00:00
AssertComputeBufferCount ( 2 ) ;
# endif
2022-09-07 20:07:17 +00:00
2022-11-17 20:35:21 +00:00
var bufferPtrs = stackalloc IntPtr [ 2 ] ;
bufferPtrs [ 0 ] = bufferOne . Handle ;
bufferPtrs [ 1 ] = bufferTwo . Handle ;
2022-09-07 20:07:17 +00:00
2022-11-17 20:35:21 +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 (
Buffer bufferOne ,
Buffer bufferTwo ,
Buffer bufferThree
) {
#if DEBUG
AssertComputePipelineBound ( ) ;
AssertComputeBufferCount ( 3 ) ;
# endif
var bufferPtrs = stackalloc IntPtr [ 3 ] ;
bufferPtrs [ 0 ] = bufferOne . Handle ;
bufferPtrs [ 1 ] = bufferTwo . Handle ;
bufferPtrs [ 2 ] = bufferThree . Handle ;
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>
/// <param name="bufferFour">A buffer to bind.</param>
public unsafe void BindComputeBuffers (
Buffer bufferOne ,
Buffer bufferTwo ,
Buffer bufferThree ,
Buffer bufferFour
) {
#if DEBUG
AssertComputePipelineBound ( ) ;
AssertComputeBufferCount ( 4 ) ;
# endif
var bufferPtrs = stackalloc IntPtr [ 4 ] ;
bufferPtrs [ 0 ] = bufferOne . Handle ;
bufferPtrs [ 1 ] = bufferTwo . Handle ;
bufferPtrs [ 2 ] = bufferThree . Handle ;
bufferPtrs [ 3 ] = bufferFour . Handle ;
Refresh . Refresh_BindComputeBuffers (
Device . Handle ,
Handle ,
( IntPtr ) bufferPtrs
) ;
}
/// <summary>
/// Binds buffers to be used in the compute shader.
/// </summary>
/// <param name="buffers">A Span of buffers to bind.</param>
public unsafe void BindComputeBuffers (
in Span < Buffer > buffers
) {
#if DEBUG
AssertComputePipelineBound ( ) ;
AssertComputeBufferCount ( buffers . Length ) ;
2022-09-07 20:07:17 +00:00
# endif
2022-02-23 05:14:32 +00:00
var bufferPtrs = stackalloc IntPtr [ buffers . Length ] ;
for ( var i = 0 ; i < buffers . Length ; i + = 1 )
{
bufferPtrs [ i ] = buffers [ i ] . Handle ;
}
Refresh . Refresh_BindComputeBuffers (
Device . Handle ,
Handle ,
( IntPtr ) bufferPtrs
) ;
}
2022-11-17 20:35:21 +00:00
/// <summary>
/// Binds a texture to be used in the compute shader.
/// </summary>
/// <param name="texture">A texture to bind.</param>
public unsafe void BindComputeTextures (
Texture texture
) {
#if DEBUG
AssertComputePipelineBound ( ) ;
AssertComputeTextureCount ( 1 ) ;
# endif
var texturePtrs = stackalloc IntPtr [ 1 ] ;
texturePtrs [ 0 ] = texture . Handle ;
Refresh . Refresh_BindComputeTextures (
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs
) ;
}
2022-02-23 05:14:32 +00:00
/// <summary>
/// Binds textures to be used in the compute shader.
/// </summary>
2022-11-17 20:35:21 +00:00
/// <param name="textureOne">A texture to bind.</param>
/// <param name="textureTwo">A texture to bind.</param>
2022-02-23 05:14:32 +00:00
public unsafe void BindComputeTextures (
2022-11-17 20:35:21 +00:00
Texture textureOne ,
Texture textureTwo
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertComputePipelineBound ( ) ;
2022-11-17 20:35:21 +00:00
AssertComputeTextureCount ( 2 ) ;
# endif
2022-09-07 20:07:17 +00:00
2022-11-17 20:35:21 +00:00
var texturePtrs = stackalloc IntPtr [ 2 ] ;
texturePtrs [ 0 ] = textureOne . Handle ;
texturePtrs [ 1 ] = textureTwo . Handle ;
2022-09-07 20:07:17 +00:00
2022-11-17 20:35:21 +00:00
Refresh . Refresh_BindComputeTextures (
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs
) ;
}
/// <summary>
/// Binds textures to be used in the compute shader.
/// </summary>
/// <param name="textureOne">A texture to bind.</param>
/// <param name="textureTwo">A texture to bind.</param>
/// <param name="textureThree">A texture to bind.</param>
public unsafe void BindComputeTextures (
Texture textureOne ,
Texture textureTwo ,
Texture textureThree
) {
#if DEBUG
AssertComputePipelineBound ( ) ;
AssertComputeTextureCount ( 3 ) ;
# endif
var texturePtrs = stackalloc IntPtr [ 3 ] ;
texturePtrs [ 0 ] = textureOne . Handle ;
texturePtrs [ 1 ] = textureTwo . Handle ;
texturePtrs [ 2 ] = textureThree . Handle ;
Refresh . Refresh_BindComputeTextures (
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs
) ;
}
/// <summary>
/// Binds textures to be used in the compute shader.
/// </summary>
/// <param name="textureOne">A texture to bind.</param>
/// <param name="textureTwo">A texture to bind.</param>
/// <param name="textureThree">A texture to bind.</param>
/// <param name="textureFour">A texture to bind.</param>
public unsafe void BindComputeTextures (
Texture textureOne ,
Texture textureTwo ,
Texture textureThree ,
Texture textureFour
) {
#if DEBUG
AssertComputePipelineBound ( ) ;
AssertComputeTextureCount ( 4 ) ;
# endif
var texturePtrs = stackalloc IntPtr [ 4 ] ;
texturePtrs [ 0 ] = textureOne . Handle ;
texturePtrs [ 1 ] = textureTwo . Handle ;
texturePtrs [ 2 ] = textureThree . Handle ;
texturePtrs [ 3 ] = textureFour . Handle ;
Refresh . Refresh_BindComputeTextures (
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs
) ;
}
/// <summary>
/// Binds textures to be used in the compute shader.
/// </summary>
/// <param name="textures">A set of textures to bind.</param>
public unsafe void BindComputeTextures (
in Span < Texture > textures
) {
#if DEBUG
AssertComputePipelineBound ( ) ;
AssertComputeTextureCount ( textures . Length ) ;
2022-09-07 20:07:17 +00:00
# endif
2022-02-23 05:14:32 +00:00
var texturePtrs = stackalloc IntPtr [ textures . Length ] ;
for ( var i = 0 ; i < textures . Length ; i + = 1 )
{
texturePtrs [ i ] = textures [ i ] . Handle ;
}
Refresh . Refresh_BindComputeTextures (
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs
) ;
}
/// <summary>
/// Dispatches compute work.
/// </summary>
/// <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 ,
uint computeParamOffset
2022-11-17 20:35:21 +00:00
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertComputePipelineBound ( ) ;
2022-11-14 18:21:03 +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
2022-02-23 05:14:32 +00:00
Refresh . Refresh_DispatchCompute (
Device . Handle ,
Handle ,
groupCountX ,
groupCountY ,
groupCountZ ,
computeParamOffset
) ;
}
/// <summary>
/// Binds a graphics pipeline so that rendering work may be performed.
/// </summary>
/// <param name="graphicsPipeline">The graphics pipeline to bind.</param>
public void BindGraphicsPipeline (
GraphicsPipeline graphicsPipeline
2022-11-17 20:35:21 +00:00
) {
2022-11-09 18:49:53 +00:00
#if DEBUG
AssertRenderPassActive ( ) ;
2022-11-17 20:35:21 +00:00
AssertRenderPassPipelineFormatMatch ( graphicsPipeline ) ;
2022-11-09 18:49:53 +00:00
if ( graphicsPipeline . SampleCount ! = currentSampleCount )
{
throw new System . ArgumentException ( "The sample count of the bound GraphicsPipeline must match the sample count of the current render pass!" ) ;
}
# endif
2022-02-23 05:14:32 +00:00
Refresh . Refresh_BindGraphicsPipeline (
Device . Handle ,
Handle ,
graphicsPipeline . Handle
) ;
2022-09-07 20:07:17 +00:00
2022-11-17 20:35:21 +00:00
#if DEBUG
2022-09-07 20:07:17 +00:00
currentGraphicsPipeline = graphicsPipeline ;
2022-11-17 20:35:21 +00:00
# endif
2022-02-23 05:14:32 +00:00
}
2022-03-04 22:14:22 +00:00
/// <summary>
/// Sets the viewport. Only valid during a render pass.
/// </summary>
2022-11-17 20:35:21 +00:00
public void SetViewport ( in Viewport viewport )
2022-03-04 21:21:52 +00:00
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertRenderPassActive ( ) ;
# endif
2022-03-04 21:21:52 +00:00
Refresh . Refresh_SetViewport (
Device . Handle ,
Handle ,
viewport . ToRefresh ( )
) ;
}
2022-03-04 22:14:22 +00:00
/// <summary>
/// Sets the scissor area. Only valid during a render pass.
/// </summary>
2022-11-17 20:35:21 +00:00
public void SetScissor ( in Rect scissor )
2022-03-04 21:21:52 +00:00
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertRenderPassActive ( ) ;
2022-12-14 00:09:32 +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!" ) ;
}
2022-09-07 20:07:17 +00:00
# endif
2022-11-17 20:35:21 +00:00
Refresh . Refresh_SetScissor (
Device . Handle ,
Handle ,
scissor . ToRefresh ( )
) ;
}
/// <summary>
/// Binds vertex buffers to be used by subsequent draw calls.
/// </summary>
/// <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
) {
var bufferPtrs = stackalloc IntPtr [ 1 ] ;
var offsets = stackalloc ulong [ 1 ] ;
bufferPtrs [ 0 ] = bufferBinding . Buffer . Handle ;
offsets [ 0 ] = bufferBinding . Offset ;
Refresh . Refresh_BindVertexBuffers (
Device . Handle ,
Handle ,
firstBinding ,
1 ,
( IntPtr ) bufferPtrs ,
( IntPtr ) offsets
) ;
}
/// <summary>
/// Binds vertex buffers to be used by subsequent draw calls.
/// </summary>
/// <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
) {
var bufferPtrs = stackalloc IntPtr [ 2 ] ;
var offsets = stackalloc ulong [ 2 ] ;
bufferPtrs [ 0 ] = bufferBindingOne . Buffer . Handle ;
bufferPtrs [ 1 ] = bufferBindingTwo . Buffer . Handle ;
offsets [ 0 ] = bufferBindingOne . Offset ;
offsets [ 1 ] = bufferBindingTwo . Offset ;
Refresh . Refresh_BindVertexBuffers (
Device . Handle ,
Handle ,
firstBinding ,
2 ,
( IntPtr ) bufferPtrs ,
( IntPtr ) offsets
) ;
}
/// <summary>
/// Binds vertex buffers to be used by subsequent draw calls.
/// </summary>
/// <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
) {
var bufferPtrs = stackalloc IntPtr [ 3 ] ;
var offsets = stackalloc ulong [ 3 ] ;
bufferPtrs [ 0 ] = bufferBindingOne . Buffer . Handle ;
bufferPtrs [ 1 ] = bufferBindingTwo . Buffer . Handle ;
bufferPtrs [ 2 ] = bufferBindingThree . Buffer . Handle ;
offsets [ 0 ] = bufferBindingOne . Offset ;
offsets [ 1 ] = bufferBindingTwo . Offset ;
offsets [ 2 ] = bufferBindingThree . Offset ;
Refresh . Refresh_BindVertexBuffers (
2022-03-04 21:21:52 +00:00
Device . Handle ,
Handle ,
2022-11-17 20:35:21 +00:00
firstBinding ,
3 ,
( IntPtr ) bufferPtrs ,
( IntPtr ) offsets
2022-03-04 21:21:52 +00:00
) ;
}
2022-02-23 05:14:32 +00:00
/// <summary>
/// Binds vertex buffers to be used by subsequent draw calls.
/// </summary>
2022-11-17 20:35:21 +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>
2022-02-23 05:14:32 +00:00
public unsafe void BindVertexBuffers (
2022-11-17 20:35:21 +00:00
in BufferBinding bufferBindingOne ,
in BufferBinding bufferBindingTwo ,
in BufferBinding bufferBindingThree ,
in BufferBinding bufferBindingFour ,
uint firstBinding = 0
) {
var bufferPtrs = stackalloc IntPtr [ 4 ] ;
var offsets = stackalloc ulong [ 4 ] ;
bufferPtrs [ 0 ] = bufferBindingOne . Buffer . Handle ;
bufferPtrs [ 1 ] = bufferBindingTwo . Buffer . Handle ;
bufferPtrs [ 2 ] = bufferBindingThree . Buffer . Handle ;
bufferPtrs [ 3 ] = bufferBindingFour . Buffer . Handle ;
offsets [ 0 ] = bufferBindingOne . Offset ;
offsets [ 1 ] = bufferBindingTwo . Offset ;
offsets [ 2 ] = bufferBindingThree . Offset ;
offsets [ 3 ] = bufferBindingFour . Offset ;
2022-02-23 05:14:32 +00:00
Refresh . Refresh_BindVertexBuffers (
Device . Handle ,
Handle ,
firstBinding ,
2022-11-17 20:35:21 +00:00
4 ,
2022-02-23 05:14:32 +00:00
( IntPtr ) bufferPtrs ,
( IntPtr ) offsets
) ;
}
/// <summary>
/// Binds vertex buffers to be used by subsequent draw calls.
/// </summary>
2022-11-17 20:35:21 +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>
2022-02-23 05:14:32 +00:00
public unsafe void BindVertexBuffers (
2022-11-17 20:35:21 +00:00
in Span < BufferBinding > bufferBindings ,
uint firstBinding = 0
) {
var bufferPtrs = stackalloc IntPtr [ bufferBindings . Length ] ;
var offsets = stackalloc ulong [ bufferBindings . Length ] ;
2022-02-23 05:14:32 +00:00
2022-11-17 20:35:21 +00:00
for ( var i = 0 ; i < bufferBindings . Length ; i + = 1 )
2022-02-23 05:14:32 +00:00
{
2022-11-17 20:35:21 +00:00
bufferPtrs [ i ] = bufferBindings [ i ] . Buffer . Handle ;
offsets [ i ] = bufferBindings [ i ] . Offset ;
2022-02-23 05:14:32 +00:00
}
Refresh . Refresh_BindVertexBuffers (
Device . Handle ,
Handle ,
2022-11-17 20:35:21 +00:00
firstBinding ,
( uint ) bufferBindings . Length ,
2022-02-23 05:14:32 +00:00
( IntPtr ) bufferPtrs ,
( IntPtr ) offsets
) ;
}
/// <summary>
/// Binds an index buffer to be used by subsequent draw calls.
/// </summary>
/// <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 (
Buffer indexBuffer ,
IndexElementSize indexElementSize ,
uint offset = 0
)
{
Refresh . Refresh_BindIndexBuffer (
Device . Handle ,
Handle ,
indexBuffer . Handle ,
offset ,
( Refresh . IndexElementSize ) indexElementSize
) ;
}
/// <summary>
/// Binds samplers to be used by the vertex shader.
/// </summary>
2022-11-17 20:35:21 +00:00
/// <param name="textureSamplerBindings">The texture-sampler to bind.</param>
2022-02-23 05:14:32 +00:00
public unsafe void BindVertexSamplers (
2022-11-17 20:35:21 +00:00
in TextureSamplerBinding textureSamplerBinding
) {
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertGraphicsPipelineBound ( ) ;
2022-11-17 20:35:21 +00:00
AssertVertexSamplerCount ( 1 ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBinding ) ;
AssertTextureBindingUsageFlags ( textureSamplerBinding . Texture ) ;
# endif
2022-09-07 20:07:17 +00:00
2022-11-17 20:35:21 +00:00
var texturePtrs = stackalloc IntPtr [ 1 ] ;
var samplerPtrs = stackalloc IntPtr [ 1 ] ;
2022-09-07 20:07:17 +00:00
2022-11-17 20:35:21 +00:00
texturePtrs [ 0 ] = textureSamplerBinding . Texture . Handle ;
samplerPtrs [ 0 ] = textureSamplerBinding . Sampler . Handle ;
2022-09-07 20:07:17 +00:00
2022-11-17 20:35:21 +00:00
Refresh . Refresh_BindVertexSamplers (
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
) ;
}
2022-02-23 05:14:32 +00:00
2022-11-17 20:35:21 +00:00
/// <summary>
/// Binds samplers to be used by the vertex shader.
/// </summary>
/// <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-08 19:29:05 +00:00
#if DEBUG
2022-11-17 20:35:21 +00:00
AssertGraphicsPipelineBound ( ) ;
AssertVertexSamplerCount ( 2 ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingOne ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingTwo ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingOne . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingTwo . Texture ) ;
2022-11-08 19:29:05 +00:00
# endif
2022-11-17 20:35:21 +00:00
var texturePtrs = stackalloc IntPtr [ 2 ] ;
var samplerPtrs = stackalloc IntPtr [ 2 ] ;
texturePtrs [ 0 ] = textureSamplerBindingOne . Texture . Handle ;
texturePtrs [ 1 ] = textureSamplerBindingTwo . Texture . Handle ;
samplerPtrs [ 0 ] = textureSamplerBindingOne . Sampler . Handle ;
samplerPtrs [ 1 ] = textureSamplerBindingTwo . Sampler . Handle ;
2022-02-23 05:14:32 +00:00
Refresh . Refresh_BindVertexSamplers (
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
) ;
}
/// <summary>
2022-11-16 01:53:30 +00:00
/// Binds samplers to be used by the vertex shader.
2022-02-23 05:14:32 +00:00
/// </summary>
2022-11-17 20:35:21 +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>
2022-11-16 01:53:30 +00:00
public unsafe void BindVertexSamplers (
2022-11-17 20:35:21 +00:00
in TextureSamplerBinding textureSamplerBindingOne ,
in TextureSamplerBinding textureSamplerBindingTwo ,
in TextureSamplerBinding textureSamplerBindingThree
) {
#if DEBUG
AssertGraphicsPipelineBound ( ) ;
AssertVertexSamplerCount ( 3 ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingOne ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingTwo ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingThree ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingOne . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingTwo . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingThree . Texture ) ;
# endif
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 (
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
) ;
2022-11-16 01:53:30 +00:00
}
/// <summary>
/// Binds samplers to be used by the vertex shader.
/// </summary>
2022-11-17 20:35:21 +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-09-07 20:07:17 +00:00
#if DEBUG
AssertGraphicsPipelineBound ( ) ;
2022-11-17 20:35:21 +00:00
AssertVertexSamplerCount ( 4 ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingOne ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingTwo ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingThree ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingFour ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingOne . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingTwo . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingThree . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingFour . Texture ) ;
# endif
2022-09-07 20:07:17 +00:00
2022-11-17 20:35:21 +00:00
var texturePtrs = stackalloc IntPtr [ 4 ] ;
var samplerPtrs = stackalloc IntPtr [ 4 ] ;
2022-09-07 20:07:17 +00:00
2022-11-17 20:35:21 +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_BindVertexSamplers (
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
) ;
}
/// <summary>
/// Binds samplers to be used by the vertex shader.
/// </summary>
/// <param name="textureSamplerBindings">The texture-sampler pairs to bind.</param>
public unsafe void BindVertexSamplers (
in Span < TextureSamplerBinding > textureSamplerBindings
) {
#if DEBUG
AssertGraphicsPipelineBound ( ) ;
AssertVertexSamplerCount ( textureSamplerBindings . Length ) ;
2022-09-07 20:07:17 +00:00
# endif
2022-11-17 20:35:21 +00:00
var texturePtrs = stackalloc IntPtr [ textureSamplerBindings . Length ] ;
var samplerPtrs = stackalloc IntPtr [ textureSamplerBindings . Length ] ;
2022-02-23 05:14:32 +00:00
2022-11-17 20:35:21 +00:00
for ( var i = 0 ; i < textureSamplerBindings . Length ; i + = 1 )
2022-02-23 05:14:32 +00:00
{
2022-11-08 19:29:05 +00:00
#if DEBUG
AssertTextureSamplerBindingNonNull ( textureSamplerBindings [ i ] ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindings [ i ] . Texture ) ;
# endif
2022-03-17 21:42:43 +00:00
2022-11-08 19:29:05 +00:00
texturePtrs [ i ] = textureSamplerBindings [ i ] . Texture . Handle ;
samplerPtrs [ i ] = textureSamplerBindings [ i ] . Sampler . Handle ;
2022-02-23 05:14:32 +00:00
}
2022-11-17 20:35:21 +00:00
Refresh . Refresh_BindVertexSamplers (
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
) ;
}
/// <summary>
/// Binds samplers to be used by the fragment shader.
/// </summary>
/// <param name="textureSamplerBinding">The texture-sampler to bind.</param>
public unsafe void BindFragmentSamplers (
in TextureSamplerBinding textureSamplerBinding
) {
#if DEBUG
AssertGraphicsPipelineBound ( ) ;
AssertFragmentSamplerCount ( 1 ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBinding ) ;
AssertTextureBindingUsageFlags ( textureSamplerBinding . Texture ) ;
# endif
var texturePtrs = stackalloc IntPtr [ 1 ] ;
var samplerPtrs = stackalloc IntPtr [ 1 ] ;
texturePtrs [ 0 ] = textureSamplerBinding . Texture . Handle ;
samplerPtrs [ 0 ] = textureSamplerBinding . Sampler . Handle ;
2022-02-23 05:14:32 +00:00
Refresh . Refresh_BindFragmentSamplers (
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
) ;
}
2022-11-16 01:53:30 +00:00
/// <summary>
/// Binds samplers to be used by the fragment shader.
/// </summary>
2022-11-17 20:35:21 +00:00
/// <param name="textureSamplerBindingOne">The first texture-sampler to bind.</param>
/// <param name="textureSamplerBindingTwo">The second texture-sampler to bind.</param>
2022-11-16 01:53:30 +00:00
public unsafe void BindFragmentSamplers (
2022-11-17 20:35:21 +00:00
in TextureSamplerBinding textureSamplerBindingOne ,
in TextureSamplerBinding textureSamplerBindingTwo
) {
#if DEBUG
AssertGraphicsPipelineBound ( ) ;
AssertFragmentSamplerCount ( 2 ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingOne ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingTwo ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingOne . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingTwo . Texture ) ;
# endif
var texturePtrs = stackalloc IntPtr [ 2 ] ;
var samplerPtrs = stackalloc IntPtr [ 2 ] ;
texturePtrs [ 0 ] = textureSamplerBindingOne . Texture . Handle ;
texturePtrs [ 1 ] = textureSamplerBindingTwo . Texture . Handle ;
samplerPtrs [ 0 ] = textureSamplerBindingOne . Sampler . Handle ;
samplerPtrs [ 1 ] = textureSamplerBindingTwo . Sampler . Handle ;
Refresh . Refresh_BindFragmentSamplers (
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
) ;
}
/// <summary>
/// Binds samplers to be used by the fragment shader.
/// </summary>
/// <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
) {
#if DEBUG
AssertGraphicsPipelineBound ( ) ;
AssertFragmentSamplerCount ( 3 ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingOne ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingTwo ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingThree ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingOne . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingTwo . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingThree . Texture ) ;
# endif
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_BindFragmentSamplers (
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
) ;
}
/// <summary>
/// Binds samplers to be used by the fragment shader.
/// </summary>
/// <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
) {
#if DEBUG
AssertGraphicsPipelineBound ( ) ;
AssertFragmentSamplerCount ( 4 ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingOne ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingTwo ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingThree ) ;
AssertTextureSamplerBindingNonNull ( textureSamplerBindingFour ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingOne . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingTwo . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingThree . Texture ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindingFour . Texture ) ;
# endif
var texturePtrs = stackalloc IntPtr [ 4 ] ;
var samplerPtrs = stackalloc IntPtr [ 4 ] ;
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 (
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
) ;
}
/// <summary>
/// Binds samplers to be used by the fragment shader.
/// </summary>
/// <param name="textureSamplerBindings">The texture-sampler pairs to bind.</param>
public unsafe void BindFragmentSamplers (
in Span < TextureSamplerBinding > textureSamplerBindings
) {
#if DEBUG
AssertGraphicsPipelineBound ( ) ;
AssertFragmentSamplerCount ( textureSamplerBindings . Length ) ;
# endif
var texturePtrs = stackalloc IntPtr [ textureSamplerBindings . Length ] ;
var samplerPtrs = stackalloc IntPtr [ textureSamplerBindings . Length ] ;
for ( var i = 0 ; i < textureSamplerBindings . Length ; i + = 1 )
{
#if DEBUG
AssertTextureSamplerBindingNonNull ( textureSamplerBindings [ i ] ) ;
AssertTextureBindingUsageFlags ( textureSamplerBindings [ i ] . Texture ) ;
# endif
texturePtrs [ i ] = textureSamplerBindings [ i ] . Texture . Handle ;
samplerPtrs [ i ] = textureSamplerBindings [ i ] . Sampler . Handle ;
}
Refresh . Refresh_BindFragmentSamplers (
Device . Handle ,
Handle ,
( IntPtr ) texturePtrs ,
( IntPtr ) samplerPtrs
) ;
2022-11-16 01:53:30 +00:00
}
2022-02-23 05:14:32 +00:00
/// <summary>
/// Pushes vertex shader uniforms to the device.
/// </summary>
/// <returns>A starting offset value to be used with draw calls.</returns>
public unsafe uint PushVertexShaderUniforms < T > (
2022-11-17 20:35:21 +00:00
in T uniforms
2022-02-23 05:14:32 +00:00
) where T : unmanaged
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertGraphicsPipelineBound ( ) ;
if ( currentGraphicsPipeline . VertexShaderInfo . UniformBufferSize = = 0 )
{
throw new InvalidOperationException ( "The current vertex shader does not take a uniform buffer!" ) ;
}
# endif
2022-11-08 19:29:05 +00:00
2022-11-17 20:35:21 +00:00
fixed ( T * uniformsPtr = & uniforms )
2022-02-23 05:14:32 +00:00
{
return Refresh . Refresh_PushVertexShaderUniforms (
Device . Handle ,
Handle ,
2022-11-17 20:35:21 +00:00
( IntPtr ) uniformsPtr ,
( uint ) sizeof ( T )
2022-02-23 05:14:32 +00:00
) ;
}
}
/// <summary>
/// Pushes fragment shader uniforms to the device.
/// </summary>
/// <returns>A starting offset to be used with draw calls.</returns>
public unsafe uint PushFragmentShaderUniforms < T > (
2022-11-17 20:35:21 +00:00
in T uniforms
2022-02-23 05:14:32 +00:00
) where T : unmanaged
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertGraphicsPipelineBound ( ) ;
if ( currentGraphicsPipeline . FragmentShaderInfo . UniformBufferSize = = 0 )
{
throw new InvalidOperationException ( "The current fragment shader does not take a uniform buffer!" ) ;
}
# endif
2022-11-17 20:35:21 +00:00
fixed ( T * uniformsPtr = & uniforms )
2022-02-23 05:14:32 +00:00
{
return Refresh . Refresh_PushFragmentShaderUniforms (
Device . Handle ,
Handle ,
2022-11-17 20:35:21 +00:00
( IntPtr ) uniformsPtr ,
( uint ) sizeof ( T )
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>
public unsafe uint PushComputeShaderUniforms < T > (
2022-11-17 20:35:21 +00:00
in T uniforms
2022-02-23 05:14:32 +00:00
) where T : unmanaged
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertComputePipelineBound ( ) ;
if ( currentComputePipeline . ComputeShaderInfo . UniformBufferSize = = 0 )
{
throw new System . InvalidOperationException ( "The current compute shader does not take a uniform buffer!" ) ;
}
# endif
2022-11-17 20:35:21 +00:00
fixed ( T * uniformsPtr = & uniforms )
2022-02-23 05:14:32 +00:00
{
return Refresh . Refresh_PushComputeShaderUniforms (
Device . Handle ,
Handle ,
2022-11-17 20:35:21 +00:00
( IntPtr ) uniformsPtr ,
( uint ) sizeof ( T )
2022-02-23 05:14:32 +00:00
) ;
}
}
/// <summary>
/// Draws using instanced rendering.
/// It is an error to call this method unless two vertex buffers have been bound.
/// </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>
/// <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 DrawInstancedPrimitives (
uint baseVertex ,
uint startIndex ,
uint primitiveCount ,
uint instanceCount ,
uint vertexParamOffset ,
uint fragmentParamOffset
)
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertGraphicsPipelineBound ( ) ;
# endif
2022-02-23 05:14:32 +00:00
Refresh . Refresh_DrawInstancedPrimitives (
Device . Handle ,
Handle ,
baseVertex ,
startIndex ,
primitiveCount ,
instanceCount ,
vertexParamOffset ,
fragmentParamOffset
) ;
}
/// <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>
/// <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 DrawIndexedPrimitives (
uint baseVertex ,
uint startIndex ,
uint primitiveCount ,
uint vertexParamOffset ,
uint fragmentParamOffset
)
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertGraphicsPipelineBound ( ) ;
# endif
2022-02-23 05:14:32 +00:00
Refresh . Refresh_DrawIndexedPrimitives (
Device . Handle ,
Handle ,
baseVertex ,
startIndex ,
primitiveCount ,
vertexParamOffset ,
fragmentParamOffset
) ;
}
/// <summary>
/// Draws using a vertex buffer.
/// </summary>
/// <param name="vertexStart"></param>
/// <param name="primitiveCount"></param>
/// <param name="vertexParamOffset"></param>
/// <param name="fragmentParamOffset"></param>
public void DrawPrimitives (
uint vertexStart ,
uint primitiveCount ,
uint vertexParamOffset ,
uint fragmentParamOffset
)
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertGraphicsPipelineBound ( ) ;
# endif
2022-02-23 05:14:32 +00:00
Refresh . Refresh_DrawPrimitives (
Device . Handle ,
Handle ,
vertexStart ,
primitiveCount ,
vertexParamOffset ,
fragmentParamOffset
) ;
}
2022-08-25 19:32: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 (
Buffer buffer ,
uint offsetInBytes ,
uint drawCount ,
uint stride ,
uint vertexParamOffset ,
uint fragmentParamOffset
)
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertGraphicsPipelineBound ( ) ;
# endif
2022-08-25 19:32:49 +00:00
Refresh . Refresh_DrawPrimitivesIndirect (
Device . Handle ,
Handle ,
buffer . Handle ,
offsetInBytes ,
drawCount ,
stride ,
vertexParamOffset ,
fragmentParamOffset
) ;
}
2022-02-23 05:14:32 +00:00
/// <summary>
/// Ends the current render pass.
/// This must be called before beginning another render pass or submitting the command buffer.
/// </summary>
public void EndRenderPass ( )
{
Refresh . Refresh_EndRenderPass (
Device . Handle ,
Handle
) ;
2022-09-07 20:07:17 +00:00
2022-11-17 20:35:21 +00:00
#if DEBUG
2022-09-07 20:07:17 +00:00
currentGraphicsPipeline = null ;
renderPassActive = false ;
2022-11-17 20:35:21 +00:00
# endif
2022-02-23 05:14:32 +00:00
}
/// <summary>
2022-03-02 06:57:10 +00:00
/// Acquires a swapchain texture.
/// This texture will be presented to the given window when the command buffer is submitted.
2022-03-02 18:13:52 +00:00
/// 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.
2022-12-01 21:20:11 +00:00
/// It is an error to dispose the swapchain texture. If you do this your game WILL crash. DO NOT DO THIS.
2022-02-23 05:14:32 +00:00
/// </summary>
2022-11-17 20:35:21 +00:00
public Texture AcquireSwapchainTexture (
2022-02-25 21:23:31 +00:00
Window window
2022-12-01 21:20:11 +00:00
) {
2022-03-02 17:39:23 +00:00
var texturePtr = Refresh . Refresh_AcquireSwapchainTexture (
Device . Handle ,
Handle ,
2022-03-10 18:25:41 +00:00
window . Handle ,
out var width ,
out var height
2022-03-02 17:39:23 +00:00
) ;
if ( texturePtr = = IntPtr . Zero )
{
return null ;
}
2022-12-13 08:52:35 +00:00
// Override the texture properties to avoid allocating a new texture instance!
window . SwapchainTexture . Handle = texturePtr ;
window . SwapchainTexture . Width = width ;
window . SwapchainTexture . Height = height ;
window . SwapchainTexture . Format = window . SwapchainFormat ;
return window . SwapchainTexture ;
2022-02-23 05:14:32 +00:00
}
2022-02-23 06:16:06 +00:00
/// <summary>
/// Copies array data into a buffer.
/// </summary>
/// <param name="buffer">The buffer to copy to.</param>
/// <param name="data">The array to copy from.</param>
/// <param name="bufferOffsetInBytes">Specifies where in the buffer to start copying.</param>
/// <param name="setDataOption">Specifies whether the buffer should be copied in immediate or deferred mode. When in doubt, use deferred.</param>
public unsafe void SetBufferData < T > (
Buffer buffer ,
T [ ] data ,
uint bufferOffsetInBytes = 0
) where T : unmanaged
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertRenderPassInactive ( "Cannot copy during render pass!" ) ;
# endif
2022-02-23 06:16:06 +00:00
SetBufferData (
buffer ,
data ,
bufferOffsetInBytes ,
0 ,
( uint ) data . Length
) ;
}
2022-02-23 05:14:32 +00:00
/// <summary>
/// Copies arbitrary data into a buffer.
/// </summary>
/// <param name="buffer">The buffer to copy into.</param>
/// <param name="dataPtr">Pointer to the data to copy into the buffer.</param>
/// <param name="bufferOffsetInBytes">Specifies where in the buffer to copy data.</param>
/// <param name="dataLengthInBytes">The length of data that should be copied.</param>
/// <param name="setDataOption">Specifies whether the buffer should be copied in immediate or deferred mode. When in doubt, use deferred.</param>
public void SetBufferData (
Buffer buffer ,
IntPtr dataPtr ,
uint bufferOffsetInBytes ,
uint dataLengthInBytes
)
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertRenderPassInactive ( "Cannot copy during render pass!" ) ;
# endif
2022-02-23 05:14:32 +00:00
Refresh . Refresh_SetBufferData (
Device . Handle ,
Handle ,
buffer . Handle ,
bufferOffsetInBytes ,
dataPtr ,
dataLengthInBytes
) ;
}
/// <summary>
/// Copies array data into a buffer.
/// </summary>
/// <param name="buffer">The buffer to copy to.</param>
/// <param name="data">The array to copy from.</param>
/// <param name="bufferOffsetInBytes">Specifies where in the buffer to start copying.</param>
/// <param name="startElement">The index of the first element to copy from the array.</param>
/// <param name="numElements">How many elements to copy.</param>
/// <param name="setDataOption">Specifies whether the buffer should be copied in immediate or deferred mode. When in doubt, use deferred.</param>
public unsafe void SetBufferData < T > (
Buffer buffer ,
T [ ] data ,
uint bufferOffsetInBytes ,
uint startElement ,
uint numElements
) where T : unmanaged
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertRenderPassInactive ( "Cannot copy during render pass!" ) ;
# endif
2022-04-27 21:14:15 +00:00
var elementSize = sizeof ( T ) ;
2022-02-23 05:14:32 +00:00
2022-11-12 03:42:35 +00:00
fixed ( T * ptr = & data [ startElement ] )
2022-02-23 05:14:32 +00:00
{
Refresh . Refresh_SetBufferData (
Device . Handle ,
Handle ,
buffer . Handle ,
bufferOffsetInBytes ,
2022-11-12 03:42:35 +00:00
( IntPtr ) ptr ,
2022-02-23 05:14:32 +00:00
( uint ) ( numElements * elementSize )
) ;
}
}
2022-04-27 21:14:15 +00:00
public unsafe void SetBufferData < T > (
2022-03-04 18:00:29 +00:00
Buffer buffer ,
IntPtr dataPtr ,
uint bufferOffsetInElements ,
uint numElements
2022-04-27 21:14:15 +00:00
) where T : unmanaged {
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertRenderPassInactive ( "Cannot copy during render pass!" ) ;
# endif
2022-03-04 18:00:29 +00:00
Refresh . Refresh_SetBufferData (
Device . Handle ,
Handle ,
buffer . Handle ,
2022-04-27 21:14:15 +00:00
( uint ) sizeof ( T ) * bufferOffsetInElements ,
2022-03-04 18:00:29 +00:00
dataPtr ,
2022-04-27 21:14:15 +00:00
( uint ) sizeof ( T ) * numElements
2022-03-04 18:00:29 +00:00
) ;
}
2022-02-23 05:14:32 +00:00
/// <summary>
/// Asynchronously copies data into a texture.
/// </summary>
2022-02-23 06:16:06 +00:00
/// <param name="data">An array of data to copy into the texture.</param>
public unsafe void SetTextureData < T > ( Texture texture , T [ ] data ) where T : unmanaged
2022-02-23 05:14:32 +00:00
{
2022-02-23 06:16:06 +00:00
SetTextureData ( new TextureSlice ( texture ) , data ) ;
2022-02-23 05:14:32 +00:00
}
/// <summary>
2022-02-23 06:16:06 +00:00
/// Asynchronously copies data into a texture slice.
2022-02-23 05:14:32 +00:00
/// </summary>
/// <param name="textureSlice">The texture slice to copy into.</param>
/// <param name="data">An array of data to copy into the texture.</param>
public unsafe void SetTextureData < T > ( in TextureSlice textureSlice , T [ ] data ) where T : unmanaged
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertRenderPassInactive ( "Cannot copy during render pass!" ) ;
# endif
2022-04-27 21:14:15 +00:00
var size = sizeof ( T ) ;
2022-02-23 05:14:32 +00:00
fixed ( T * ptr = & data [ 0 ] )
{
Refresh . Refresh_SetTextureData (
Device . Handle ,
Handle ,
textureSlice . ToRefreshTextureSlice ( ) ,
( IntPtr ) ptr ,
( uint ) ( data . Length * size )
) ;
}
}
2022-02-23 06:16:06 +00:00
/// <summary>
/// Asynchronously copies data into a texture slice.
/// </summary>
/// <param name="textureSlice">The texture slice to copy into.</param>
/// <param name="dataPtr">A pointer to an array of data to copy from.</param>
/// <param name="dataLengthInBytes">The amount of data to copy from the array.</param>
public void SetTextureData ( in TextureSlice textureSlice , IntPtr dataPtr , uint dataLengthInBytes )
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertRenderPassInactive ( "Cannot copy during render pass!" ) ;
# endif
2022-02-23 06:16:06 +00:00
Refresh . Refresh_SetTextureData (
Device . Handle ,
Handle ,
textureSlice . ToRefreshTextureSlice ( ) ,
dataPtr ,
dataLengthInBytes
) ;
}
2022-02-23 05:14:32 +00:00
/// <summary>
/// Asynchronously copies data into a texture.
/// </summary>
2022-02-23 06:16:06 +00:00
/// <param name="dataPtr">A pointer to an array of data to copy from.</param>
/// <param name="dataLengthInBytes">The amount of data to copy from the array.</param>
public void SetTextureData ( Texture texture , IntPtr dataPtr , uint dataLengthInBytes )
2022-02-23 05:14:32 +00:00
{
2022-02-23 06:16:06 +00:00
SetTextureData ( new TextureSlice ( texture ) , dataPtr , dataLengthInBytes ) ;
2022-02-23 05:14:32 +00:00
}
2022-08-02 21:04:12 +00:00
/// <summary>
/// Asynchronously copies YUV data into three textures. Use with compressed video.
/// </summary>
public void SetTextureDataYUV ( Texture yTexture , Texture uTexture , Texture vTexture , IntPtr dataPtr , uint dataLengthInBytes )
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertRenderPassInactive ( "Cannot copy during render pass!" ) ;
# endif
2022-08-02 21:04:12 +00:00
Refresh . Refresh_SetTextureDataYUV (
Device . Handle ,
Handle ,
yTexture . Handle ,
uTexture . Handle ,
vTexture . Handle ,
yTexture . Width ,
yTexture . Height ,
uTexture . Width ,
uTexture . Height ,
dataPtr ,
dataLengthInBytes
) ;
}
2022-02-23 05:14:32 +00:00
/// <summary>
/// Performs an asynchronous texture-to-texture copy on the GPU.
/// </summary>
/// <param name="sourceTextureSlice">The texture slice to copy from.</param>
/// <param name="destinationTextureSlice">The texture slice to copy to.</param>
/// <param name="filter">The filter to use if the sizes of the texture slices differ.</param>
public void CopyTextureToTexture (
in TextureSlice sourceTextureSlice ,
in TextureSlice destinationTextureSlice ,
Filter filter
)
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertRenderPassInactive ( "Cannot copy during render pass!" ) ;
# endif
2022-02-23 05:14:32 +00:00
var sourceRefreshTextureSlice = sourceTextureSlice . ToRefreshTextureSlice ( ) ;
var destRefreshTextureSlice = destinationTextureSlice . ToRefreshTextureSlice ( ) ;
Refresh . Refresh_CopyTextureToTexture (
Device . Handle ,
Handle ,
sourceRefreshTextureSlice ,
destRefreshTextureSlice ,
( Refresh . Filter ) filter
) ;
}
/// <summary>
/// Performs an asynchronous texture-to-buffer copy.
/// Note that the buffer is not guaranteed to be filled until you call GraphicsDevice.Wait()
/// </summary>
/// <param name="textureSlice"></param>
/// <param name="buffer"></param>
public void CopyTextureToBuffer (
in TextureSlice textureSlice ,
Buffer buffer
)
{
2022-09-07 20:07:17 +00:00
#if DEBUG
AssertRenderPassInactive ( "Cannot copy during render pass!" ) ;
# endif
2022-02-23 05:14:32 +00:00
var refreshTextureSlice = textureSlice . ToRefreshTextureSlice ( ) ;
Refresh . Refresh_CopyTextureToBuffer (
Device . Handle ,
Handle ,
refreshTextureSlice ,
buffer . Handle
) ;
}
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 ;
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
2022-11-17 20:35:21 +00:00
private void AssertSameSampleCount ( ColorAttachmentInfo a , ColorAttachmentInfo b )
{
if ( a . SampleCount ! = b . SampleCount )
{
throw new System . ArgumentException ( "All color 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!" ) ;
}
}
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
}