2022-02-23 05:14:32 +00:00
|
|
|
|
using System;
|
2021-11-15 05:08:02 +00:00
|
|
|
|
using System.Runtime.InteropServices;
|
2021-02-10 06:51:30 +00:00
|
|
|
|
using MoonWorks.Math;
|
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; }
|
|
|
|
|
public IntPtr Handle { get; internal set; }
|
|
|
|
|
|
|
|
|
|
// called from RefreshDevice
|
|
|
|
|
internal CommandBuffer(GraphicsDevice device, IntPtr handle)
|
|
|
|
|
{
|
|
|
|
|
Device = device;
|
|
|
|
|
Handle = handle;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-13 03:06:14 +00:00
|
|
|
|
// FIXME: we can probably use the NativeMemory functions to not have to generate arrays here
|
|
|
|
|
|
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="colorAttachmentInfos">The color attachments to use in the render pass.</param>
|
2022-02-23 05:14:32 +00:00
|
|
|
|
public unsafe void BeginRenderPass(
|
2022-02-25 05:34:36 +00:00
|
|
|
|
params ColorAttachmentInfo[] colorAttachmentInfos
|
2022-02-23 05:14:32 +00:00
|
|
|
|
)
|
|
|
|
|
{
|
2022-02-25 05:34:36 +00:00
|
|
|
|
#if DEBUG
|
|
|
|
|
if (colorAttachmentInfos.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
Logger.LogError("Render pass must contain at least one attachment!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-02-23 05:14:32 +00:00
|
|
|
|
|
2022-02-25 05:34:36 +00:00
|
|
|
|
if (colorAttachmentInfos.Length > 4)
|
|
|
|
|
{
|
|
|
|
|
Logger.LogError("Render pass cannot have more than 4 color attachments!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
var refreshColorAttachmentInfos = new Refresh.ColorAttachmentInfo[colorAttachmentInfos.Length];
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < colorAttachmentInfos.Length; i += 1)
|
|
|
|
|
{
|
|
|
|
|
refreshColorAttachmentInfos[i] = colorAttachmentInfos[i].ToRefresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fixed (Refresh.ColorAttachmentInfo* pColorAttachmentInfos = refreshColorAttachmentInfos)
|
|
|
|
|
{
|
|
|
|
|
Refresh.Refresh_BeginRenderPass(
|
|
|
|
|
Device.Handle,
|
|
|
|
|
Handle,
|
2022-03-07 06:33:12 +00:00
|
|
|
|
IntPtr.Zero,
|
2022-02-25 05:34:36 +00:00
|
|
|
|
(IntPtr) pColorAttachmentInfos,
|
|
|
|
|
(uint) colorAttachmentInfos.Length,
|
|
|
|
|
IntPtr.Zero
|
|
|
|
|
);
|
|
|
|
|
}
|
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>
|
|
|
|
|
/// <param name="colorAttachmentInfos">The color attachments to use in the render pass.</param>
|
2022-02-23 05:14:32 +00:00
|
|
|
|
public unsafe void BeginRenderPass(
|
2022-02-25 05:34:36 +00:00
|
|
|
|
DepthStencilAttachmentInfo depthStencilAttachmentInfo,
|
|
|
|
|
params ColorAttachmentInfo[] colorAttachmentInfos
|
2022-02-23 05:14:32 +00:00
|
|
|
|
)
|
|
|
|
|
{
|
2022-02-25 05:34:36 +00:00
|
|
|
|
#if DEBUG
|
|
|
|
|
if (colorAttachmentInfos.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
Logger.LogError("Render pass must contain at least one attachment!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (colorAttachmentInfos.Length > 4)
|
|
|
|
|
{
|
|
|
|
|
Logger.LogError("Render pass cannot have more than 4 color attachments!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
var refreshColorAttachmentInfos = new Refresh.ColorAttachmentInfo[colorAttachmentInfos.Length];
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < colorAttachmentInfos.Length; i += 1)
|
|
|
|
|
{
|
|
|
|
|
refreshColorAttachmentInfos[i] = colorAttachmentInfos[i].ToRefresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var refreshDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToRefresh();
|
|
|
|
|
|
|
|
|
|
fixed (Refresh.ColorAttachmentInfo* pColorAttachmentInfos = refreshColorAttachmentInfos)
|
|
|
|
|
{
|
|
|
|
|
Refresh.Refresh_BeginRenderPass(
|
|
|
|
|
Device.Handle,
|
|
|
|
|
Handle,
|
2022-03-07 06:33:12 +00:00
|
|
|
|
IntPtr.Zero,
|
2022-02-25 05:34:36 +00:00
|
|
|
|
pColorAttachmentInfos,
|
|
|
|
|
(uint) colorAttachmentInfos.Length,
|
|
|
|
|
&refreshDepthStencilAttachmentInfo
|
|
|
|
|
);
|
|
|
|
|
}
|
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="renderArea">The rectangle that should be drawn to on the attachments.</param>
|
|
|
|
|
/// <param name="colorAttachmentInfos">The color attachments to use in the render pass.</param>
|
2022-02-23 05:14:32 +00:00
|
|
|
|
public unsafe void BeginRenderPass(
|
2022-02-23 06:16:06 +00:00
|
|
|
|
in Rect renderArea,
|
2022-02-25 05:34:36 +00:00
|
|
|
|
params ColorAttachmentInfo[] colorAttachmentInfos
|
2022-02-23 05:14:32 +00:00
|
|
|
|
)
|
|
|
|
|
{
|
2022-02-25 05:34:36 +00:00
|
|
|
|
#if DEBUG
|
|
|
|
|
if (colorAttachmentInfos.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
Logger.LogError("Render pass must contain at least one attachment!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (colorAttachmentInfos.Length > 4)
|
|
|
|
|
{
|
|
|
|
|
Logger.LogError("Render pass cannot have more than 4 color attachments!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
var refreshColorAttachmentInfos = new Refresh.ColorAttachmentInfo[colorAttachmentInfos.Length];
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < colorAttachmentInfos.Length; i += 1)
|
|
|
|
|
{
|
|
|
|
|
refreshColorAttachmentInfos[i] = colorAttachmentInfos[i].ToRefresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fixed (Refresh.ColorAttachmentInfo* pColorAttachmentInfos = refreshColorAttachmentInfos)
|
|
|
|
|
{
|
|
|
|
|
Refresh.Refresh_BeginRenderPass(
|
|
|
|
|
Device.Handle,
|
|
|
|
|
Handle,
|
|
|
|
|
renderArea.ToRefresh(),
|
|
|
|
|
(IntPtr) pColorAttachmentInfos,
|
|
|
|
|
(uint) colorAttachmentInfos.Length,
|
|
|
|
|
IntPtr.Zero
|
|
|
|
|
);
|
|
|
|
|
}
|
2022-02-23 06:16:06 +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="renderArea">The rectangle that should be drawn to on the attachments.</param>
|
|
|
|
|
/// <param name="depthStencilAttachmentInfo">The depth stencil attachment to use in the render pass.</param>
|
|
|
|
|
/// <param name="colorAttachmentInfos">The color attachments to use in the render pass.</param>
|
2022-02-23 06:16:06 +00:00
|
|
|
|
public unsafe void BeginRenderPass(
|
|
|
|
|
in Rect renderArea,
|
2022-02-25 05:34:36 +00:00
|
|
|
|
DepthStencilAttachmentInfo depthStencilAttachmentInfo,
|
|
|
|
|
params ColorAttachmentInfo[] colorAttachmentInfos
|
2022-02-23 06:16:06 +00:00
|
|
|
|
)
|
|
|
|
|
{
|
2022-02-25 05:34:36 +00:00
|
|
|
|
#if DEBUG
|
|
|
|
|
if (colorAttachmentInfos.Length == 0)
|
|
|
|
|
{
|
|
|
|
|
Logger.LogError("Render pass must contain at least one attachment!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (colorAttachmentInfos.Length > 4)
|
|
|
|
|
{
|
|
|
|
|
Logger.LogError("Render pass cannot have more than 4 color attachments!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
var refreshColorAttachmentInfos = new Refresh.ColorAttachmentInfo[colorAttachmentInfos.Length];
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < colorAttachmentInfos.Length; i += 1)
|
|
|
|
|
{
|
|
|
|
|
refreshColorAttachmentInfos[i] = colorAttachmentInfos[i].ToRefresh();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var refreshDepthStencilAttachmentInfo = depthStencilAttachmentInfo.ToRefresh();
|
|
|
|
|
|
|
|
|
|
fixed (Refresh.ColorAttachmentInfo* pColorAttachmentInfos = refreshColorAttachmentInfos)
|
|
|
|
|
{
|
|
|
|
|
Refresh.Refresh_BeginRenderPass(
|
|
|
|
|
Device.Handle,
|
|
|
|
|
Handle,
|
|
|
|
|
renderArea.ToRefresh(),
|
|
|
|
|
pColorAttachmentInfos,
|
|
|
|
|
(uint) colorAttachmentInfos.Length,
|
|
|
|
|
&refreshDepthStencilAttachmentInfo
|
|
|
|
|
);
|
|
|
|
|
}
|
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
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
Refresh.Refresh_BindComputePipeline(
|
|
|
|
|
Device.Handle,
|
|
|
|
|
Handle,
|
|
|
|
|
computePipeline.Handle
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Binds buffers to be used in the compute shader.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buffers">A set of buffers to bind.</param>
|
|
|
|
|
public unsafe void BindComputeBuffers(
|
|
|
|
|
params Buffer[] buffers
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <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(
|
|
|
|
|
params Texture[] textures
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
Refresh.Refresh_BindGraphicsPipeline(
|
|
|
|
|
Device.Handle,
|
|
|
|
|
Handle,
|
|
|
|
|
graphicsPipeline.Handle
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-04 22:14:22 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Sets the viewport. Only valid during a render pass.
|
|
|
|
|
/// </summary>
|
2022-03-04 21:21:52 +00:00
|
|
|
|
public void SetViewport(Viewport viewport)
|
|
|
|
|
{
|
|
|
|
|
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-03-04 21:21:52 +00:00
|
|
|
|
public void SetScissor(Rect scissor)
|
|
|
|
|
{
|
|
|
|
|
Refresh.Refresh_SetScissor(
|
|
|
|
|
Device.Handle,
|
|
|
|
|
Handle,
|
|
|
|
|
scissor.ToRefresh()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-23 05:14:32 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Binds vertex buffers to be used by subsequent draw calls.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="firstBinding">The index of the first buffer to bind.</param>
|
|
|
|
|
/// <param name="bufferBindings">Buffers to bind and their associated offsets.</param>
|
|
|
|
|
public unsafe void BindVertexBuffers(
|
|
|
|
|
uint firstBinding,
|
|
|
|
|
params BufferBinding[] bufferBindings
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
var bufferPtrs = stackalloc IntPtr[bufferBindings.Length];
|
|
|
|
|
var offsets = stackalloc ulong[bufferBindings.Length];
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < bufferBindings.Length; i += 1)
|
|
|
|
|
{
|
|
|
|
|
bufferPtrs[i] = bufferBindings[i].Buffer.Handle;
|
|
|
|
|
offsets[i] = bufferBindings[i].Offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Refresh.Refresh_BindVertexBuffers(
|
|
|
|
|
Device.Handle,
|
|
|
|
|
Handle,
|
|
|
|
|
firstBinding,
|
|
|
|
|
(uint) bufferBindings.Length,
|
|
|
|
|
(IntPtr) bufferPtrs,
|
|
|
|
|
(IntPtr) offsets
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Binds vertex buffers to be used by subsequent draw calls.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="buffers">The buffers to bind.</param>
|
|
|
|
|
public unsafe void BindVertexBuffers(
|
|
|
|
|
params Buffer[] buffers
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
var bufferPtrs = stackalloc IntPtr[buffers.Length];
|
|
|
|
|
var offsets = stackalloc ulong[buffers.Length];
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < buffers.Length; i += 1)
|
|
|
|
|
{
|
|
|
|
|
bufferPtrs[i] = buffers[i].Handle;
|
|
|
|
|
offsets[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Refresh.Refresh_BindVertexBuffers(
|
|
|
|
|
Device.Handle,
|
|
|
|
|
Handle,
|
|
|
|
|
0,
|
|
|
|
|
(uint) buffers.Length,
|
|
|
|
|
(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>
|
|
|
|
|
/// <param name="textureSamplerBindings">An array of texture-sampler pairs to bind.</param>
|
|
|
|
|
/// <param name="length">The number of texture-sampler pairs from the array to bind.</param>
|
|
|
|
|
public unsafe void BindVertexSamplers(
|
|
|
|
|
TextureSamplerBinding[] textureSamplerBindings,
|
|
|
|
|
int length
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
var texturePtrs = stackalloc IntPtr[textureSamplerBindings.Length];
|
|
|
|
|
var samplerPtrs = stackalloc IntPtr[textureSamplerBindings.Length];
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < length; i += 1)
|
|
|
|
|
{
|
2022-05-24 02:12:17 +00:00
|
|
|
|
texturePtrs[i] = textureSamplerBindings[i].TextureHandle;
|
|
|
|
|
samplerPtrs[i] = textureSamplerBindings[i].SamplerHandle;
|
2022-02-23 05:14:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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(
|
|
|
|
|
params TextureSamplerBinding[] textureSamplerBindings
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
BindVertexSamplers(textureSamplerBindings, textureSamplerBindings.Length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Binds samplers to be used by the fragment shader.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="textureSamplerBindings">An array of texture-sampler pairs to bind.</param>
|
|
|
|
|
/// <param name="length">The number of texture-sampler pairs from the given array to bind.</param>
|
|
|
|
|
public unsafe void BindFragmentSamplers(
|
|
|
|
|
TextureSamplerBinding[] textureSamplerBindings,
|
|
|
|
|
int length
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
var texturePtrs = stackalloc IntPtr[textureSamplerBindings.Length];
|
|
|
|
|
var samplerPtrs = stackalloc IntPtr[textureSamplerBindings.Length];
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < length; i += 1)
|
|
|
|
|
{
|
2022-03-17 21:42:43 +00:00
|
|
|
|
#if DEBUG
|
2022-05-24 02:12:17 +00:00
|
|
|
|
if (textureSamplerBindings[i].TextureHandle == IntPtr.Zero)
|
2022-03-17 21:42:43 +00:00
|
|
|
|
{
|
|
|
|
|
throw new NullReferenceException("Texture binding must not be null!");
|
|
|
|
|
}
|
2022-05-24 02:12:17 +00:00
|
|
|
|
if (textureSamplerBindings[i].TextureHandle == IntPtr.Zero)
|
2022-03-17 21:42:43 +00:00
|
|
|
|
{
|
|
|
|
|
throw new NullReferenceException("Sampler binding must not be null!");
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2022-05-24 02:12:17 +00:00
|
|
|
|
texturePtrs[i] = textureSamplerBindings[i].TextureHandle;
|
|
|
|
|
samplerPtrs[i] = textureSamplerBindings[i].SamplerHandle;
|
2022-02-23 05:14:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Refresh.Refresh_BindFragmentSamplers(
|
|
|
|
|
Device.Handle,
|
|
|
|
|
Handle,
|
|
|
|
|
(IntPtr) texturePtrs,
|
|
|
|
|
(IntPtr) samplerPtrs
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Binds samplers to be used by the fragment shader.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="textureSamplerBindings">An array of texture-sampler pairs to bind.</param>
|
|
|
|
|
public unsafe void BindFragmentSamplers(
|
|
|
|
|
params TextureSamplerBinding[] textureSamplerBindings
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
BindFragmentSamplers(textureSamplerBindings, textureSamplerBindings.Length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <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>(
|
|
|
|
|
params T[] uniforms
|
|
|
|
|
) where T : unmanaged
|
|
|
|
|
{
|
|
|
|
|
fixed (T* ptr = &uniforms[0])
|
|
|
|
|
{
|
|
|
|
|
return Refresh.Refresh_PushVertexShaderUniforms(
|
|
|
|
|
Device.Handle,
|
|
|
|
|
Handle,
|
|
|
|
|
(IntPtr) ptr,
|
2022-04-27 21:14:15 +00:00
|
|
|
|
(uint) (uniforms.Length * 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>(
|
|
|
|
|
params T[] uniforms
|
|
|
|
|
) where T : unmanaged
|
|
|
|
|
{
|
|
|
|
|
fixed (T* ptr = &uniforms[0])
|
|
|
|
|
{
|
|
|
|
|
return Refresh.Refresh_PushFragmentShaderUniforms(
|
|
|
|
|
Device.Handle,
|
|
|
|
|
Handle,
|
|
|
|
|
(IntPtr) ptr,
|
2022-04-27 21:14:15 +00:00
|
|
|
|
(uint) (uniforms.Length * 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>(
|
|
|
|
|
params T[] uniforms
|
|
|
|
|
) where T : unmanaged
|
|
|
|
|
{
|
|
|
|
|
fixed (T* ptr = &uniforms[0])
|
|
|
|
|
{
|
|
|
|
|
return Refresh.Refresh_PushComputeShaderUniforms(
|
|
|
|
|
Device.Handle,
|
|
|
|
|
Handle,
|
|
|
|
|
(IntPtr) ptr,
|
2022-04-27 21:14:15 +00:00
|
|
|
|
(uint) (uniforms.Length * 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
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
Refresh.Refresh_DrawPrimitives(
|
|
|
|
|
Device.Handle,
|
|
|
|
|
Handle,
|
|
|
|
|
vertexStart,
|
|
|
|
|
primitiveCount,
|
|
|
|
|
vertexParamOffset,
|
|
|
|
|
fragmentParamOffset
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <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
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <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-02-23 05:14:32 +00:00
|
|
|
|
/// </summary>
|
2022-03-02 17:39:23 +00:00
|
|
|
|
public Texture? AcquireSwapchainTexture(
|
2022-02-25 21:23:31 +00:00
|
|
|
|
Window window
|
2022-02-23 05:14:32 +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-03-02 06:57:10 +00:00
|
|
|
|
return new Texture(
|
|
|
|
|
Device,
|
2022-03-02 17:39:23 +00:00
|
|
|
|
texturePtr,
|
2022-03-02 07:21:42 +00:00
|
|
|
|
Device.GetSwapchainFormat(window),
|
2022-03-10 18:25:41 +00:00
|
|
|
|
width,
|
|
|
|
|
height
|
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
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
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-04-27 21:14:15 +00:00
|
|
|
|
var elementSize = sizeof(T);
|
2022-02-23 05:14:32 +00:00
|
|
|
|
|
|
|
|
|
fixed (T* ptr = &data[0])
|
|
|
|
|
{
|
|
|
|
|
var dataPtr = ptr + (startElement * elementSize);
|
|
|
|
|
|
|
|
|
|
Refresh.Refresh_SetBufferData(
|
|
|
|
|
Device.Handle,
|
|
|
|
|
Handle,
|
|
|
|
|
buffer.Handle,
|
|
|
|
|
bufferOffsetInBytes,
|
|
|
|
|
(IntPtr) dataPtr,
|
|
|
|
|
(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-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-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)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <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
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
var refreshTextureSlice = textureSlice.ToRefreshTextureSlice();
|
|
|
|
|
|
|
|
|
|
Refresh.Refresh_CopyTextureToBuffer(
|
|
|
|
|
Device.Handle,
|
|
|
|
|
Handle,
|
|
|
|
|
refreshTextureSlice,
|
|
|
|
|
buffer.Handle
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-01-20 03:33:27 +00:00
|
|
|
|
}
|