wrap some graphics resources

main
cosmonaut 2021-01-14 01:26:54 -08:00
parent dab4c57284
commit 7a7e26d84e
9 changed files with 197 additions and 83 deletions

View File

@ -3,6 +3,7 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Platforms>x64</Platforms>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup>

View File

@ -1,82 +0,0 @@
using System;
using RefreshCS;
namespace Campari
{
public class Texture : IDisposable
{
public RefreshDevice Device { get; }
public IntPtr Handle { get; }
public uint Height { get; }
public uint Width { get; }
public bool IsDisposed { get; private set; }
public static Texture Load(RefreshDevice device, string path)
{
var pixels = Refresh.Refresh_Image_Load(path, out var width, out var height, out var channels);
IntPtr textureHandle = Refresh.Refresh_CreateTexture2D(
device.Handle,
Refresh.ColorFormat.R8G8B8A8,
(uint) width,
(uint) height,
1,
(uint) Refresh.TextureUsageFlagBits.SamplerBit
);
Refresh.TextureSlice textureSlice;
textureSlice.texture = textureHandle;
textureSlice.rectangle.x = 0;
textureSlice.rectangle.y = 0;
textureSlice.rectangle.w = width;
textureSlice.rectangle.h = height;
textureSlice.level = 0;
textureSlice.layer = 0;
textureSlice.depth = 0;
Refresh.Refresh_SetTextureData(
device.Handle,
ref textureSlice,
pixels,
(uint) (width * height * 4)
);
return new Texture(
device,
textureHandle,
(uint) width,
(uint) height
);
}
public Texture(RefreshDevice device, IntPtr handle, uint width, uint height)
{
Device = device;
Handle = handle;
Width = width;
Height = height;
}
protected virtual void Dispose(bool disposing)
{
if (!IsDisposed)
{
Refresh.Refresh_QueueDestroyTexture(Device.Handle, Handle);
IsDisposed = true;
}
}
~Texture()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: false);
}
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}

@ -1 +1 @@
Subproject commit c33e62b9e46f9c86c40fffe56bce461739b71bf8
Subproject commit c6fddad50aaf4a6d00ca8571fb8f94876d0fcbef

33
src/Bytecode.cs Normal file
View File

@ -0,0 +1,33 @@
using System.IO;
namespace Campari
{
public static class Bytecode
{
public static uint[] ReadBytecode(FileInfo fileInfo)
{
byte[] data;
int size;
using (FileStream stream = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read))
{
size = (int)stream.Length;
data = new byte[size];
stream.Read(data, 0, size);
}
uint[] uintData = new uint[size / 4];
using (var memoryStream = new MemoryStream(data))
{
using (var reader = new BinaryReader(memoryStream))
{
for (int i = 0; i < size / 4; i++)
{
uintData[i] = reader.ReadUInt32();
}
}
}
return uintData;
}
}
}

42
src/GraphicsResource.cs Normal file
View File

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Campari
{
public abstract class GraphicsResource : IDisposable
{
public RefreshDevice Device { get; }
public IntPtr Handle { get; protected set; }
public bool IsDisposed { get; private set; }
protected abstract Action<IntPtr, IntPtr> QueueDestroyFunction { get; }
public GraphicsResource(RefreshDevice device)
{
Device = device;
}
protected virtual void Dispose(bool disposing)
{
if (!IsDisposed)
{
QueueDestroyFunction(Device.Handle, Handle);
IsDisposed = true;
}
}
~GraphicsResource()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: false);
}
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}

42
src/RenderPass.cs Normal file
View File

@ -0,0 +1,42 @@
using System;
using RefreshCS;
namespace Campari
{
public class RenderPass : GraphicsResource
{
protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyRenderPass;
public unsafe RenderPass(RefreshDevice device, params Refresh.ColorTargetDescription[] colorTargetDescriptions) : base(device)
{
fixed (Refresh.ColorTargetDescription* ptr = colorTargetDescriptions)
{
Refresh.RenderPassCreateInfo renderPassCreateInfo;
renderPassCreateInfo.colorTargetCount = (uint) colorTargetDescriptions.Length;
renderPassCreateInfo.colorTargetDescriptions = (IntPtr) ptr;
renderPassCreateInfo.depthStencilTargetDescription = IntPtr.Zero;
Handle = Refresh.Refresh_CreateRenderPass(device.Handle, ref renderPassCreateInfo);
}
}
public unsafe RenderPass(
RefreshDevice device,
Refresh.DepthStencilTargetDescription depthStencilTargetDescription,
params Refresh.ColorTargetDescription[] colorTargetDescriptions
) : base(device)
{
Refresh.DepthStencilTargetDescription* depthStencilPtr = &depthStencilTargetDescription;
fixed (Refresh.ColorTargetDescription* colorPtr = colorTargetDescriptions)
{
Refresh.RenderPassCreateInfo renderPassCreateInfo;
renderPassCreateInfo.colorTargetCount = (uint)colorTargetDescriptions.Length;
renderPassCreateInfo.colorTargetDescriptions = (IntPtr)colorPtr;
renderPassCreateInfo.depthStencilTargetDescription = (IntPtr) depthStencilPtr;
Handle = Refresh.Refresh_CreateRenderPass(device.Handle, ref renderPassCreateInfo);
}
}
}
}

23
src/ShaderModule.cs Normal file
View File

@ -0,0 +1,23 @@
using RefreshCS;
using System;
using System.IO;
namespace Campari
{
public class ShaderModule : GraphicsResource
{
protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyShaderModule;
public unsafe ShaderModule(RefreshDevice device, FileInfo fileInfo) : base(device)
{
fixed (uint* ptr = Bytecode.ReadBytecode(fileInfo))
{
Refresh.ShaderModuleCreateInfo shaderModuleCreateInfo;
shaderModuleCreateInfo.codeSize = (UIntPtr) fileInfo.Length;
shaderModuleCreateInfo.byteCode = (IntPtr) ptr;
Handle = Refresh.Refresh_CreateShaderModule(device.Handle, ref shaderModuleCreateInfo);
}
}
}
}

55
src/Texture.cs Normal file
View File

@ -0,0 +1,55 @@
using System;
using System.IO;
using RefreshCS;
namespace Campari
{
public class Texture : GraphicsResource
{
public uint Height { get; }
public uint Width { get; }
protected override Action<IntPtr, IntPtr> QueueDestroyFunction => Refresh.Refresh_QueueDestroyTexture;
public Texture(RefreshDevice device, FileInfo fileInfo) : base(device)
{
var pixels = Refresh.Refresh_Image_Load(
fileInfo.FullName,
out var width,
out var height,
out var channels
);
IntPtr textureHandle = Refresh.Refresh_CreateTexture2D(
device.Handle,
Refresh.ColorFormat.R8G8B8A8,
(uint)width,
(uint)height,
1,
(uint)Refresh.TextureUsageFlagBits.SamplerBit
);
Refresh.TextureSlice textureSlice;
textureSlice.texture = textureHandle;
textureSlice.rectangle.x = 0;
textureSlice.rectangle.y = 0;
textureSlice.rectangle.w = width;
textureSlice.rectangle.h = height;
textureSlice.level = 0;
textureSlice.layer = 0;
textureSlice.depth = 0;
Refresh.Refresh_SetTextureData(
device.Handle,
ref textureSlice,
pixels,
(uint)(width * height * 4)
);
Refresh.Refresh_Image_Free(pixels);
Width = (uint) width;
Height = (uint) height;
}
}
}