Campari/src/CommandBuffer.cs

208 lines
5.8 KiB
C#
Raw Normal View History

2021-01-15 01:25:15 +00:00
using System;
using System.Runtime.InteropServices;
using RefreshCS;
namespace Campari
{
2021-01-16 02:25:25 +00:00
public class CommandBuffer
2021-01-15 01:25:15 +00:00
{
2021-01-16 02:13:53 +00:00
public GraphicsDevice Device { get; }
2021-01-16 02:25:25 +00:00
public IntPtr Handle { get; internal set; }
2021-01-15 01:25:15 +00:00
// called from RefreshDevice
2021-01-16 02:25:25 +00:00
internal CommandBuffer(GraphicsDevice device)
2021-01-15 01:25:15 +00:00
{
Device = device;
2021-01-16 02:25:25 +00:00
Handle = IntPtr.Zero;
2021-01-15 01:25:15 +00:00
}
public void BeginRenderPass(
RenderPass renderPass,
Framebuffer framebuffer,
ref Refresh.Rect renderArea,
Refresh.Color[] clearColors,
ref Refresh.DepthStencilValue depthStencilClearValue
) {
var clearColorHandle = GCHandle.Alloc(clearColors, GCHandleType.Pinned);
Refresh.Refresh_BeginRenderPass(
Device.Handle,
Handle,
renderPass.Handle,
framebuffer.Handle,
ref renderArea,
clearColorHandle.AddrOfPinnedObject(),
(uint) clearColors.Length,
ref depthStencilClearValue
);
clearColorHandle.Free();
}
2021-01-15 03:14:56 +00:00
public void BeginRenderPass(
RenderPass renderPass,
Framebuffer framebuffer,
ref Refresh.Rect renderArea,
Refresh.Color[] clearColors
) {
var clearColorHandle = GCHandle.Alloc(clearColors, GCHandleType.Pinned);
Refresh.Refresh_BeginRenderPass(
Device.Handle,
Handle,
renderPass.Handle,
framebuffer.Handle,
ref renderArea,
clearColorHandle.AddrOfPinnedObject(),
(uint) clearColors.Length,
IntPtr.Zero
);
clearColorHandle.Free();
}
2021-01-15 01:25:15 +00:00
public void BindGraphicsPipeline(
GraphicsPipeline graphicsPipeline
) {
Refresh.Refresh_BindGraphicsPipeline(
Device.Handle,
Handle,
graphicsPipeline.Handle
);
}
public unsafe uint PushVertexShaderParams<T>(
2021-01-15 03:14:56 +00:00
params T[] uniforms
2021-01-15 01:25:15 +00:00
) where T : unmanaged
{
fixed (T* ptr = &uniforms[0])
{
return Refresh.Refresh_PushVertexShaderParams(
Device.Handle,
Handle,
(IntPtr) ptr,
(uint) uniforms.Length
);
}
}
public unsafe uint PushFragmentShaderParams<T>(
2021-01-15 03:14:56 +00:00
params T[] uniforms
2021-01-15 01:25:15 +00:00
) where T : unmanaged
{
fixed (T* ptr = &uniforms[0])
{
return Refresh.Refresh_PushFragmentShaderParams(
Device.Handle,
Handle,
(IntPtr) ptr,
(uint) uniforms.Length
);
}
}
2021-01-15 03:14:56 +00:00
public unsafe void BindVertexBuffers(
2021-01-15 01:25:15 +00:00
uint firstBinding,
uint bindingCount,
Buffer[] buffers,
UInt64[] offsets
) {
2021-01-15 03:14:56 +00:00
var bufferPtrs = stackalloc IntPtr[buffers.Length];
for (var i = 0; i < buffers.Length; i += 1)
{
bufferPtrs[i] = buffers[i].Handle;
}
2021-01-15 01:25:15 +00:00
var offsetHandle = GCHandle.Alloc(offsets, GCHandleType.Pinned);
Refresh.Refresh_BindVertexBuffers(
Device.Handle,
Handle,
firstBinding,
bindingCount,
2021-01-15 03:14:56 +00:00
(IntPtr) bufferPtrs,
2021-01-15 01:25:15 +00:00
offsetHandle.AddrOfPinnedObject()
);
offsetHandle.Free();
}
public void BindIndexBuffer(
Buffer indexBuffer,
uint offset,
Refresh.IndexElementSize indexElementSize
) {
Refresh.Refresh_BindIndexBuffer(
Device.Handle,
Handle,
indexBuffer.Handle,
offset,
indexElementSize
);
}
2021-01-15 03:14:56 +00:00
public unsafe void BindFragmentSamplers(
2021-01-15 01:25:15 +00:00
Texture[] textures,
Sampler[] samplers
) {
2021-01-15 03:14:56 +00:00
var texturePtrs = stackalloc IntPtr[textures.Length];
var samplerPtrs = stackalloc IntPtr[samplers.Length];
for (var i = 0; i < textures.Length; i += 1)
{
texturePtrs[i] = textures[i].Handle;
}
for (var i = 0; i < samplers.Length; i += 1)
{
samplerPtrs[i] = samplers[i].Handle;
}
2021-01-15 01:25:15 +00:00
Refresh.Refresh_BindFragmentSamplers(
Device.Handle,
Handle,
2021-01-15 03:14:56 +00:00
(IntPtr) texturePtrs,
(IntPtr) samplerPtrs
2021-01-15 01:25:15 +00:00
);
}
public void DrawPrimitives(
uint vertexStart,
uint primitiveCount,
uint vertexParamOffset,
uint fragmentParamOffset
) {
Refresh.Refresh_DrawPrimitives(
Device.Handle,
Handle,
vertexStart,
primitiveCount,
vertexParamOffset,
fragmentParamOffset
);
}
public void EndRenderPass()
{
Refresh.Refresh_EndRenderPass(
Device.Handle,
Handle
);
}
public void QueuePresent(ref TextureSlice textureSlice, ref Refresh.Rect rectangle, Refresh.Filter filter)
{
var refreshTextureSlice = textureSlice.ToRefreshTextureSlice();
Refresh.Refresh_QueuePresent(
Device.Handle,
Handle,
ref refreshTextureSlice,
ref rectangle,
filter
);
}
}
}