update bindings and WriteOption API

what_if_no_video_threads
cosmonaut 2024-03-01 15:03:14 -08:00
parent 0e723514df
commit 00adec189c
12 changed files with 445 additions and 334 deletions

@ -1 +1 @@
Subproject commit 020e76782a2aba7861a8e356d1d212a2bffb2d2e Subproject commit 4268db46161ec5ff924c8006a66aa59635d3ca50

View File

@ -1,17 +1,21 @@
namespace MoonWorks.Graphics using RefreshCS;
namespace MoonWorks.Graphics
{ {
/// <summary> /// <summary>
/// A buffer-offset pair to be used when binding vertex buffers. /// A buffer-offset pair to be used when binding vertex or index buffers.
/// </summary> /// </summary>
public struct BufferBinding public readonly record struct BufferBinding(
GpuBuffer Buffer,
uint Offset
) {
public Refresh.BufferBinding ToRefresh()
{ {
public GpuBuffer Buffer; return new Refresh.BufferBinding
public ulong Offset;
public BufferBinding(GpuBuffer buffer, ulong offset)
{ {
Buffer = buffer; gpuBuffer = Buffer.Handle,
Offset = offset; offset = Offset
};
} }
} }
} }

View File

@ -0,0 +1,35 @@
using RefreshCS;
namespace MoonWorks.Graphics
{
/// <summary>
/// Binding specification to be used when binding buffers for compute shaders.
/// </summary>
/// <param name="GpuBuffer">The GpuBuffer to bind.</param>
/// <param name="WriteOption">
/// Specifies data dependency behavior when this buffer is written to in the shader. <br/>
///
/// SafeDiscard:
/// If this buffer has been used in commands that have not finished,
/// this option will prevent a dependency on those commands
/// at the cost of increased memory usage.
/// You may NOT assume that any of the previous data is retained.
/// Otherwise this option is equivalent to SafeOverwrite. <br/>
///
/// SafeOverwrite:
/// Overwrites the data safely using a GPU memory barrier.
/// </param>
public readonly record struct ComputeBufferBinding(
GpuBuffer GpuBuffer,
WriteOptions WriteOption
) {
public Refresh.ComputeBufferBinding ToRefresh()
{
return new Refresh.ComputeBufferBinding
{
gpuBuffer = GpuBuffer.Handle,
writeOption = (Refresh.WriteOptions) WriteOption
};
}
}
}

View File

@ -0,0 +1,35 @@
using RefreshCS;
namespace MoonWorks.Graphics
{
/// <summary>
/// Binding specification used for binding texture slices for compute shaders.
/// </summary>
/// <param name="TextureSlice">The TextureSlice to bind.</param>
/// <param name="WriteOption">
/// Specifies data dependency behavior when this texture is written to in the shader. <br/>
///
/// SafeDiscard:
/// If this texture slice has been used in commands that have not finished,
/// this option will prevent a dependency on those commands
/// at the cost of increased memory usage.
/// You may NOT assume that any of the previous texture (not slice!) data is retained.
/// Otherwise this option is equivalent to SafeOverwrite. <br/>
///
/// SafeOverwrite:
/// Overwrites the data safely using a GPU memory barrier.
/// </param>
public readonly record struct ComputeTextureBinding(
TextureSlice TextureSlice,
WriteOptions WriteOption
) {
public Refresh.ComputeTextureBinding ToRefresh()
{
return new Refresh.ComputeTextureBinding
{
textureSlice = TextureSlice.ToRefreshTextureSlice(),
writeOption = (Refresh.WriteOptions) WriteOption
};
}
}
}

View File

@ -1,17 +1,21 @@
namespace MoonWorks.Graphics using RefreshCS;
namespace MoonWorks.Graphics
{ {
/// <summary> /// <summary>
/// A texture-sampler pair to be used when binding samplers. /// A texture-sampler pair to be used when binding samplers.
/// </summary> /// </summary>
public struct TextureSamplerBinding public readonly record struct TextureSamplerBinding(
Texture Texture,
Sampler Sampler
) {
public Refresh.TextureSamplerBinding ToRefresh()
{ {
public Texture Texture; return new Refresh.TextureSamplerBinding
public Sampler Sampler;
public TextureSamplerBinding(Texture texture, Sampler sampler)
{ {
Texture = texture; texture = Texture.Handle,
Sampler = sampler; sampler = Sampler.Handle
};
} }
} }
} }

View File

@ -670,19 +670,15 @@ namespace MoonWorks.Graphics
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
#endif #endif
var bufferPtrs = stackalloc IntPtr[1]; var bindingArray = stackalloc Refresh.BufferBinding[1];
var offsets = stackalloc ulong[1]; bindingArray[0] = bufferBinding.ToRefresh();
bufferPtrs[0] = bufferBinding.Buffer.Handle;
offsets[0] = bufferBinding.Offset;
Refresh.Refresh_BindVertexBuffers( Refresh.Refresh_BindVertexBuffers(
Device.Handle, Device.Handle,
Handle, Handle,
firstBinding, firstBinding,
1, 1,
(IntPtr) bufferPtrs, bindingArray
(IntPtr) offsets
); );
} }
@ -702,22 +698,16 @@ namespace MoonWorks.Graphics
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
#endif #endif
var bufferPtrs = stackalloc IntPtr[2]; var bindingArray = stackalloc Refresh.BufferBinding[2];
var offsets = stackalloc ulong[2]; bindingArray[0] = bufferBindingOne.ToRefresh();
bindingArray[1] = bufferBindingTwo.ToRefresh();
bufferPtrs[0] = bufferBindingOne.Buffer.Handle;
bufferPtrs[1] = bufferBindingTwo.Buffer.Handle;
offsets[0] = bufferBindingOne.Offset;
offsets[1] = bufferBindingTwo.Offset;
Refresh.Refresh_BindVertexBuffers( Refresh.Refresh_BindVertexBuffers(
Device.Handle, Device.Handle,
Handle, Handle,
firstBinding, firstBinding,
2, 2,
(IntPtr) bufferPtrs, bindingArray
(IntPtr) offsets
); );
} }
@ -739,24 +729,17 @@ namespace MoonWorks.Graphics
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
#endif #endif
var bufferPtrs = stackalloc IntPtr[3]; var bindingArray = stackalloc Refresh.BufferBinding[3];
var offsets = stackalloc ulong[3]; bindingArray[0] = bufferBindingOne.ToRefresh();
bindingArray[1] = bufferBindingTwo.ToRefresh();
bufferPtrs[0] = bufferBindingOne.Buffer.Handle; bindingArray[2] = bufferBindingThree.ToRefresh();
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( Refresh.Refresh_BindVertexBuffers(
Device.Handle, Device.Handle,
Handle, Handle,
firstBinding, firstBinding,
3, 3,
(IntPtr) bufferPtrs, bindingArray
(IntPtr) offsets
); );
} }
@ -780,26 +763,18 @@ namespace MoonWorks.Graphics
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
#endif #endif
var bufferPtrs = stackalloc IntPtr[4]; var bindingArray = stackalloc Refresh.BufferBinding[4];
var offsets = stackalloc ulong[4]; bindingArray[0] = bufferBindingOne.ToRefresh();
bindingArray[1] = bufferBindingTwo.ToRefresh();
bufferPtrs[0] = bufferBindingOne.Buffer.Handle; bindingArray[2] = bufferBindingThree.ToRefresh();
bufferPtrs[1] = bufferBindingTwo.Buffer.Handle; bindingArray[3] = bufferBindingFour.ToRefresh();
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;
Refresh.Refresh_BindVertexBuffers( Refresh.Refresh_BindVertexBuffers(
Device.Handle, Device.Handle,
Handle, Handle,
firstBinding, firstBinding,
4, 4,
(IntPtr) bufferPtrs, bindingArray
(IntPtr) offsets
); );
} }
@ -817,13 +792,11 @@ namespace MoonWorks.Graphics
AssertGraphicsPipelineBound(); AssertGraphicsPipelineBound();
#endif #endif
var bufferPtrs = stackalloc IntPtr[bufferBindings.Length]; Refresh.BufferBinding* bufferBindingsArray = (Refresh.BufferBinding*) NativeMemory.Alloc((nuint) (Marshal.SizeOf<Refresh.BufferBinding>() * bufferBindings.Length));
var offsets = stackalloc ulong[bufferBindings.Length];
for (var i = 0; i < bufferBindings.Length; i += 1) for (var i = 0; i < bufferBindings.Length; i += 1)
{ {
bufferPtrs[i] = bufferBindings[i].Buffer.Handle; bufferBindingsArray[i] = bufferBindings[i].ToRefresh();
offsets[i] = bufferBindings[i].Offset;
} }
Refresh.Refresh_BindVertexBuffers( Refresh.Refresh_BindVertexBuffers(
@ -831,9 +804,10 @@ namespace MoonWorks.Graphics
Handle, Handle,
firstBinding, firstBinding,
(uint) bufferBindings.Length, (uint) bufferBindings.Length,
(IntPtr) bufferPtrs, bufferBindingsArray
(IntPtr) offsets
); );
NativeMemory.Free(bufferBindingsArray);
} }
/// <summary> /// <summary>
@ -843,9 +817,8 @@ namespace MoonWorks.Graphics
/// <param name="indexElementSize">The size in bytes of the index buffer elements.</param> /// <param name="indexElementSize">The size in bytes of the index buffer elements.</param>
/// <param name="offset">The offset index for the buffer.</param> /// <param name="offset">The offset index for the buffer.</param>
public void BindIndexBuffer( public void BindIndexBuffer(
GpuBuffer indexBuffer, BufferBinding bufferBinding,
IndexElementSize indexElementSize, IndexElementSize indexElementSize
uint offset = 0
) )
{ {
#if DEBUG #if DEBUG
@ -855,8 +828,7 @@ namespace MoonWorks.Graphics
Refresh.Refresh_BindIndexBuffer( Refresh.Refresh_BindIndexBuffer(
Device.Handle, Device.Handle,
Handle, Handle,
indexBuffer.Handle, bufferBinding.ToRefresh(),
offset,
(Refresh.IndexElementSize) indexElementSize (Refresh.IndexElementSize) indexElementSize
); );
} }
@ -876,17 +848,13 @@ namespace MoonWorks.Graphics
AssertTextureBindingUsageFlags(textureSamplerBinding.Texture); AssertTextureBindingUsageFlags(textureSamplerBinding.Texture);
#endif #endif
var texturePtrs = stackalloc IntPtr[1]; var bindingArray = stackalloc Refresh.TextureSamplerBinding[1];
var samplerPtrs = stackalloc IntPtr[1]; bindingArray[0] = textureSamplerBinding.ToRefresh();
texturePtrs[0] = textureSamplerBinding.Texture.Handle;
samplerPtrs[0] = textureSamplerBinding.Sampler.Handle;
Refresh.Refresh_BindVertexSamplers( Refresh.Refresh_BindVertexSamplers(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) texturePtrs, bindingArray
(IntPtr) samplerPtrs
); );
} }
@ -909,20 +877,14 @@ namespace MoonWorks.Graphics
AssertTextureBindingUsageFlags(textureSamplerBindingTwo.Texture); AssertTextureBindingUsageFlags(textureSamplerBindingTwo.Texture);
#endif #endif
var texturePtrs = stackalloc IntPtr[2]; var bindingArray = stackalloc Refresh.TextureSamplerBinding[2];
var samplerPtrs = stackalloc IntPtr[2]; bindingArray[0] = textureSamplerBindingOne.ToRefresh();
bindingArray[1] = textureSamplerBindingTwo.ToRefresh();
texturePtrs[0] = textureSamplerBindingOne.Texture.Handle;
texturePtrs[1] = textureSamplerBindingTwo.Texture.Handle;
samplerPtrs[0] = textureSamplerBindingOne.Sampler.Handle;
samplerPtrs[1] = textureSamplerBindingTwo.Sampler.Handle;
Refresh.Refresh_BindVertexSamplers( Refresh.Refresh_BindVertexSamplers(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) texturePtrs, bindingArray
(IntPtr) samplerPtrs
); );
} }
@ -949,22 +911,15 @@ namespace MoonWorks.Graphics
AssertTextureBindingUsageFlags(textureSamplerBindingThree.Texture); AssertTextureBindingUsageFlags(textureSamplerBindingThree.Texture);
#endif #endif
var texturePtrs = stackalloc IntPtr[3]; var bindingArray = stackalloc Refresh.TextureSamplerBinding[3];
var samplerPtrs = stackalloc IntPtr[3]; bindingArray[0] = textureSamplerBindingOne.ToRefresh();
bindingArray[1] = textureSamplerBindingTwo.ToRefresh();
texturePtrs[0] = textureSamplerBindingOne.Texture.Handle; bindingArray[2] = textureSamplerBindingThree.ToRefresh();
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( Refresh.Refresh_BindVertexSamplers(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) texturePtrs, bindingArray
(IntPtr) samplerPtrs
); );
} }
@ -995,24 +950,16 @@ namespace MoonWorks.Graphics
AssertTextureBindingUsageFlags(textureSamplerBindingFour.Texture); AssertTextureBindingUsageFlags(textureSamplerBindingFour.Texture);
#endif #endif
var texturePtrs = stackalloc IntPtr[4]; var bindingArray = stackalloc Refresh.TextureSamplerBinding[4];
var samplerPtrs = stackalloc IntPtr[4]; bindingArray[0] = textureSamplerBindingOne.ToRefresh();
bindingArray[1] = textureSamplerBindingTwo.ToRefresh();
texturePtrs[0] = textureSamplerBindingOne.Texture.Handle; bindingArray[2] = textureSamplerBindingThree.ToRefresh();
texturePtrs[1] = textureSamplerBindingTwo.Texture.Handle; bindingArray[3] = textureSamplerBindingFour.ToRefresh();
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( Refresh.Refresh_BindVertexSamplers(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) texturePtrs, bindingArray
(IntPtr) samplerPtrs
); );
} }
@ -1029,8 +976,7 @@ namespace MoonWorks.Graphics
AssertVertexSamplerCount(textureSamplerBindings.Length); AssertVertexSamplerCount(textureSamplerBindings.Length);
#endif #endif
var texturePtrs = stackalloc IntPtr[textureSamplerBindings.Length]; Refresh.TextureSamplerBinding* bindingsArray = (Refresh.TextureSamplerBinding*) NativeMemory.Alloc((nuint) (Marshal.SizeOf<Refresh.TextureSamplerBinding>() * textureSamplerBindings.Length));
var samplerPtrs = stackalloc IntPtr[textureSamplerBindings.Length];
for (var i = 0; i < textureSamplerBindings.Length; i += 1) for (var i = 0; i < textureSamplerBindings.Length; i += 1)
{ {
@ -1039,16 +985,16 @@ namespace MoonWorks.Graphics
AssertTextureBindingUsageFlags(textureSamplerBindings[i].Texture); AssertTextureBindingUsageFlags(textureSamplerBindings[i].Texture);
#endif #endif
texturePtrs[i] = textureSamplerBindings[i].Texture.Handle; bindingsArray[i] = textureSamplerBindings[i].ToRefresh();
samplerPtrs[i] = textureSamplerBindings[i].Sampler.Handle;
} }
Refresh.Refresh_BindVertexSamplers( Refresh.Refresh_BindVertexSamplers(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) texturePtrs, bindingsArray
(IntPtr) samplerPtrs
); );
NativeMemory.Free(bindingsArray);
} }
/// <summary> /// <summary>
@ -1066,17 +1012,13 @@ namespace MoonWorks.Graphics
AssertTextureBindingUsageFlags(textureSamplerBinding.Texture); AssertTextureBindingUsageFlags(textureSamplerBinding.Texture);
#endif #endif
var texturePtrs = stackalloc IntPtr[1]; var bindingArray = stackalloc Refresh.TextureSamplerBinding[1];
var samplerPtrs = stackalloc IntPtr[1]; bindingArray[0] = textureSamplerBinding.ToRefresh();
texturePtrs[0] = textureSamplerBinding.Texture.Handle;
samplerPtrs[0] = textureSamplerBinding.Sampler.Handle;
Refresh.Refresh_BindFragmentSamplers( Refresh.Refresh_BindFragmentSamplers(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) texturePtrs, bindingArray
(IntPtr) samplerPtrs
); );
} }
@ -1099,20 +1041,14 @@ namespace MoonWorks.Graphics
AssertTextureBindingUsageFlags(textureSamplerBindingTwo.Texture); AssertTextureBindingUsageFlags(textureSamplerBindingTwo.Texture);
#endif #endif
var texturePtrs = stackalloc IntPtr[2]; var bindingArray = stackalloc Refresh.TextureSamplerBinding[2];
var samplerPtrs = stackalloc IntPtr[2]; bindingArray[0] = textureSamplerBindingOne.ToRefresh();
bindingArray[1] = textureSamplerBindingTwo.ToRefresh();
texturePtrs[0] = textureSamplerBindingOne.Texture.Handle;
texturePtrs[1] = textureSamplerBindingTwo.Texture.Handle;
samplerPtrs[0] = textureSamplerBindingOne.Sampler.Handle;
samplerPtrs[1] = textureSamplerBindingTwo.Sampler.Handle;
Refresh.Refresh_BindFragmentSamplers( Refresh.Refresh_BindFragmentSamplers(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) texturePtrs, bindingArray
(IntPtr) samplerPtrs
); );
} }
@ -1139,22 +1075,15 @@ namespace MoonWorks.Graphics
AssertTextureBindingUsageFlags(textureSamplerBindingThree.Texture); AssertTextureBindingUsageFlags(textureSamplerBindingThree.Texture);
#endif #endif
var texturePtrs = stackalloc IntPtr[3]; var bindingArray = stackalloc Refresh.TextureSamplerBinding[3];
var samplerPtrs = stackalloc IntPtr[3]; bindingArray[0] = textureSamplerBindingOne.ToRefresh();
bindingArray[1] = textureSamplerBindingTwo.ToRefresh();
texturePtrs[0] = textureSamplerBindingOne.Texture.Handle; bindingArray[2] = textureSamplerBindingThree.ToRefresh();
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( Refresh.Refresh_BindFragmentSamplers(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) texturePtrs, bindingArray
(IntPtr) samplerPtrs
); );
} }
@ -1185,24 +1114,16 @@ namespace MoonWorks.Graphics
AssertTextureBindingUsageFlags(textureSamplerBindingFour.Texture); AssertTextureBindingUsageFlags(textureSamplerBindingFour.Texture);
#endif #endif
var texturePtrs = stackalloc IntPtr[4]; var bindingArray = stackalloc Refresh.TextureSamplerBinding[4];
var samplerPtrs = stackalloc IntPtr[4]; bindingArray[0] = textureSamplerBindingOne.ToRefresh();
bindingArray[1] = textureSamplerBindingTwo.ToRefresh();
texturePtrs[0] = textureSamplerBindingOne.Texture.Handle; bindingArray[2] = textureSamplerBindingThree.ToRefresh();
texturePtrs[1] = textureSamplerBindingTwo.Texture.Handle; bindingArray[3] = textureSamplerBindingFour.ToRefresh();
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( Refresh.Refresh_BindFragmentSamplers(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) texturePtrs, bindingArray
(IntPtr) samplerPtrs
); );
} }
@ -1219,8 +1140,7 @@ namespace MoonWorks.Graphics
AssertFragmentSamplerCount(textureSamplerBindings.Length); AssertFragmentSamplerCount(textureSamplerBindings.Length);
#endif #endif
var texturePtrs = stackalloc IntPtr[textureSamplerBindings.Length]; Refresh.TextureSamplerBinding* bindingArray = (Refresh.TextureSamplerBinding*) NativeMemory.Alloc((nuint) (Marshal.SizeOf<Refresh.TextureSamplerBinding>() * textureSamplerBindings.Length));
var samplerPtrs = stackalloc IntPtr[textureSamplerBindings.Length];
for (var i = 0; i < textureSamplerBindings.Length; i += 1) for (var i = 0; i < textureSamplerBindings.Length; i += 1)
{ {
@ -1229,16 +1149,16 @@ namespace MoonWorks.Graphics
AssertTextureBindingUsageFlags(textureSamplerBindings[i].Texture); AssertTextureBindingUsageFlags(textureSamplerBindings[i].Texture);
#endif #endif
texturePtrs[i] = textureSamplerBindings[i].Texture.Handle; bindingArray[i] = textureSamplerBindings[i].ToRefresh();
samplerPtrs[i] = textureSamplerBindings[i].Sampler.Handle;
} }
Refresh.Refresh_BindFragmentSamplers( Refresh.Refresh_BindFragmentSamplers(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) texturePtrs, bindingArray
(IntPtr) samplerPtrs
); );
NativeMemory.Free(bindingArray);
} }
/// <summary> /// <summary>
@ -1466,16 +1386,20 @@ namespace MoonWorks.Graphics
/// ///
/// This operation cannot be performed inside any pass. /// This operation cannot be performed inside any pass.
/// </summary> /// </summary>
/// <param name="writeOption">Specifies data dependency behavior.</param>
public void Blit( public void Blit(
Texture source, TextureSlice source,
Texture destination, TextureSlice destination,
Filter filter Filter filter,
WriteOptions writeOption
) { ) {
var sampler = filter == Filter.Linear ? Device.LinearSampler : Device.PointSampler; var sampler = filter == Filter.Linear ? Device.LinearSampler : Device.PointSampler;
BeginRenderPass(new ColorAttachmentInfo(destination)); // FIXME: this will break with non-2D textures
// FIXME: this should take a TextureRegion
BeginRenderPass(new ColorAttachmentInfo(destination, writeOption));
BindGraphicsPipeline(Device.BlitPipeline); BindGraphicsPipeline(Device.BlitPipeline);
BindFragmentSamplers(new TextureSamplerBinding(source, sampler)); BindFragmentSamplers(new TextureSamplerBinding(source.Texture, sampler));
DrawPrimitives(0, 2); DrawPrimitives(0, 2);
EndRenderPass(); EndRenderPass();
} }
@ -1520,9 +1444,8 @@ namespace MoonWorks.Graphics
/// <summary> /// <summary>
/// Binds a buffer to be used in the compute shader. /// Binds a buffer to be used in the compute shader.
/// </summary> /// </summary>
/// <param name="buffer">A buffer to bind.</param>
public unsafe void BindComputeBuffers( public unsafe void BindComputeBuffers(
GpuBuffer buffer ComputeBufferBinding binding
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted(); AssertNotSubmitted();
@ -1531,24 +1454,22 @@ namespace MoonWorks.Graphics
AssertComputeBufferCount(1); AssertComputeBufferCount(1);
#endif #endif
var bufferPtrs = stackalloc IntPtr[1]; var bindingArray = stackalloc Refresh.ComputeBufferBinding[1];
bufferPtrs[0] = buffer.Handle; bindingArray[0] = binding.ToRefresh();
Refresh.Refresh_BindComputeBuffers( Refresh.Refresh_BindComputeBuffers(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) bufferPtrs bindingArray
); );
} }
/// <summary> /// <summary>
/// Binds buffers to be used in the compute shader. /// Binds buffers to be used in the compute shader.
/// </summary> /// </summary>
/// <param name="bufferOne">A buffer to bind.</param>
/// <param name="bufferTwo">A buffer to bind.</param>
public unsafe void BindComputeBuffers( public unsafe void BindComputeBuffers(
GpuBuffer bufferOne, ComputeBufferBinding bindingOne,
GpuBuffer bufferTwo ComputeBufferBinding bindingTwo
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted(); AssertNotSubmitted();
@ -1557,27 +1478,24 @@ namespace MoonWorks.Graphics
AssertComputeBufferCount(2); AssertComputeBufferCount(2);
#endif #endif
var bufferPtrs = stackalloc IntPtr[2]; var bindingArray = stackalloc Refresh.ComputeBufferBinding[2];
bufferPtrs[0] = bufferOne.Handle; bindingArray[0] = bindingOne.ToRefresh();
bufferPtrs[1] = bufferTwo.Handle; bindingArray[1] = bindingTwo.ToRefresh();
Refresh.Refresh_BindComputeBuffers( Refresh.Refresh_BindComputeBuffers(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) bufferPtrs bindingArray
); );
} }
/// <summary> /// <summary>
/// Binds buffers to be used in the compute shader. /// Binds buffers to be used in the compute shader.
/// </summary> /// </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( public unsafe void BindComputeBuffers(
GpuBuffer bufferOne, ComputeBufferBinding bindingOne,
GpuBuffer bufferTwo, ComputeBufferBinding bindingTwo,
GpuBuffer bufferThree ComputeBufferBinding bindingThree
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted(); AssertNotSubmitted();
@ -1586,30 +1504,26 @@ namespace MoonWorks.Graphics
AssertComputeBufferCount(3); AssertComputeBufferCount(3);
#endif #endif
var bufferPtrs = stackalloc IntPtr[3]; var bindingArray = stackalloc Refresh.ComputeBufferBinding[3];
bufferPtrs[0] = bufferOne.Handle; bindingArray[0] = bindingOne.ToRefresh();
bufferPtrs[1] = bufferTwo.Handle; bindingArray[1] = bindingTwo.ToRefresh();
bufferPtrs[2] = bufferThree.Handle; bindingArray[2] = bindingThree.ToRefresh();
Refresh.Refresh_BindComputeBuffers( Refresh.Refresh_BindComputeBuffers(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) bufferPtrs bindingArray
); );
} }
/// <summary> /// <summary>
/// Binds buffers to be used in the compute shader. /// Binds buffers to be used in the compute shader.
/// </summary> /// </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( public unsafe void BindComputeBuffers(
GpuBuffer bufferOne, ComputeBufferBinding bindingOne,
GpuBuffer bufferTwo, ComputeBufferBinding bindingTwo,
GpuBuffer bufferThree, ComputeBufferBinding bindingThree,
GpuBuffer bufferFour ComputeBufferBinding bindingFour
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted(); AssertNotSubmitted();
@ -1618,16 +1532,16 @@ namespace MoonWorks.Graphics
AssertComputeBufferCount(4); AssertComputeBufferCount(4);
#endif #endif
var bufferPtrs = stackalloc IntPtr[4]; var bindingArray = stackalloc Refresh.ComputeBufferBinding[4];
bufferPtrs[0] = bufferOne.Handle; bindingArray[0] = bindingOne.ToRefresh();
bufferPtrs[1] = bufferTwo.Handle; bindingArray[1] = bindingTwo.ToRefresh();
bufferPtrs[2] = bufferThree.Handle; bindingArray[2] = bindingThree.ToRefresh();
bufferPtrs[3] = bufferFour.Handle; bindingArray[3] = bindingFour.ToRefresh();
Refresh.Refresh_BindComputeBuffers( Refresh.Refresh_BindComputeBuffers(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) bufferPtrs bindingArray
); );
} }
@ -1636,35 +1550,38 @@ namespace MoonWorks.Graphics
/// </summary> /// </summary>
/// <param name="buffers">A Span of buffers to bind.</param> /// <param name="buffers">A Span of buffers to bind.</param>
public unsafe void BindComputeBuffers( public unsafe void BindComputeBuffers(
in Span<GpuBuffer> buffers in Span<ComputeBufferBinding> bindings
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted(); AssertNotSubmitted();
AssertInComputePass("Cannot bind compute buffers outside of compute pass!"); AssertInComputePass("Cannot bind compute buffers outside of compute pass!");
AssertComputePipelineBound(); AssertComputePipelineBound();
AssertComputeBufferCount(buffers.Length); AssertComputeBufferCount(bindings.Length);
#endif #endif
var bufferPtrs = stackalloc IntPtr[buffers.Length]; Refresh.ComputeBufferBinding* bindingArray = (Refresh.ComputeBufferBinding*) NativeMemory.Alloc(
(nuint) (Marshal.SizeOf<ComputeBufferBinding>() * bindings.Length)
);
for (var i = 0; i < buffers.Length; i += 1) for (var i = 0; i < bindings.Length; i += 1)
{ {
bufferPtrs[i] = buffers[i].Handle; bindingArray[i] = bindings[i].ToRefresh();
} }
Refresh.Refresh_BindComputeBuffers( Refresh.Refresh_BindComputeBuffers(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) bufferPtrs bindingArray
); );
NativeMemory.Free(bindingArray);
} }
/// <summary> /// <summary>
/// Binds a texture to be used in the compute shader. /// Binds a texture slice to be used in the compute shader.
/// </summary> /// </summary>
/// <param name="slice">A texture slice to bind.</param>
public unsafe void BindComputeTextures( public unsafe void BindComputeTextures(
TextureSlice slice ComputeTextureBinding binding
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted(); AssertNotSubmitted();
@ -1673,24 +1590,22 @@ namespace MoonWorks.Graphics
AssertComputeTextureCount(1); AssertComputeTextureCount(1);
#endif #endif
var textureSlicePtrs = stackalloc Refresh.TextureSlice[1]; var bindingArray = stackalloc Refresh.ComputeTextureBinding[1];
textureSlicePtrs[0] = slice.ToRefreshTextureSlice(); bindingArray[0] = binding.ToRefresh();
Refresh.Refresh_BindComputeTextures( Refresh.Refresh_BindComputeTextures(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) textureSlicePtrs bindingArray
); );
} }
/// <summary> /// <summary>
/// Binds textures to be used in the compute shader. /// Binds textures to be used in the compute shader.
/// </summary> /// </summary>
/// <param name="sliceOne">A texture-level pair to bind.</param>
/// <param name="sliceTwo">A texture-level pair to bind.</param>
public unsafe void BindComputeTextures( public unsafe void BindComputeTextures(
TextureSlice sliceOne, ComputeTextureBinding bindingOne,
TextureSlice sliceTwo ComputeTextureBinding bindingTwo
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted(); AssertNotSubmitted();
@ -1699,27 +1614,24 @@ namespace MoonWorks.Graphics
AssertComputeTextureCount(2); AssertComputeTextureCount(2);
#endif #endif
var textureSlicePtrs = stackalloc Refresh.TextureSlice[2]; var bindingArray = stackalloc Refresh.ComputeTextureBinding[2];
textureSlicePtrs[0] = sliceOne.ToRefreshTextureSlice(); bindingArray[0] = bindingOne.ToRefresh();
textureSlicePtrs[1] = sliceTwo.ToRefreshTextureSlice(); bindingArray[1] = bindingTwo.ToRefresh();
Refresh.Refresh_BindComputeTextures( Refresh.Refresh_BindComputeTextures(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) textureSlicePtrs bindingArray
); );
} }
/// <summary> /// <summary>
/// Binds textures to be used in the compute shader. /// Binds textures to be used in the compute shader.
/// </summary> /// </summary>
/// <param name="sliceOne">A texture-level pair to bind.</param>
/// <param name="sliceTwo">A texture-level pair to bind.</param>
/// <param name="sliceThree">A texture-level pair to bind.</param>
public unsafe void BindComputeTextures( public unsafe void BindComputeTextures(
TextureSlice sliceOne, ComputeTextureBinding bindingOne,
TextureSlice sliceTwo, ComputeTextureBinding bindingTwo,
TextureSlice sliceThree ComputeTextureBinding bindingThree
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted(); AssertNotSubmitted();
@ -1728,30 +1640,26 @@ namespace MoonWorks.Graphics
AssertComputeTextureCount(3); AssertComputeTextureCount(3);
#endif #endif
var textureSlicePtrs = stackalloc Refresh.TextureSlice[3]; var bindingArray = stackalloc Refresh.ComputeTextureBinding[3];
textureSlicePtrs[0] = sliceOne.ToRefreshTextureSlice(); bindingArray[0] = bindingOne.ToRefresh();
textureSlicePtrs[1] = sliceTwo.ToRefreshTextureSlice(); bindingArray[1] = bindingTwo.ToRefresh();
textureSlicePtrs[2] = sliceThree.ToRefreshTextureSlice(); bindingArray[2] = bindingThree.ToRefresh();
Refresh.Refresh_BindComputeTextures( Refresh.Refresh_BindComputeTextures(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) textureSlicePtrs bindingArray
); );
} }
/// <summary> /// <summary>
/// Binds textures to be used in the compute shader. /// Binds textures to be used in the compute shader.
/// </summary> /// </summary>
/// <param name="sliceOne">A texture-level pair to bind.</param>
/// <param name="sliceTwo">A texture-level pair to bind.</param>
/// <param name="sliceThree">A texture-level pair to bind.</param>
/// <param name="sliceFour">A texture-level pair to bind.</param>
public unsafe void BindComputeTextures( public unsafe void BindComputeTextures(
TextureSlice sliceOne, ComputeTextureBinding bindingOne,
TextureSlice sliceTwo, ComputeTextureBinding bindingTwo,
TextureSlice sliceThree, ComputeTextureBinding bindingThree,
TextureSlice sliceFour ComputeTextureBinding bindingFour
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted(); AssertNotSubmitted();
@ -1760,49 +1668,48 @@ namespace MoonWorks.Graphics
AssertComputeTextureCount(4); AssertComputeTextureCount(4);
#endif #endif
var textureSlicePtrs = stackalloc Refresh.TextureSlice[4]; var textureSlicePtrs = stackalloc Refresh.ComputeTextureBinding[4];
textureSlicePtrs[0] = sliceOne.ToRefreshTextureSlice(); textureSlicePtrs[0] = bindingOne.ToRefresh();
textureSlicePtrs[1] = sliceTwo.ToRefreshTextureSlice(); textureSlicePtrs[1] = bindingTwo.ToRefresh();
textureSlicePtrs[2] = sliceThree.ToRefreshTextureSlice(); textureSlicePtrs[2] = bindingThree.ToRefresh();
textureSlicePtrs[3] = sliceFour.ToRefreshTextureSlice(); textureSlicePtrs[3] = bindingFour.ToRefresh();
Refresh.Refresh_BindComputeTextures( Refresh.Refresh_BindComputeTextures(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) textureSlicePtrs textureSlicePtrs
); );
} }
/// <summary> /// <summary>
/// Binds textures to be used in the compute shader. /// Binds textures to be used in the compute shader.
/// </summary> /// </summary>
/// <param name="slices">A set of texture-level pairs to bind.</param>
public unsafe void BindComputeTextures( public unsafe void BindComputeTextures(
in Span<TextureSlice> slices in Span<ComputeTextureBinding> bindings
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted(); AssertNotSubmitted();
AssertInComputePass("Cannot bind compute textures outside of compute pass!"); AssertInComputePass("Cannot bind compute textures outside of compute pass!");
AssertComputePipelineBound(); AssertComputePipelineBound();
AssertComputeTextureCount(slices.Length); AssertComputeTextureCount(bindings.Length);
#endif #endif
Refresh.TextureSlice* textureSlicePtrs = (Refresh.TextureSlice*) NativeMemory.Alloc( Refresh.ComputeTextureBinding* bindingArray = (Refresh.ComputeTextureBinding*) NativeMemory.Alloc(
(nuint) (Marshal.SizeOf<Refresh.TextureSlice>() * slices.Length) (nuint) (Marshal.SizeOf<Refresh.TextureSlice>() * bindings.Length)
); );
for (var i = 0; i < slices.Length; i += 1) for (var i = 0; i < bindings.Length; i += 1)
{ {
textureSlicePtrs[i] = slices[i].ToRefreshTextureSlice(); bindingArray[i] = bindings[i].ToRefresh();
} }
Refresh.Refresh_BindComputeTextures( Refresh.Refresh_BindComputeTextures(
Device.Handle, Device.Handle,
Handle, Handle,
(IntPtr) textureSlicePtrs bindingArray
); );
NativeMemory.Free(textureSlicePtrs); NativeMemory.Free(bindingArray);
} }
/// <summary> /// <summary>
@ -1916,6 +1823,7 @@ namespace MoonWorks.Graphics
); );
} }
/// <summary> /// <summary>
/// Uploads data from a TransferBuffer to a TextureSlice. /// Uploads data from a TransferBuffer to a TextureSlice.
/// This copy occurs on the GPU timeline. /// This copy occurs on the GPU timeline.
@ -1925,11 +1833,12 @@ namespace MoonWorks.Graphics
/// ///
/// You MAY assume that the copy has finished for subsequent commands. /// You MAY assume that the copy has finished for subsequent commands.
/// </summary> /// </summary>
/// <param name="writeOption">Specifies data dependency behavior.</param>
public void UploadToTexture( public void UploadToTexture(
TransferBuffer transferBuffer, TransferBuffer transferBuffer,
in TextureRegion textureRegion, in TextureRegion textureRegion,
in BufferImageCopy copyParams, in BufferImageCopy copyParams,
CopyOptions option WriteOptions writeOption
) )
{ {
#if DEBUG #if DEBUG
@ -1944,7 +1853,7 @@ namespace MoonWorks.Graphics
transferBuffer.Handle, transferBuffer.Handle,
textureRegion.ToRefreshTextureRegion(), textureRegion.ToRefreshTextureRegion(),
copyParams.ToRefresh(), copyParams.ToRefresh(),
(Refresh.CopyOptions) option (Refresh.WriteOptions) writeOption
); );
} }
@ -1954,13 +1863,13 @@ namespace MoonWorks.Graphics
public void UploadToTexture( public void UploadToTexture(
TransferBuffer transferBuffer, TransferBuffer transferBuffer,
Texture texture, Texture texture,
CopyOptions option WriteOptions writeOption
) { ) {
UploadToTexture( UploadToTexture(
transferBuffer, transferBuffer,
new TextureRegion(texture), new TextureRegion(texture),
new BufferImageCopy(0, 0, 0), new BufferImageCopy(0, 0, 0),
option writeOption
); );
} }
@ -1977,7 +1886,7 @@ namespace MoonWorks.Graphics
TransferBuffer transferBuffer, TransferBuffer transferBuffer,
GpuBuffer gpuBuffer, GpuBuffer gpuBuffer,
in BufferCopy copyParams, in BufferCopy copyParams,
CopyOptions option WriteOptions option
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted(); AssertNotSubmitted();
@ -1992,7 +1901,7 @@ namespace MoonWorks.Graphics
transferBuffer.Handle, transferBuffer.Handle,
gpuBuffer.Handle, gpuBuffer.Handle,
copyParams.ToRefresh(), copyParams.ToRefresh(),
(Refresh.CopyOptions) option (Refresh.WriteOptions) option
); );
} }
@ -2002,7 +1911,7 @@ namespace MoonWorks.Graphics
public void UploadToBuffer( public void UploadToBuffer(
TransferBuffer transferBuffer, TransferBuffer transferBuffer,
GpuBuffer gpuBuffer, GpuBuffer gpuBuffer,
CopyOptions option WriteOptions option
) { ) {
UploadToBuffer( UploadToBuffer(
transferBuffer, transferBuffer,
@ -2021,7 +1930,7 @@ namespace MoonWorks.Graphics
uint sourceStartElement, uint sourceStartElement,
uint destinationStartElement, uint destinationStartElement,
uint numElements, uint numElements,
CopyOptions option WriteOptions option
) where T : unmanaged ) where T : unmanaged
{ {
var elementSize = Marshal.SizeOf<T>(); var elementSize = Marshal.SizeOf<T>();
@ -2145,7 +2054,7 @@ namespace MoonWorks.Graphics
public void CopyTextureToTexture( public void CopyTextureToTexture(
in TextureRegion source, in TextureRegion source,
in TextureRegion destination, in TextureRegion destination,
CopyOptions option WriteOptions option
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted(); AssertNotSubmitted();
@ -2158,7 +2067,7 @@ namespace MoonWorks.Graphics
Handle, Handle,
source.ToRefreshTextureRegion(), source.ToRefreshTextureRegion(),
destination.ToRefreshTextureRegion(), destination.ToRefreshTextureRegion(),
(Refresh.CopyOptions) option (Refresh.WriteOptions) option
); );
} }
@ -2169,7 +2078,7 @@ namespace MoonWorks.Graphics
public void CopyTextureToTexture( public void CopyTextureToTexture(
Texture source, Texture source,
Texture destination, Texture destination,
CopyOptions option WriteOptions option
) { ) {
CopyTextureToTexture( CopyTextureToTexture(
new TextureRegion(source), new TextureRegion(source),
@ -2188,7 +2097,7 @@ namespace MoonWorks.Graphics
in TextureRegion textureRegion, in TextureRegion textureRegion,
GpuBuffer buffer, GpuBuffer buffer,
in BufferImageCopy copyParams, in BufferImageCopy copyParams,
CopyOptions option WriteOptions option
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted(); AssertNotSubmitted();
@ -2202,7 +2111,7 @@ namespace MoonWorks.Graphics
textureRegion.ToRefreshTextureRegion(), textureRegion.ToRefreshTextureRegion(),
buffer.Handle, buffer.Handle,
copyParams.ToRefresh(), copyParams.ToRefresh(),
(Refresh.CopyOptions) option (Refresh.WriteOptions) option
); );
} }
@ -2212,7 +2121,7 @@ namespace MoonWorks.Graphics
public void CopyTextureToBuffer( public void CopyTextureToBuffer(
Texture texture, Texture texture,
GpuBuffer buffer, GpuBuffer buffer,
CopyOptions option WriteOptions option
) { ) {
CopyTextureToBuffer( CopyTextureToBuffer(
new TextureRegion(texture), new TextureRegion(texture),
@ -2232,7 +2141,7 @@ namespace MoonWorks.Graphics
GpuBuffer gpuBuffer, GpuBuffer gpuBuffer,
in TextureRegion textureRegion, in TextureRegion textureRegion,
in BufferImageCopy copyParams, in BufferImageCopy copyParams,
CopyOptions option WriteOptions option
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted(); AssertNotSubmitted();
@ -2246,7 +2155,7 @@ namespace MoonWorks.Graphics
gpuBuffer.Handle, gpuBuffer.Handle,
textureRegion.ToRefreshTextureRegion(), textureRegion.ToRefreshTextureRegion(),
copyParams.ToRefresh(), copyParams.ToRefresh(),
(Refresh.CopyOptions) option (Refresh.WriteOptions) option
); );
} }
@ -2256,7 +2165,7 @@ namespace MoonWorks.Graphics
public void CopyBufferToTexture( public void CopyBufferToTexture(
GpuBuffer buffer, GpuBuffer buffer,
Texture texture, Texture texture,
CopyOptions option WriteOptions option
) { ) {
CopyBufferToTexture( CopyBufferToTexture(
buffer, buffer,
@ -2276,7 +2185,7 @@ namespace MoonWorks.Graphics
GpuBuffer source, GpuBuffer source,
GpuBuffer destination, GpuBuffer destination,
in BufferCopy copyParams, in BufferCopy copyParams,
CopyOptions option WriteOptions option
) { ) {
#if DEBUG #if DEBUG
AssertNotSubmitted(); AssertNotSubmitted();
@ -2291,7 +2200,7 @@ namespace MoonWorks.Graphics
source.Handle, source.Handle,
destination.Handle, destination.Handle,
copyParams.ToRefresh(), copyParams.ToRefresh(),
(Refresh.CopyOptions) option (Refresh.WriteOptions) option
); );
} }
@ -2301,7 +2210,7 @@ namespace MoonWorks.Graphics
public void CopyBufferToBuffer( public void CopyBufferToBuffer(
GpuBuffer source, GpuBuffer source,
GpuBuffer destination, GpuBuffer destination,
CopyOptions option WriteOptions option
) { ) {
CopyBufferToBuffer( CopyBufferToBuffer(
source, source,

View File

@ -63,7 +63,7 @@ namespace MoonWorks.Graphics.Font
commandBuffer.UploadToTexture( commandBuffer.UploadToTexture(
transferBuffer, transferBuffer,
texture, texture,
CopyOptions.SafeOverwrite WriteOptions.SafeOverwrite
); );
commandBuffer.EndCopyPass(); commandBuffer.EndCopyPass();

View File

@ -127,8 +127,8 @@ namespace MoonWorks.Graphics.Font
TransferBuffer.SetData(vertexSpan, TransferOptions.Discard); TransferBuffer.SetData(vertexSpan, TransferOptions.Discard);
TransferBuffer.SetData(indexSpan, (uint) vertexSpan.Length, TransferOptions.Overwrite); TransferBuffer.SetData(indexSpan, (uint) vertexSpan.Length, TransferOptions.Overwrite);
commandBuffer.UploadToBuffer(TransferBuffer, VertexBuffer, new BufferCopy(0, 0, (uint) vertexSpan.Length), CopyOptions.SafeDiscard); commandBuffer.UploadToBuffer(TransferBuffer, VertexBuffer, new BufferCopy(0, 0, (uint) vertexSpan.Length), WriteOptions.SafeDiscard);
commandBuffer.UploadToBuffer(TransferBuffer, IndexBuffer, new BufferCopy((uint) vertexSpan.Length, 0, (uint) indexSpan.Length), CopyOptions.SafeDiscard); commandBuffer.UploadToBuffer(TransferBuffer, IndexBuffer, new BufferCopy((uint) vertexSpan.Length, 0, (uint) indexSpan.Length), WriteOptions.SafeDiscard);
} }
PrimitiveCount = vertexCount / 2; PrimitiveCount = vertexCount / 2;

View File

@ -303,7 +303,7 @@ namespace MoonWorks.Graphics
Overwrite Overwrite
} }
public enum CopyOptions public enum WriteOptions
{ {
SafeDiscard, SafeDiscard,
SafeOverwrite SafeOverwrite

View File

@ -174,29 +174,78 @@ namespace MoonWorks.Graphics
} }
} }
/// <summary>
/// Determines how a color texture will be read/written in a render pass.
/// </summary>
public struct ColorAttachmentInfo public struct ColorAttachmentInfo
{ {
public TextureSlice TextureSlice; public TextureSlice TextureSlice;
/// <summary>
/// If LoadOp is set to Clear, the texture slice will be cleared to this color.
/// </summary>
public Color ClearColor; public Color ClearColor;
/// <summary>
/// Determines what is done with the texture slice memory
/// at the beginning of the render pass. <br/>
///
/// Load:
/// Loads the data currently in the texture slice. <br/>
///
/// Clear:
/// Clears the texture slice to a single color. <br/>
///
/// DontCare:
/// The driver will do whatever it wants with the texture slice data.
/// This is a good option if you know that every single pixel will be written in the render pass.
/// </summary>
public LoadOp LoadOp; public LoadOp LoadOp;
/// <summary>
/// Determines what is done with the texture slice memory
/// at the end of the render pass. <br/>
///
/// Store:
/// Stores the results of the render pass in the texture slice memory. <br/>
///
/// DontCare:
/// The driver will do whatever it wants with the texture slice memory.
/// </summary>
public StoreOp StoreOp; public StoreOp StoreOp;
public bool SafeDiscard;
/// <summary>
/// Specifies data dependency behavior. This option is ignored if LoadOp is Load. <br/>
///
/// SafeDiscard:
/// If this texture slice has been used in commands that have not completed,
/// this option will prevent a dependency on those commands
/// at the cost of increased memory usage.
/// You may NOT assume that any of the previous texture (not slice!) data is retained.
/// If the texture slice was not in use, this is equivalent to SafeOverwrite.
/// This is a good option to prevent stalls when frequently reusing a texture slice in rendering. <br/>
///
/// SafeOverwrite:
/// Overwrites the data safely using a GPU memory barrier.
/// </summary>
public WriteOptions WriteOption;
public ColorAttachmentInfo( public ColorAttachmentInfo(
TextureSlice textureSlice, TextureSlice textureSlice,
WriteOptions writeOption,
Color clearColor, Color clearColor,
bool safeDiscard = true,
StoreOp storeOp = StoreOp.Store StoreOp storeOp = StoreOp.Store
) { ) {
TextureSlice = textureSlice; TextureSlice = textureSlice;
ClearColor = clearColor; ClearColor = clearColor;
LoadOp = LoadOp.Clear; LoadOp = LoadOp.Clear;
StoreOp = storeOp; StoreOp = storeOp;
SafeDiscard = safeDiscard; WriteOption = writeOption;
} }
public ColorAttachmentInfo( public ColorAttachmentInfo(
TextureSlice textureSlice, TextureSlice textureSlice,
WriteOptions writeOption,
LoadOp loadOp = LoadOp.DontCare, LoadOp loadOp = LoadOp.DontCare,
StoreOp storeOp = StoreOp.Store StoreOp storeOp = StoreOp.Store
) { ) {
@ -204,6 +253,7 @@ namespace MoonWorks.Graphics
ClearColor = Color.White; ClearColor = Color.White;
LoadOp = loadOp; LoadOp = loadOp;
StoreOp = storeOp; StoreOp = storeOp;
WriteOption = writeOption;
} }
public Refresh.ColorAttachmentInfo ToRefresh() public Refresh.ColorAttachmentInfo ToRefresh()
@ -220,27 +270,104 @@ namespace MoonWorks.Graphics
}, },
loadOp = (Refresh.LoadOp) LoadOp, loadOp = (Refresh.LoadOp) LoadOp,
storeOp = (Refresh.StoreOp) StoreOp, storeOp = (Refresh.StoreOp) StoreOp,
safeDiscard = Conversions.BoolToByte(SafeDiscard) writeOption = (Refresh.WriteOptions) WriteOption
}; };
} }
} }
/// <summary>
/// Determines how a depth/stencil texture will be read/written in a render pass.
/// </summary>
public struct DepthStencilAttachmentInfo public struct DepthStencilAttachmentInfo
{ {
public TextureSlice TextureSlice; public TextureSlice TextureSlice;
/// <summary>
/// If LoadOp is set to Clear, the texture slice depth will be cleared to this depth value. <br/>
/// If StencilLoadOp is set to Clear, the texture slice stencil value will be cleared to this stencil value.
/// </summary>
public DepthStencilValue DepthStencilClearValue; public DepthStencilValue DepthStencilClearValue;
/// <summary>
/// Determines what is done with the texture slice depth values
/// at the beginning of the render pass. <br/>
///
/// Load:
/// Loads the data currently in the texture slice. <br/>
///
/// Clear:
/// Clears the texture slice to a single depth value. <br/>
///
/// DontCare:
/// The driver will do whatever it wants with the texture slice data.
/// This is a good option if you know that every single pixel will be written in the render pass.
/// </summary>
public LoadOp LoadOp; public LoadOp LoadOp;
/// <summary>
/// Determines what is done with the texture slice depth values
/// at the end of the render pass. <br/>
///
/// Store:
/// Stores the results of the render pass in the texture slice memory. <br/>
///
/// DontCare:
/// The driver will do whatever it wants with the texture slice memory.
/// This is usually a good option for depth textures that don't need to be reused.
/// </summary>
public StoreOp StoreOp; public StoreOp StoreOp;
/// <summary>
/// Determines what is done with the texture slice stencil values
/// at the beginning of the render pass. <br/>
///
/// Load:
/// Loads the data currently in the texture slice. <br/>
///
/// Clear:
/// Clears the texture slice to a single stencil value. <br/>
///
/// DontCare:
/// The driver will do whatever it wants with the texture slice data.
/// This is a good option if you know that every single pixel will be written in the render pass.
/// </summary>
public LoadOp StencilLoadOp; public LoadOp StencilLoadOp;
/// <summary>
/// Determines what is done with the texture slice stencil values
/// at the end of the render pass. <br/>
///
/// Store:
/// Stores the results of the render pass in the texture slice memory. <br/>
///
/// DontCare:
/// The driver will do whatever it wants with the texture slice memory.
/// This is usually a good option for stencil textures that don't need to be reused.
/// </summary>
public StoreOp StencilStoreOp; public StoreOp StencilStoreOp;
public bool SafeDiscard;
/// <summary>
/// Specifies data dependency behavior. This option is ignored if LoadOp or StencilLoadOp is Load. <br/>
///
/// SafeDiscard:
/// If this texture slice has been used in commands that have not completed,
/// this option will prevent a dependency on those commands
/// at the cost of increased memory usage.
/// You may NOT assume that any of the previous texture (not slice!) data is retained.
/// If the texture slice was not in use, this is equivalent to SafeOverwrite.
/// This is a good option to prevent stalls when frequently reusing a texture slice in rendering. <br/>
///
/// SafeOverwrite:
/// Overwrites the data safely using a GPU memory barrier.
/// </summary>
public WriteOptions WriteOption;
public DepthStencilAttachmentInfo( public DepthStencilAttachmentInfo(
TextureSlice textureSlice, TextureSlice textureSlice,
WriteOptions writeOption,
DepthStencilValue clearValue, DepthStencilValue clearValue,
bool safeDiscard = true, StoreOp depthStoreOp = StoreOp.DontCare,
StoreOp depthStoreOp = StoreOp.Store, StoreOp stencilStoreOp = StoreOp.DontCare
StoreOp stencilStoreOp = StoreOp.Store
){ ){
TextureSlice = textureSlice; TextureSlice = textureSlice;
DepthStencilClearValue = clearValue; DepthStencilClearValue = clearValue;
@ -248,15 +375,16 @@ namespace MoonWorks.Graphics
StoreOp = depthStoreOp; StoreOp = depthStoreOp;
StencilLoadOp = LoadOp.Clear; StencilLoadOp = LoadOp.Clear;
StencilStoreOp = stencilStoreOp; StencilStoreOp = stencilStoreOp;
SafeDiscard = safeDiscard; WriteOption = writeOption;
} }
public DepthStencilAttachmentInfo( public DepthStencilAttachmentInfo(
TextureSlice textureSlice, TextureSlice textureSlice,
WriteOptions writeOption,
LoadOp loadOp = LoadOp.DontCare, LoadOp loadOp = LoadOp.DontCare,
StoreOp storeOp = StoreOp.Store, StoreOp storeOp = StoreOp.DontCare,
LoadOp stencilLoadOp = LoadOp.DontCare, LoadOp stencilLoadOp = LoadOp.DontCare,
StoreOp stencilStoreOp = StoreOp.Store StoreOp stencilStoreOp = StoreOp.DontCare
) { ) {
TextureSlice = textureSlice; TextureSlice = textureSlice;
DepthStencilClearValue = new DepthStencilValue(); DepthStencilClearValue = new DepthStencilValue();
@ -264,6 +392,7 @@ namespace MoonWorks.Graphics
StoreOp = storeOp; StoreOp = storeOp;
StencilLoadOp = stencilLoadOp; StencilLoadOp = stencilLoadOp;
StencilStoreOp = stencilStoreOp; StencilStoreOp = stencilStoreOp;
WriteOption = writeOption;
} }
public Refresh.DepthStencilAttachmentInfo ToRefresh() public Refresh.DepthStencilAttachmentInfo ToRefresh()
@ -276,7 +405,7 @@ namespace MoonWorks.Graphics
storeOp = (Refresh.StoreOp) StoreOp, storeOp = (Refresh.StoreOp) StoreOp,
stencilLoadOp = (Refresh.LoadOp) StencilLoadOp, stencilLoadOp = (Refresh.LoadOp) StencilLoadOp,
stencilStoreOp = (Refresh.StoreOp) StencilStoreOp, stencilStoreOp = (Refresh.StoreOp) StencilStoreOp,
safeDiscard = Conversions.BoolToByte(SafeDiscard) writeOption = (Refresh.WriteOptions) WriteOption
}; };
} }
} }
@ -345,23 +474,18 @@ namespace MoonWorks.Graphics
} }
} }
/// <summary>
/// Parameters for a copy between buffer and image.
/// </summary>
/// <param name="BufferOffset">The offset into the buffer.</param>
/// <param name="BufferStride">If 0, image data is assumed tightly packed.</param>
/// <param name="BufferImageHeight">If 0, image data is assumed tightly packed.</param>
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct BufferImageCopy public readonly record struct BufferImageCopy(
{ uint BufferOffset,
public uint BufferOffset; uint BufferStride,
public uint BufferStride; // if 0, image assumed to be tightly packed uint BufferImageHeight
public uint BufferImageHeight; // if 0, image assumed to be tightly packed
public BufferImageCopy(
uint bufferOffset,
uint bufferStride,
uint bufferImageHeight
) { ) {
BufferOffset = bufferOffset;
BufferStride = bufferStride;
BufferImageHeight = bufferImageHeight;
}
public Refresh.BufferImageCopy ToRefresh() public Refresh.BufferImageCopy ToRefresh()
{ {
return new Refresh.BufferImageCopy return new Refresh.BufferImageCopy

View File

@ -21,8 +21,8 @@ namespace MoonWorks.Graphics
uint dataOffset = 0; uint dataOffset = 0;
uint dataSize = 1024; uint dataSize = 1024;
List<(GpuBuffer, BufferCopy, CopyOptions)> BufferUploads = new List<(GpuBuffer, BufferCopy, CopyOptions)>(); List<(GpuBuffer, BufferCopy, WriteOptions)> BufferUploads = new List<(GpuBuffer, BufferCopy, WriteOptions)>();
List<(TextureRegion, uint, CopyOptions)> TextureUploads = new List<(TextureRegion, uint, CopyOptions)>(); List<(TextureRegion, uint, WriteOptions)> TextureUploads = new List<(TextureRegion, uint, WriteOptions)>();
public ResourceUploader(GraphicsDevice device) : base(device) public ResourceUploader(GraphicsDevice device) : base(device)
{ {
@ -39,7 +39,7 @@ namespace MoonWorks.Graphics
var lengthInBytes = (uint) (Marshal.SizeOf<T>() * data.Length); var lengthInBytes = (uint) (Marshal.SizeOf<T>() * data.Length);
var gpuBuffer = new GpuBuffer(Device, usageFlags, lengthInBytes); var gpuBuffer = new GpuBuffer(Device, usageFlags, lengthInBytes);
SetBufferData(gpuBuffer, 0, data, CopyOptions.SafeOverwrite); SetBufferData(gpuBuffer, 0, data, WriteOptions.SafeOverwrite);
return gpuBuffer; return gpuBuffer;
} }
@ -47,7 +47,7 @@ namespace MoonWorks.Graphics
/// <summary> /// <summary>
/// Prepares upload of data into a GpuBuffer. /// Prepares upload of data into a GpuBuffer.
/// </summary> /// </summary>
public void SetBufferData<T>(GpuBuffer buffer, uint bufferOffsetInElements, Span<T> data, CopyOptions option) where T : unmanaged public void SetBufferData<T>(GpuBuffer buffer, uint bufferOffsetInElements, Span<T> data, WriteOptions option) where T : unmanaged
{ {
uint elementSize = (uint) Marshal.SizeOf<T>(); uint elementSize = (uint) Marshal.SizeOf<T>();
uint offsetInBytes = elementSize * bufferOffsetInElements; uint offsetInBytes = elementSize * bufferOffsetInElements;
@ -65,10 +65,10 @@ namespace MoonWorks.Graphics
// Textures // Textures
public Texture CreateTexture2D(Span<byte> pixelData, uint width, uint height) public Texture CreateTexture2D<T>(Span<T> pixelData, uint width, uint height) where T : unmanaged
{ {
var texture = Texture.CreateTexture2D(Device, width, height, TextureFormat.R8G8B8A8, TextureUsageFlags.Sampler); var texture = Texture.CreateTexture2D(Device, width, height, TextureFormat.R8G8B8A8, TextureUsageFlags.Sampler);
SetTextureData(texture, pixelData, CopyOptions.SafeOverwrite); SetTextureData(texture, pixelData, WriteOptions.SafeOverwrite);
return texture; return texture;
} }
@ -158,7 +158,7 @@ namespace MoonWorks.Graphics
Depth = 1 Depth = 1
}; };
SetTextureData(textureRegion, byteSpan, CopyOptions.SafeOverwrite); SetTextureData(textureRegion, byteSpan, WriteOptions.SafeOverwrite);
NativeMemory.Free(byteBuffer); NativeMemory.Free(byteBuffer);
} }
@ -181,7 +181,7 @@ namespace MoonWorks.Graphics
var pixelData = ImageUtils.GetPixelDataFromBytes(compressedImageData, out var _, out var _, out var sizeInBytes); var pixelData = ImageUtils.GetPixelDataFromBytes(compressedImageData, out var _, out var _, out var sizeInBytes);
var pixelSpan = new Span<byte>((void*) pixelData, (int) sizeInBytes); var pixelSpan = new Span<byte>((void*) pixelData, (int) sizeInBytes);
SetTextureData(textureRegion, pixelSpan, CopyOptions.SafeOverwrite); SetTextureData(textureRegion, pixelSpan, WriteOptions.SafeOverwrite);
ImageUtils.FreePixelData(pixelData); ImageUtils.FreePixelData(pixelData);
} }
@ -205,7 +205,7 @@ namespace MoonWorks.Graphics
/// <summary> /// <summary>
/// Prepares upload of pixel data into a TextureSlice. /// Prepares upload of pixel data into a TextureSlice.
/// </summary> /// </summary>
public void SetTextureData<T>(TextureRegion textureRegion, Span<T> data, CopyOptions option) where T : unmanaged public void SetTextureData<T>(TextureRegion textureRegion, Span<T> data, WriteOptions option) where T : unmanaged
{ {
var elementSize = Marshal.SizeOf<T>(); var elementSize = Marshal.SizeOf<T>();
var dataLengthInBytes = (uint) (elementSize * data.Length); var dataLengthInBytes = (uint) (elementSize * data.Length);

View File

@ -258,7 +258,7 @@ namespace MoonWorks.Video
BufferStride = CurrentStream.yStride, BufferStride = CurrentStream.yStride,
BufferImageHeight = yTexture.Height BufferImageHeight = yTexture.Height
}, },
CopyOptions.SafeDiscard WriteOptions.SafeDiscard
); );
commandBuffer.UploadToTexture( commandBuffer.UploadToTexture(
@ -269,7 +269,7 @@ namespace MoonWorks.Video
BufferStride = CurrentStream.uvStride, BufferStride = CurrentStream.uvStride,
BufferImageHeight = uTexture.Height BufferImageHeight = uTexture.Height
}, },
CopyOptions.SafeDiscard WriteOptions.SafeDiscard
); );
commandBuffer.UploadToTexture( commandBuffer.UploadToTexture(
@ -281,13 +281,13 @@ namespace MoonWorks.Video
BufferStride = CurrentStream.uvStride, BufferStride = CurrentStream.uvStride,
BufferImageHeight = vTexture.Height BufferImageHeight = vTexture.Height
}, },
CopyOptions.SafeDiscard WriteOptions.SafeDiscard
); );
commandBuffer.EndCopyPass(); commandBuffer.EndCopyPass();
commandBuffer.BeginRenderPass( commandBuffer.BeginRenderPass(
new ColorAttachmentInfo(RenderTexture, Color.Black, true) new ColorAttachmentInfo(RenderTexture, WriteOptions.SafeDiscard, Color.Black)
); );
commandBuffer.BindGraphicsPipeline(Device.VideoPipeline); commandBuffer.BindGraphicsPipeline(Device.VideoPipeline);