Added IShaderCompiler
This commit is contained in:
@@ -22,6 +22,11 @@ public readonly struct Result
|
|||||||
return new Result(false, message);
|
return new Result(false, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Result<T> Success<T>(T value)
|
||||||
|
{
|
||||||
|
return Result<T>.Success(value);
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString() => success ? "OK" : $"Error: {message}";
|
public override string ToString() => success ? "OK" : $"Error: {message}";
|
||||||
|
|
||||||
public static implicit operator bool(Result result) => result.success;
|
public static implicit operator bool(Result result) => result.success;
|
||||||
@@ -34,16 +39,16 @@ public readonly struct Result<T>
|
|||||||
|
|
||||||
public readonly string? message;
|
public readonly string? message;
|
||||||
|
|
||||||
public Result(bool success, T data, string? message = null)
|
public Result(bool success, T value, string? message = null)
|
||||||
{
|
{
|
||||||
this.success = success;
|
this.success = success;
|
||||||
this.value = data;
|
this.value = value;
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result<T> Success(T data)
|
public static Result<T> Success(T value)
|
||||||
{
|
{
|
||||||
return new Result<T>(true, data);
|
return new Result<T>(true, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result<T> Fail(string? message)
|
public static Result<T> Fail(string? message)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Misaki.HighPerformance.LowLevel;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
@@ -97,4 +98,18 @@ internal static unsafe partial class Win32Utility
|
|||||||
{
|
{
|
||||||
return (flags & Unsafe.As<T, uint>(ref flag)) != 0;
|
return (flags & Unsafe.As<T, uint>(ref flag)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension(MemoryLeakException)
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
[Conditional("DEBUG")]
|
||||||
|
[Conditional("GHOST_EDITOR")]
|
||||||
|
public static void ThrowIfRefCountNonZero(uint count)
|
||||||
|
{
|
||||||
|
if (count != 0)
|
||||||
|
{
|
||||||
|
throw new MemoryLeakException($"Reference count is not zero: {count}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using Ghost.Core;
|
using Ghost.Core;
|
||||||
using Ghost.Core.Graphics;
|
|
||||||
using Ghost.Graphics.RHI;
|
using Ghost.Graphics.RHI;
|
||||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
using Misaki.HighPerformance.LowLevel.Collections;
|
using Misaki.HighPerformance.LowLevel.Collections;
|
||||||
@@ -123,7 +122,7 @@ public unsafe readonly ref struct RenderingContext
|
|||||||
public void UploadTexture(Handle<Texture> texture, ReadOnlySpan<byte> data)
|
public void UploadTexture(Handle<Texture> texture, ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
var desc = ResourceDatabase.GetResourceDescription(texture.AsResource());
|
var desc = ResourceDatabase.GetResourceDescription(texture.AsResource());
|
||||||
desc.textureDescription.Format.GetSurfaceInfo((int)desc.textureDescription.Width, (int)desc.textureDescription.Height, out var rowPitch, out var slicePitch, out _);
|
desc.TextureDescription.Format.GetSurfaceInfo((int)desc.TextureDescription.Width, (int)desc.TextureDescription.Height, out var rowPitch, out var slicePitch, out _);
|
||||||
|
|
||||||
var subresourceData = new SubResourceData
|
var subresourceData = new SubResourceData
|
||||||
{
|
{
|
||||||
@@ -159,12 +158,12 @@ public unsafe readonly ref struct RenderingContext
|
|||||||
shader.TryGetPassKey(passName, out var passIndex, out var passKey);
|
shader.TryGetPassKey(passName, out var passIndex, out var passKey);
|
||||||
var hash = new GraphicsPipelineHash
|
var hash = new GraphicsPipelineHash
|
||||||
{
|
{
|
||||||
id = passKey,
|
Id = passKey,
|
||||||
rtvCount = 1,
|
RtvCount = 1,
|
||||||
dsvFormat = TextureFormat.Unknown,
|
DsvFormat = TextureFormat.Unknown,
|
||||||
};
|
};
|
||||||
|
|
||||||
hash.rtvFormats[0] = TextureFormat.B8G8R8A8_UNorm;
|
hash.RtvFormats[0] = TextureFormat.B8G8R8A8_UNorm;
|
||||||
var pipelineKey = hash.GetKey();
|
var pipelineKey = hash.GetKey();
|
||||||
_directCmd.SetPipelineState(pipelineKey);
|
_directCmd.SetPipelineState(pipelineKey);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
namespace Ghost.Core.Graphics;
|
namespace Ghost.Graphics.Core;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The layout of the root signature is:
|
/// The layout of the root signature is:
|
||||||
@@ -32,4 +32,12 @@ public static class RootSignatureLayout
|
|||||||
|
|
||||||
public const int TEXTURE_HEAP_SLOT = 0;
|
public const int TEXTURE_HEAP_SLOT = 0;
|
||||||
public const int SAMPLER_HEAP_SLOT = 0;
|
public const int SAMPLER_HEAP_SLOT = 0;
|
||||||
|
|
||||||
|
public const int ROOT_PARAMETER_COUNT =
|
||||||
|
#if USE_TRADITIONAL_BINDLESS
|
||||||
|
6
|
||||||
|
#else
|
||||||
|
4
|
||||||
|
#endif
|
||||||
|
;
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
using Ghost.Core;
|
using Ghost.Core;
|
||||||
using Ghost.Core.Graphics;
|
using Ghost.Core.Utilities;
|
||||||
using Ghost.Graphics.Core;
|
using Ghost.Graphics.Core;
|
||||||
using Ghost.Graphics.D3D12.Utilities;
|
using Ghost.Graphics.D3D12.Utilities;
|
||||||
using Ghost.Graphics.RHI;
|
using Ghost.Graphics.RHI;
|
||||||
|
using Misaki.HighPerformance.LowLevel;
|
||||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
using Misaki.HighPerformance.LowLevel.Utilities;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using TerraFX.Interop.DirectX;
|
using TerraFX.Interop.DirectX;
|
||||||
@@ -13,10 +14,9 @@ using static TerraFX.Aliases.DXGI_Alias;
|
|||||||
|
|
||||||
namespace Ghost.Graphics.D3D12;
|
namespace Ghost.Graphics.D3D12;
|
||||||
|
|
||||||
internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
internal unsafe class D3D12CommandBuffer : D3D12RHIObject<ID3D12GraphicsCommandList10>, ICommandBuffer
|
||||||
{
|
{
|
||||||
private ComPtr<ID3D12CommandAllocator> _allocator;
|
private ComPtr<ID3D12CommandAllocator> _allocator;
|
||||||
private ComPtr<ID3D12GraphicsCommandList10> _commandList;
|
|
||||||
|
|
||||||
private readonly D3D12PipelineLibrary _pipelineLibrary;
|
private readonly D3D12PipelineLibrary _pipelineLibrary;
|
||||||
private readonly D3D12ResourceDatabase _resourceDatabase;
|
private readonly D3D12ResourceDatabase _resourceDatabase;
|
||||||
@@ -24,26 +24,14 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
private readonly D3D12DescriptorAllocator _descriptorAllocator;
|
private readonly D3D12DescriptorAllocator _descriptorAllocator;
|
||||||
private readonly CommandBufferType _type;
|
private readonly CommandBufferType _type;
|
||||||
|
|
||||||
private string _name;
|
|
||||||
private ushort _commandCount;
|
private ushort _commandCount;
|
||||||
private bool _isRecording;
|
private bool _isRecording;
|
||||||
private bool _disposed;
|
|
||||||
|
|
||||||
public ID3D12GraphicsCommandList10* NativeCommandList => _commandList.Get();
|
public ID3D12GraphicsCommandList10* NativeCommandList => nativeObject.Get();
|
||||||
|
|
||||||
public CommandBufferType Type => _type;
|
public CommandBufferType Type => _type;
|
||||||
public bool IsEmpty => _commandCount == 0;
|
public bool IsEmpty => _commandCount == 0;
|
||||||
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get => _name;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_name = value;
|
|
||||||
_commandList.Get()->SetName(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public D3D12CommandBuffer(
|
public D3D12CommandBuffer(
|
||||||
D3D12RenderDevice device,
|
D3D12RenderDevice device,
|
||||||
D3D12PipelineLibrary stateController,
|
D3D12PipelineLibrary stateController,
|
||||||
@@ -52,7 +40,6 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
D3D12DescriptorAllocator descriptorAllocator,
|
D3D12DescriptorAllocator descriptorAllocator,
|
||||||
CommandBufferType type)
|
CommandBufferType type)
|
||||||
{
|
{
|
||||||
_name = string.Empty;
|
|
||||||
_type = type;
|
_type = type;
|
||||||
|
|
||||||
ID3D12CommandAllocator* pAllocator = default;
|
ID3D12CommandAllocator* pAllocator = default;
|
||||||
@@ -63,7 +50,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
device.NativeDevice->CreateCommandList1(0u, commandListType, D3D12_COMMAND_LIST_FLAG_NONE, __uuidof(pCommandList), (void**)&pCommandList);
|
device.NativeDevice->CreateCommandList1(0u, commandListType, D3D12_COMMAND_LIST_FLAG_NONE, __uuidof(pCommandList), (void**)&pCommandList);
|
||||||
|
|
||||||
_allocator.Attach(pAllocator);
|
_allocator.Attach(pAllocator);
|
||||||
_commandList.Attach(pCommandList);
|
nativeObject.Attach(pCommandList);
|
||||||
|
|
||||||
_pipelineLibrary = stateController;
|
_pipelineLibrary = stateController;
|
||||||
_resourceDatabase = resourceDatabase;
|
_resourceDatabase = resourceDatabase;
|
||||||
@@ -71,12 +58,6 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
_descriptorAllocator = descriptorAllocator;
|
_descriptorAllocator = descriptorAllocator;
|
||||||
|
|
||||||
_isRecording = false;
|
_isRecording = false;
|
||||||
_disposed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
~D3D12CommandBuffer()
|
|
||||||
{
|
|
||||||
Dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static D3D12_COMMAND_LIST_TYPE ConvertCommandBufferType(CommandBufferType type)
|
private static D3D12_COMMAND_LIST_TYPE ConvertCommandBufferType(CommandBufferType type)
|
||||||
@@ -90,12 +71,6 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
private void ThrowIfDisposed()
|
|
||||||
{
|
|
||||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void ThrowIfRecording()
|
private void ThrowIfRecording()
|
||||||
{
|
{
|
||||||
@@ -125,7 +100,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
void ResetCommandList()
|
void ResetCommandList()
|
||||||
{
|
{
|
||||||
ThrowIfFailed(_allocator.Get()->Reset());
|
ThrowIfFailed(_allocator.Get()->Reset());
|
||||||
ThrowIfFailed(_commandList.Get()->Reset(_allocator.Get(), null));
|
ThrowIfFailed(nativeObject.Get()->Reset(_allocator.Get(), null));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetBindlessHeap()
|
void SetBindlessHeap()
|
||||||
@@ -133,7 +108,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
var heaps = stackalloc ID3D12DescriptorHeap*[2];
|
var heaps = stackalloc ID3D12DescriptorHeap*[2];
|
||||||
heaps[0] = _descriptorAllocator.GetCbvSrvUavHeap(); // Bindless resource heap
|
heaps[0] = _descriptorAllocator.GetCbvSrvUavHeap(); // Bindless resource heap
|
||||||
heaps[1] = _descriptorAllocator.GetSamplerHeap(); // Bindless sampler heap
|
heaps[1] = _descriptorAllocator.GetSamplerHeap(); // Bindless sampler heap
|
||||||
_commandList.Get()->SetDescriptorHeaps(2, heaps);
|
nativeObject.Get()->SetDescriptorHeaps(2, heaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
@@ -151,7 +126,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
|
|
||||||
_commandList.Get()->Close();
|
nativeObject.Get()->Close();
|
||||||
_isRecording = false;
|
_isRecording = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,8 +136,8 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
IncrementCommandCount();
|
IncrementCommandCount();
|
||||||
|
|
||||||
var d3d12Rect = new RECT((int)rect.left, (int)rect.top, (int)rect.right, (int)rect.bottom);
|
var d3d12Rect = new RECT((int)rect.Left, (int)rect.Top, (int)rect.Right, (int)rect.Bottom);
|
||||||
_commandList.Get()->RSSetScissorRects(1, &d3d12Rect);
|
nativeObject.Get()->RSSetScissorRects(1, &d3d12Rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResourceBarrier(Handle<GPUResource> resource, ResourceState before, ResourceState after)
|
public void ResourceBarrier(Handle<GPUResource> resource, ResourceState before, ResourceState after)
|
||||||
@@ -175,7 +150,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
var barrier = D3D12_RESOURCE_BARRIER.InitTransition(d3d12Resource,
|
var barrier = D3D12_RESOURCE_BARRIER.InitTransition(d3d12Resource,
|
||||||
before.ToD3D12States(), after.ToD3D12States());
|
before.ToD3D12States(), after.ToD3D12States());
|
||||||
|
|
||||||
_commandList.Get()->ResourceBarrier(1, &barrier);
|
nativeObject.Get()->ResourceBarrier(1, &barrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetRenderTargets(ReadOnlySpan<Handle<Texture>> renderTargets, Handle<Texture> depthTarget)
|
public void SetRenderTargets(ReadOnlySpan<Handle<Texture>> renderTargets, Handle<Texture> depthTarget)
|
||||||
@@ -203,7 +178,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
pDsvHandle[0] = _descriptorAllocator.GetCpuHandle(_resourceDatabase.GetResourceInfo(depthTarget.AsResource()).viewGroup.dsv);
|
pDsvHandle[0] = _descriptorAllocator.GetCpuHandle(_resourceDatabase.GetResourceInfo(depthTarget.AsResource()).viewGroup.dsv);
|
||||||
}
|
}
|
||||||
|
|
||||||
_commandList.Get()->OMSetRenderTargets((uint)renderTargets.Length, pRtvHandles, FALSE, pDsvHandle);
|
nativeObject.Get()->OMSetRenderTargets((uint)renderTargets.Length, pRtvHandles, FALSE, pDsvHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BeginRenderPass(ReadOnlySpan<PassRenderTargetDesc> rtDescs, PassDepthStencilDesc depthDesc, bool allowUAVWrites = false)
|
public void BeginRenderPass(ReadOnlySpan<PassRenderTargetDesc> rtDescs, PassDepthStencilDesc depthDesc, bool allowUAVWrites = false)
|
||||||
@@ -216,12 +191,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
for (var i = 0; i < rtDescs.Length; i++)
|
for (var i = 0; i < rtDescs.Length; i++)
|
||||||
{
|
{
|
||||||
var rtDesc = rtDescs[i];
|
var rtDesc = rtDescs[i];
|
||||||
if (!rtDesc.texture.IsValid)
|
if (!rtDesc.Texture.IsValid)
|
||||||
{
|
{
|
||||||
throw new ArgumentException($"Render target at index {i} is not a valid texture handle");
|
throw new ArgumentException($"Render target at index {i} is not a valid texture handle");
|
||||||
}
|
}
|
||||||
|
|
||||||
var resourceInfo = _resourceDatabase.GetResourceInfo(rtDesc.texture.AsResource());
|
var resourceInfo = _resourceDatabase.GetResourceInfo(rtDesc.Texture.AsResource());
|
||||||
var cpuHandle = _descriptorAllocator.GetCpuHandle(resourceInfo.viewGroup.rtv);
|
var cpuHandle = _descriptorAllocator.GetCpuHandle(resourceInfo.viewGroup.rtv);
|
||||||
|
|
||||||
var desc = new D3D12_RENDER_PASS_RENDER_TARGET_DESC
|
var desc = new D3D12_RENDER_PASS_RENDER_TARGET_DESC
|
||||||
@@ -234,24 +209,24 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
{
|
{
|
||||||
ClearValue = new D3D12_CLEAR_VALUE
|
ClearValue = new D3D12_CLEAR_VALUE
|
||||||
{
|
{
|
||||||
Format = resourceInfo.desc.textureDescription.Format.ToDXGIFormat(),
|
Format = resourceInfo.desc.TextureDescription.Format.ToDXGIFormat(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
desc.BeginningAccess.Clear.ClearValue.Color[0] = rtDesc.clearColor.r;
|
desc.BeginningAccess.Clear.ClearValue.Color[0] = rtDesc.ClearColor.r;
|
||||||
desc.BeginningAccess.Clear.ClearValue.Color[1] = rtDesc.clearColor.g;
|
desc.BeginningAccess.Clear.ClearValue.Color[1] = rtDesc.ClearColor.g;
|
||||||
desc.BeginningAccess.Clear.ClearValue.Color[2] = rtDesc.clearColor.b;
|
desc.BeginningAccess.Clear.ClearValue.Color[2] = rtDesc.ClearColor.b;
|
||||||
desc.BeginningAccess.Clear.ClearValue.Color[3] = rtDesc.clearColor.a;
|
desc.BeginningAccess.Clear.ClearValue.Color[3] = rtDesc.ClearColor.a;
|
||||||
|
|
||||||
pRtvDescs[i] = desc;
|
pRtvDescs[i] = desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
var pDsvDesc = stackalloc D3D12_RENDER_PASS_DEPTH_STENCIL_DESC[depthDesc.texture.IsValid ? 1 : 0];
|
var pDsvDesc = stackalloc D3D12_RENDER_PASS_DEPTH_STENCIL_DESC[depthDesc.Texture.IsValid ? 1 : 0];
|
||||||
if (pDsvDesc != null)
|
if (pDsvDesc != null)
|
||||||
{
|
{
|
||||||
var resourceInfo = _resourceDatabase.GetResourceInfo(depthDesc.texture.AsResource());
|
var resourceInfo = _resourceDatabase.GetResourceInfo(depthDesc.Texture.AsResource());
|
||||||
var cpuHandle = _descriptorAllocator.GetCpuHandle(resourceInfo.viewGroup.dsv);
|
var cpuHandle = _descriptorAllocator.GetCpuHandle(resourceInfo.viewGroup.dsv);
|
||||||
|
|
||||||
var desc = new D3D12_RENDER_PASS_DEPTH_STENCIL_DESC
|
var desc = new D3D12_RENDER_PASS_DEPTH_STENCIL_DESC
|
||||||
@@ -264,11 +239,11 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
{
|
{
|
||||||
ClearValue = new D3D12_CLEAR_VALUE
|
ClearValue = new D3D12_CLEAR_VALUE
|
||||||
{
|
{
|
||||||
Format = resourceInfo.desc.textureDescription.Format.ToDXGIFormat(),
|
Format = resourceInfo.desc.TextureDescription.Format.ToDXGIFormat(),
|
||||||
DepthStencil = new D3D12_DEPTH_STENCIL_VALUE
|
DepthStencil = new D3D12_DEPTH_STENCIL_VALUE
|
||||||
{
|
{
|
||||||
Depth = depthDesc.clearDepth,
|
Depth = depthDesc.ClearDepth,
|
||||||
Stencil = depthDesc.clearStencil
|
Stencil = depthDesc.ClearStencil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -278,7 +253,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
pDsvDesc[0] = desc;
|
pDsvDesc[0] = desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
_commandList.Get()->BeginRenderPass((uint)rtDescs.Length, pRtvDescs, pDsvDesc,
|
nativeObject.Get()->BeginRenderPass((uint)rtDescs.Length, pRtvDescs, pDsvDesc,
|
||||||
allowUAVWrites ? D3D12_RENDER_PASS_FLAG_ALLOW_UAV_WRITES : D3D12_RENDER_PASS_FLAG_NONE);
|
allowUAVWrites ? D3D12_RENDER_PASS_FLAG_ALLOW_UAV_WRITES : D3D12_RENDER_PASS_FLAG_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,7 +263,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
IncrementCommandCount();
|
IncrementCommandCount();
|
||||||
|
|
||||||
_commandList.Get()->EndRenderPass();
|
nativeObject.Get()->EndRenderPass();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetViewport(ViewportDesc viewport)
|
public void SetViewport(ViewportDesc viewport)
|
||||||
@@ -297,8 +272,8 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
IncrementCommandCount();
|
IncrementCommandCount();
|
||||||
|
|
||||||
var d3d12Viewport = new D3D12_VIEWPORT(viewport.width, viewport.height, viewport.x, viewport.y, viewport.minDepth, viewport.maxDepth);
|
var d3d12Viewport = new D3D12_VIEWPORT(viewport.Width, viewport.Height, viewport.X, viewport.Y, viewport.MinDepth, viewport.MaxDepth);
|
||||||
_commandList.Get()->RSSetViewports(1, &d3d12Viewport);
|
nativeObject.Get()->RSSetViewports(1, &d3d12Viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPipelineState(GraphicsPipelineKey pipelineKey)
|
public void SetPipelineState(GraphicsPipelineKey pipelineKey)
|
||||||
@@ -308,7 +283,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
IncrementCommandCount();
|
IncrementCommandCount();
|
||||||
|
|
||||||
var shaderPipeline = _pipelineLibrary.GetGraphicsPSO(pipelineKey).GetValueOrThrow();
|
var shaderPipeline = _pipelineLibrary.GetGraphicsPSO(pipelineKey).GetValueOrThrow();
|
||||||
_commandList.Get()->SetPipelineState(shaderPipeline.value);
|
nativeObject.Get()->SetPipelineState(shaderPipeline.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetConstantBufferView(uint slot, Handle<GraphicsBuffer> buffer)
|
public void SetConstantBufferView(uint slot, Handle<GraphicsBuffer> buffer)
|
||||||
@@ -318,7 +293,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
IncrementCommandCount();
|
IncrementCommandCount();
|
||||||
|
|
||||||
var resource = _resourceDatabase.GetResource(buffer.AsResource());
|
var resource = _resourceDatabase.GetResource(buffer.AsResource());
|
||||||
_commandList.Get()->SetGraphicsRootConstantBufferView(RootSignatureLayout.PER_MATERIAL_BUFFER_SLOT, resource->GetGPUVirtualAddress());
|
nativeObject.Get()->SetGraphicsRootConstantBufferView(RootSignatureLayout.PER_MATERIAL_BUFFER_SLOT, resource->GetGPUVirtualAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVertexBuffer(uint slot, Handle<GraphicsBuffer> buffer, ulong offset = 0)
|
public void SetVertexBuffer(uint slot, Handle<GraphicsBuffer> buffer, ulong offset = 0)
|
||||||
@@ -332,10 +307,10 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
{
|
{
|
||||||
BufferLocation = pResource->GetGPUVirtualAddress() + offset,
|
BufferLocation = pResource->GetGPUVirtualAddress() + offset,
|
||||||
SizeInBytes = (uint)(pResource->GetDesc().Width - offset),
|
SizeInBytes = (uint)(pResource->GetDesc().Width - offset),
|
||||||
StrideInBytes = _resourceDatabase.GetResourceDescription(buffer.AsResource()).bufferDescription.Stride
|
StrideInBytes = _resourceDatabase.GetResourceDescription(buffer.AsResource()).BufferDescription.Stride
|
||||||
};
|
};
|
||||||
|
|
||||||
_commandList.Get()->IASetVertexBuffers(slot, 1, &vbView);
|
nativeObject.Get()->IASetVertexBuffers(slot, 1, &vbView);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetIndexBuffer(Handle<GraphicsBuffer> buffer, IndexType type, ulong offset = 0)
|
public void SetIndexBuffer(Handle<GraphicsBuffer> buffer, IndexType type, ulong offset = 0)
|
||||||
@@ -352,7 +327,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
Format = type == IndexType.UInt16 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT
|
Format = type == IndexType.UInt16 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT
|
||||||
};
|
};
|
||||||
|
|
||||||
_commandList.Get()->IASetIndexBuffer(&ibView);
|
nativeObject.Get()->IASetIndexBuffer(&ibView);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPrimitiveTopology(PrimitiveTopology topology)
|
public void SetPrimitiveTopology(PrimitiveTopology topology)
|
||||||
@@ -369,7 +344,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
_ => D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST
|
_ => D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST
|
||||||
};
|
};
|
||||||
|
|
||||||
_commandList.Get()->IASetPrimitiveTopology(d3d12Topology);
|
nativeObject.Get()->IASetPrimitiveTopology(d3d12Topology);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(uint vertexCount, uint instanceCount = 1, uint startVertex = 0, uint startInstance = 0)
|
public void Draw(uint vertexCount, uint instanceCount = 1, uint startVertex = 0, uint startInstance = 0)
|
||||||
@@ -378,7 +353,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
IncrementCommandCount();
|
IncrementCommandCount();
|
||||||
|
|
||||||
_commandList.Get()->DrawInstanced(vertexCount, instanceCount, startVertex, startInstance);
|
nativeObject.Get()->DrawInstanced(vertexCount, instanceCount, startVertex, startInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawIndexed(uint indexCount, uint instanceCount = 1, uint startIndex = 0, int baseVertex = 0, uint startInstance = 0)
|
public void DrawIndexed(uint indexCount, uint instanceCount = 1, uint startIndex = 0, int baseVertex = 0, uint startInstance = 0)
|
||||||
@@ -387,7 +362,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
IncrementCommandCount();
|
IncrementCommandCount();
|
||||||
|
|
||||||
_commandList.Get()->DrawIndexedInstanced(indexCount, instanceCount, startIndex, baseVertex, startInstance);
|
nativeObject.Get()->DrawIndexedInstanced(indexCount, instanceCount, startIndex, baseVertex, startInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DispatchCompute(uint threadGroupCountX, uint threadGroupCountY, uint threadGroupCountZ)
|
public void DispatchCompute(uint threadGroupCountX, uint threadGroupCountY, uint threadGroupCountZ)
|
||||||
@@ -396,7 +371,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
IncrementCommandCount();
|
IncrementCommandCount();
|
||||||
|
|
||||||
_commandList.Get()->Dispatch(threadGroupCountX, threadGroupCountY, threadGroupCountZ);
|
nativeObject.Get()->Dispatch(threadGroupCountX, threadGroupCountY, threadGroupCountZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DispatchMesh(uint threadGroupCountX, uint threadGroupCountY, uint threadGroupCountZ)
|
public void DispatchMesh(uint threadGroupCountX, uint threadGroupCountY, uint threadGroupCountZ)
|
||||||
@@ -405,7 +380,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
ThrowIfNotRecording();
|
ThrowIfNotRecording();
|
||||||
IncrementCommandCount();
|
IncrementCommandCount();
|
||||||
|
|
||||||
_commandList.Get()->DispatchMesh(threadGroupCountX, threadGroupCountY, threadGroupCountZ);
|
nativeObject.Get()->DispatchMesh(threadGroupCountX, threadGroupCountY, threadGroupCountZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DispatchRay()
|
public void DispatchRay()
|
||||||
@@ -416,7 +391,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
// ThrowIfNotRecording();
|
// ThrowIfNotRecording();
|
||||||
// IncrementCommandCount();
|
// IncrementCommandCount();
|
||||||
|
|
||||||
// _commandList.Get()->DispatchRays();
|
// nativeObject.Get()->DispatchRays();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UploadBuffer<T>(Handle<GraphicsBuffer> buffer, ReadOnlySpan<T> data)
|
public void UploadBuffer<T>(Handle<GraphicsBuffer> buffer, ReadOnlySpan<T> data)
|
||||||
@@ -441,7 +416,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
|
|
||||||
var pResource = _resourceDatabase.GetResource(buffer.AsResource());
|
var pResource = _resourceDatabase.GetResource(buffer.AsResource());
|
||||||
|
|
||||||
_commandList.Get()->CopyBufferRegion(pResource, 0, pUploadResource, 0, sizeInBytes);
|
nativeObject.Get()->CopyBufferRegion(pResource, 0, pUploadResource, 0, sizeInBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UploadTexture(Handle<Texture> texture, params ReadOnlySpan<SubResourceData> subresources)
|
public void UploadTexture(Handle<Texture> texture, params ReadOnlySpan<SubResourceData> subresources)
|
||||||
@@ -470,7 +445,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
}
|
}
|
||||||
|
|
||||||
UpdateSubresources(
|
UpdateSubresources(
|
||||||
(ID3D12GraphicsCommandList*)_commandList.Get(),
|
(ID3D12GraphicsCommandList*)nativeObject.Get(),
|
||||||
pResource,
|
pResource,
|
||||||
pUploadResource,
|
pUploadResource,
|
||||||
0,
|
0,
|
||||||
@@ -494,17 +469,17 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
|
|
||||||
if (numBytes == 0)
|
if (numBytes == 0)
|
||||||
{
|
{
|
||||||
_commandList.Get()->CopyResource(pDestResource, pSrcResource);
|
nativeObject.Get()->CopyResource(pDestResource, pSrcResource);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_commandList.Get()->CopyBufferRegion(pDestResource, destOffset, pSrcResource, srcOffset, numBytes);
|
nativeObject.Get()->CopyBufferRegion(pDestResource, destOffset, pSrcResource, srcOffset, numBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (_disposed)
|
if (IsDisposed)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -514,12 +489,9 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
|||||||
throw new InvalidOperationException("Command buffer is still recording");
|
throw new InvalidOperationException("Command buffer is still recording");
|
||||||
}
|
}
|
||||||
|
|
||||||
_commandList.Dispose();
|
MemoryLeakException.ThrowIfRefCountNonZero(_allocator.Reset());
|
||||||
_allocator.Dispose();
|
|
||||||
_isRecording = false;
|
|
||||||
_commandCount = 0;
|
_commandCount = 0;
|
||||||
_disposed = true;
|
|
||||||
|
|
||||||
GC.SuppressFinalize(this);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using Ghost.Core;
|
using Ghost.Core;
|
||||||
using Ghost.Core.Graphics;
|
using Ghost.Core.Graphics;
|
||||||
using Ghost.Core.Utilities;
|
using Ghost.Core.Utilities;
|
||||||
|
using Ghost.Graphics.Core;
|
||||||
using Ghost.Graphics.D3D12.Utilities;
|
using Ghost.Graphics.D3D12.Utilities;
|
||||||
using Ghost.Graphics.RHI;
|
using Ghost.Graphics.RHI;
|
||||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
@@ -45,14 +46,6 @@ internal struct D3D12PipelineState : IDisposable
|
|||||||
|
|
||||||
internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
||||||
{
|
{
|
||||||
private const int rootParamCount =
|
|
||||||
#if USE_TRADITIONAL_BINDLESS
|
|
||||||
6
|
|
||||||
#else
|
|
||||||
4
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
|
|
||||||
private readonly D3D12RenderDevice _device;
|
private readonly D3D12RenderDevice _device;
|
||||||
private readonly D3D12ResourceDatabase _resourceDatabase;
|
private readonly D3D12ResourceDatabase _resourceDatabase;
|
||||||
|
|
||||||
@@ -81,7 +74,7 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
|||||||
_defaultRootSignature = default;
|
_defaultRootSignature = default;
|
||||||
|
|
||||||
// NOTE: Since we are targeting SM 6.6, we can use ResourceDescriptorHeap and SamplerDescriptorHeap directly without needing to set up viewGroup tables.
|
// NOTE: Since we are targeting SM 6.6, we can use ResourceDescriptorHeap and SamplerDescriptorHeap directly without needing to set up viewGroup tables.
|
||||||
var rootParameters = stackalloc D3D12_ROOT_PARAMETER1[rootParamCount];
|
var rootParameters = stackalloc D3D12_ROOT_PARAMETER1[RootSignatureLayout.ROOT_PARAMETER_COUNT];
|
||||||
rootParameters[0] = new D3D12_ROOT_PARAMETER1
|
rootParameters[0] = new D3D12_ROOT_PARAMETER1
|
||||||
{
|
{
|
||||||
ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV,
|
ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV,
|
||||||
@@ -144,7 +137,7 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
|||||||
|
|
||||||
var rootSignatureDesc = new D3D12_ROOT_SIGNATURE_DESC1
|
var rootSignatureDesc = new D3D12_ROOT_SIGNATURE_DESC1
|
||||||
{
|
{
|
||||||
NumParameters = rootParamCount,
|
NumParameters = RootSignatureLayout.ROOT_PARAMETER_COUNT,
|
||||||
pParameters = rootParameters,
|
pParameters = rootParameters,
|
||||||
NumStaticSamplers = 0,
|
NumStaticSamplers = 0,
|
||||||
pStaticSamplers = null,
|
pStaticSamplers = null,
|
||||||
@@ -215,19 +208,38 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
|||||||
fs.Write(buffer.AsSpan());
|
fs.Write(buffer.AsSpan());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CBufferInfo ValidateReflectionData(FullPassDescriptor descriptor, ShaderReflectionData reflectionData)
|
private static Result<CBufferInfo> ValidateReflectionData(FullPassDescriptor descriptor, ShaderReflectionData reflectionData)
|
||||||
{
|
{
|
||||||
if (reflectionData.ConstantBuffers.Count != rootParamCount)
|
CBufferInfo cbufferInfo = default;
|
||||||
|
|
||||||
|
foreach (var info in reflectionData.ResourcesBindings)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException($"Shader reflection data has {reflectionData.ConstantBuffers.Count} constant buffers, expected {rootParamCount}");
|
if (info.BindPoint > 3)
|
||||||
|
{
|
||||||
|
return Result.Fail($"Resource binding point {info.BindPoint} is out of range. Only binding points 0-3 are supported in the current root signature.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.Type != D3D_SHADER_INPUT_TYPE.D3D_SIT_CBUFFER)
|
||||||
|
{
|
||||||
|
return Result.Fail($"Resource binding type {info.Type} is not supported. Only constant buffers are supported in the current root signature.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.BindPoint == RootSignatureLayout.PER_MATERIAL_BUFFER_SLOT)
|
||||||
|
{
|
||||||
|
cbufferInfo = new CBufferInfo
|
||||||
|
{
|
||||||
|
Name = info.Name,
|
||||||
|
RegisterSlot = info.BindPoint,
|
||||||
|
RegisterSpace = info.Space,
|
||||||
|
SizeInBytes = info.Size,
|
||||||
|
Properties = info.Properties ?? Array.Empty<CBufferPropertyInfo>(),
|
||||||
|
};
|
||||||
|
|
||||||
|
return Result.Success(cbufferInfo);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reflectionData.OtherResources.Count != 0)
|
return Result.Fail("Per-material constant buffer not found in shader reflection data.");
|
||||||
{
|
|
||||||
throw new NotSupportedException("Shader reflection data contains unsupported resource types. Only constant buffers are supported in the current root signature.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return reflectionData.ConstantBuffers[RootSignatureLayout.PER_MATERIAL_BUFFER_SLOT];
|
|
||||||
|
|
||||||
// TODO: Validate Cbuffer sizes and bindings.
|
// TODO: Validate Cbuffer sizes and bindings.
|
||||||
}
|
}
|
||||||
@@ -242,11 +254,11 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// TODO: This does not include generated code. This will cause a root signature mismatch.
|
// TODO: This does not include generated code. This will cause a root signature mismatch.
|
||||||
var result = D3D12ShaderCompiler.Compile(ref config, Allocator.Persistent, &reflectionBlob).GetValueOrThrow();
|
var result = D3D12ShaderCompiler.Compile(ref config, Allocator.Persistent, (void**)&reflectionBlob).GetValueOrThrow();
|
||||||
if (reflectionBlob != null)
|
if (reflectionBlob != null)
|
||||||
{
|
{
|
||||||
var reflection = D3D12ShaderCompiler.PerformDXCReflection(reflectionBlob).GetValueOrThrow();
|
var reflection = D3D12ShaderCompiler.PerformDXCReflection(reflectionBlob).GetValueOrThrow();
|
||||||
cbufferInfo = ValidateReflectionData(descriptor, reflection);
|
cbufferInfo = ValidateReflectionData(descriptor, reflection).GetValueOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -361,7 +373,7 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
|||||||
|
|
||||||
private GraphicsPipelineKey CompilePSO(ref readonly GraphicsPSODescriptor descriptor, ref readonly D3D12GraphicsCompiledResult compiled)
|
private GraphicsPipelineKey CompilePSO(ref readonly GraphicsPSODescriptor descriptor, ref readonly D3D12GraphicsCompiledResult compiled)
|
||||||
{
|
{
|
||||||
var rtvCount = (uint)Math.Min(descriptor.rtvFormats.Length, D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT);
|
var rtvCount = (uint)Math.Min(descriptor.RtvFormats.Length, D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT);
|
||||||
|
|
||||||
var desc = new D3DX12_MESH_SHADER_PIPELINE_STATE_DESC
|
var desc = new D3DX12_MESH_SHADER_PIPELINE_STATE_DESC
|
||||||
{
|
{
|
||||||
@@ -372,12 +384,12 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
|||||||
SampleMask = UINT32_MAX,
|
SampleMask = UINT32_MAX,
|
||||||
SampleDesc = new DXGI_SAMPLE_DESC(1, 0),
|
SampleDesc = new DXGI_SAMPLE_DESC(1, 0),
|
||||||
NumRenderTargets = rtvCount,
|
NumRenderTargets = rtvCount,
|
||||||
DSVFormat = descriptor.dsvFormat.ToDXGIFormat(),
|
DSVFormat = descriptor.DsvFormat.ToDXGIFormat(),
|
||||||
DepthStencilState = BuildDepthStencil(descriptor.zTest, descriptor.zWrite),
|
DepthStencilState = BuildDepthStencil(descriptor.ZTest, descriptor.ZWrite),
|
||||||
NodeMask = 0,
|
NodeMask = 0,
|
||||||
Flags = D3D12_PIPELINE_STATE_FLAG_NONE,
|
Flags = D3D12_PIPELINE_STATE_FLAG_NONE,
|
||||||
|
|
||||||
BlendState = descriptor.blend switch
|
BlendState = descriptor.Blend switch
|
||||||
{
|
{
|
||||||
BlendOptions.Opaque => D3D12Utility.D3D12_BLEND_DESC_OPAQUE,
|
BlendOptions.Opaque => D3D12Utility.D3D12_BLEND_DESC_OPAQUE,
|
||||||
BlendOptions.Alpha => D3D12Utility.D3D12_BLEND_DESC_ALPHA_BLEND,
|
BlendOptions.Alpha => D3D12Utility.D3D12_BLEND_DESC_ALPHA_BLEND,
|
||||||
@@ -386,7 +398,7 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
|||||||
BlendOptions.PremultipliedAlpha => D3D12Utility.D3D12_BLEND_DESC_PREMULTIPLIED,
|
BlendOptions.PremultipliedAlpha => D3D12Utility.D3D12_BLEND_DESC_PREMULTIPLIED,
|
||||||
_ => D3D12Utility.D3D12_BLEND_DESC_OPAQUE
|
_ => D3D12Utility.D3D12_BLEND_DESC_OPAQUE
|
||||||
},
|
},
|
||||||
RasterizerState = descriptor.cull switch
|
RasterizerState = descriptor.Cull switch
|
||||||
{
|
{
|
||||||
CullOptions.Off => D3D12Utility.D3D12_RASTERIZER_DESC_CULL_NONE,
|
CullOptions.Off => D3D12Utility.D3D12_RASTERIZER_DESC_CULL_NONE,
|
||||||
CullOptions.Front => D3D12Utility.D3D12_RASTERIZER_DESC_CULL_CLOCKWISE,
|
CullOptions.Front => D3D12Utility.D3D12_RASTERIZER_DESC_CULL_CLOCKWISE,
|
||||||
@@ -402,16 +414,16 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
|||||||
|
|
||||||
var hash = new GraphicsPipelineHash
|
var hash = new GraphicsPipelineHash
|
||||||
{
|
{
|
||||||
id = descriptor.passId,
|
Id = descriptor.PassId,
|
||||||
rtvCount = (uint)descriptor.rtvFormats.Length,
|
RtvCount = (uint)descriptor.RtvFormats.Length,
|
||||||
dsvFormat = descriptor.dsvFormat,
|
DsvFormat = descriptor.DsvFormat,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (var i = 0; i < rtvCount && i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
|
for (var i = 0; i < rtvCount && i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
|
||||||
{
|
{
|
||||||
desc.RTVFormats[i] = descriptor.rtvFormats[i].ToDXGIFormat();
|
desc.RTVFormats[i] = descriptor.RtvFormats[i].ToDXGIFormat();
|
||||||
desc.BlendState.RenderTarget[i].RenderTargetWriteMask = (byte)(descriptor.colorMask & 0x0F);
|
desc.BlendState.RenderTarget[i].RenderTargetWriteMask = (byte)(descriptor.ColorMask & 0x0F);
|
||||||
hash.rtvFormats[i] = descriptor.rtvFormats[i];
|
hash.RtvFormats[i] = descriptor.RtvFormats[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
var key = hash.GetKey();
|
var key = hash.GetKey();
|
||||||
@@ -468,15 +480,15 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
|||||||
|
|
||||||
var psoDes = new GraphicsPSODescriptor
|
var psoDes = new GraphicsPSODescriptor
|
||||||
{
|
{
|
||||||
passId = new ShaderPassKey(fullPass.Identifier),
|
PassId = new ShaderPassKey(fullPass.Identifier),
|
||||||
zTest = fullPass.localPipeline.zTest,
|
ZTest = fullPass.localPipeline.zTest,
|
||||||
zWrite = fullPass.localPipeline.zWrite,
|
ZWrite = fullPass.localPipeline.zWrite,
|
||||||
cull = fullPass.localPipeline.cull,
|
Cull = fullPass.localPipeline.cull,
|
||||||
blend = fullPass.localPipeline.blend,
|
Blend = fullPass.localPipeline.blend,
|
||||||
colorMask = fullPass.localPipeline.colorMask,
|
ColorMask = fullPass.localPipeline.colorMask,
|
||||||
|
|
||||||
rtvFormats = rtvs,
|
RtvFormats = rtvs,
|
||||||
dsvFormat = dsv,
|
DsvFormat = dsv,
|
||||||
};
|
};
|
||||||
|
|
||||||
key = CompilePSO(in psoDes, in compiled);
|
key = CompilePSO(in psoDes, in compiled);
|
||||||
|
|||||||
67
Ghost.Graphics/D3D12/D3D12RHIObject.cs
Normal file
67
Ghost.Graphics/D3D12/D3D12RHIObject.cs
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
using Ghost.Graphics.D3D12.Utilities;
|
||||||
|
using Ghost.Graphics.RHI;
|
||||||
|
using Misaki.HighPerformance.LowLevel;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using TerraFX.Interop.DirectX;
|
||||||
|
using TerraFX.Interop.Windows;
|
||||||
|
|
||||||
|
namespace Ghost.Graphics.D3D12;
|
||||||
|
|
||||||
|
internal abstract unsafe class D3D12RHIObject<T> : IRHIObject, IDisposable
|
||||||
|
where T : unmanaged, ID3D12Object.Interface
|
||||||
|
{
|
||||||
|
private bool _disposed;
|
||||||
|
private string _name = string.Empty;
|
||||||
|
|
||||||
|
protected ComPtr<T> nativeObject;
|
||||||
|
|
||||||
|
protected bool IsDisposed => _disposed;
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get => _name;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_name == value)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_name = value;
|
||||||
|
if (nativeObject.Get() != null)
|
||||||
|
{
|
||||||
|
nativeObject.Get()->SetName(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
~D3D12RHIObject()
|
||||||
|
{
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
protected void ThrowIfDisposed()
|
||||||
|
{
|
||||||
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MemoryLeakException.ThrowIfRefCountNonZero(nativeObject.Reset());
|
||||||
|
|
||||||
|
_disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -199,15 +199,15 @@ internal unsafe class D3D12Renderer : IRenderer
|
|||||||
Span<PassRenderTargetDesc> rtDesc = stackalloc PassRenderTargetDesc[1];
|
Span<PassRenderTargetDesc> rtDesc = stackalloc PassRenderTargetDesc[1];
|
||||||
rtDesc[0] = new PassRenderTargetDesc
|
rtDesc[0] = new PassRenderTargetDesc
|
||||||
{
|
{
|
||||||
texture = target,
|
Texture = target,
|
||||||
clearColor = clearColor,
|
ClearColor = clearColor,
|
||||||
};
|
};
|
||||||
|
|
||||||
var depthDesc = new PassDepthStencilDesc
|
var depthDesc = new PassDepthStencilDesc
|
||||||
{
|
{
|
||||||
texture = Handle<Texture>.Invalid,
|
Texture = Handle<Texture>.Invalid,
|
||||||
clearDepth = 1.0f,
|
ClearDepth = 1.0f,
|
||||||
clearStencil = 0,
|
ClearStencil = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: Testing only.
|
// NOTE: Testing only.
|
||||||
@@ -219,8 +219,8 @@ internal unsafe class D3D12Renderer : IRenderer
|
|||||||
|
|
||||||
cmd.BeginRenderPass(rtDesc, depthDesc, false);
|
cmd.BeginRenderPass(rtDesc, depthDesc, false);
|
||||||
|
|
||||||
var viewport = new ViewportDesc { width = _currentSize.x, height = _currentSize.y, minDepth = 0, maxDepth = 1 };
|
var viewport = new ViewportDesc { Width = _currentSize.x, Height = _currentSize.y, MinDepth = 0, MaxDepth = 1 };
|
||||||
var scissor = new RectDesc { right = _currentSize.x, bottom = _currentSize.y };
|
var scissor = new RectDesc { Right = _currentSize.x, Bottom = _currentSize.y };
|
||||||
|
|
||||||
cmd.SetViewport(viewport);
|
cmd.SetViewport(viewport);
|
||||||
cmd.SetScissorRect(scissor);
|
cmd.SetScissorRect(scissor);
|
||||||
|
|||||||
@@ -10,70 +10,7 @@ using static TerraFX.Interop.DirectX.DXC;
|
|||||||
|
|
||||||
namespace Ghost.Graphics.D3D12;
|
namespace Ghost.Graphics.D3D12;
|
||||||
|
|
||||||
internal struct CompileResult : IDisposable
|
internal partial class D3D12ShaderCompiler
|
||||||
{
|
|
||||||
public UnsafeArray<byte> bytecode;
|
|
||||||
|
|
||||||
public readonly bool IsCreated => bytecode.IsCreated;
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
bytecode.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal readonly struct ResourceBindingInfo
|
|
||||||
{
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get; init;
|
|
||||||
}
|
|
||||||
|
|
||||||
public D3D_SHADER_INPUT_TYPE Type
|
|
||||||
{
|
|
||||||
get; init;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint BindPoint
|
|
||||||
{
|
|
||||||
get; init;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint BindCount
|
|
||||||
{
|
|
||||||
get; init;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint Space
|
|
||||||
{
|
|
||||||
get; init;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal readonly struct ShaderReflectionData
|
|
||||||
{
|
|
||||||
public List<CBufferInfo> ConstantBuffers
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ResourceBindingInfo> OtherResources
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
}
|
|
||||||
|
|
||||||
// public List<ResourceBindingInfo> Samplers { get; } = new();
|
|
||||||
// public List<ResourceBindingInfo> ShaderResourceViews { get; } = new();
|
|
||||||
// public List<ResourceBindingInfo> UnorderedAccessViews { get; } = new();
|
|
||||||
|
|
||||||
public ShaderReflectionData()
|
|
||||||
{
|
|
||||||
ConstantBuffers = new List<CBufferInfo>();
|
|
||||||
OtherResources = new List<ResourceBindingInfo>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static unsafe class D3D12ShaderCompiler
|
|
||||||
{
|
{
|
||||||
private static string GetProfileString(ShaderStage stage, CompilerTier version)
|
private static string GetProfileString(ShaderStage stage, CompilerTier version)
|
||||||
{
|
{
|
||||||
@@ -150,29 +87,63 @@ internal static unsafe class D3D12ShaderCompiler
|
|||||||
return argsArray;
|
return argsArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Result<CompileResult> Compile(ref readonly CompilerConfig config, Allocator allocator, IDxcBlob** ppReflectionBlob)
|
private static ShaderInputType ToInputType(D3D_SHADER_INPUT_TYPE type)
|
||||||
{
|
{
|
||||||
// NOTE: Should we cache the pCompiler and pUtils instances for better performance?
|
return type switch
|
||||||
|
{
|
||||||
|
D3D_SHADER_INPUT_TYPE.D3D_SIT_CBUFFER => ShaderInputType.ConstantBuffer,
|
||||||
|
D3D_SHADER_INPUT_TYPE.D3D_SIT_TBUFFER => ShaderInputType.Texture,
|
||||||
|
D3D_SHADER_INPUT_TYPE.D3D_SIT_TEXTURE => ShaderInputType.Texture,
|
||||||
|
D3D_SHADER_INPUT_TYPE.D3D_SIT_SAMPLER => ShaderInputType.Sampler,
|
||||||
|
D3D_SHADER_INPUT_TYPE.D3D_SIT_UAV_RWTYPED => ShaderInputType.UAV,
|
||||||
|
D3D_SHADER_INPUT_TYPE.D3D_SIT_STRUCTURED => ShaderInputType.StructuredBuffer,
|
||||||
|
D3D_SHADER_INPUT_TYPE.D3D_SIT_BYTEADDRESS => ShaderInputType.ByteAddressBuffer,
|
||||||
|
D3D_SHADER_INPUT_TYPE.D3D_SIT_UAV_RWSTRUCTURED => ShaderInputType.RWStructuredBuffer,
|
||||||
|
D3D_SHADER_INPUT_TYPE.D3D_SIT_UAV_RWBYTEADDRESS => ShaderInputType.RWByteAddressBuffer,
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(type), "Unsupported shader input type")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal unsafe partial class D3D12ShaderCompiler : IShaderCompiler
|
||||||
|
{
|
||||||
|
private ComPtr<IDxcCompiler3> _compiler;
|
||||||
|
private ComPtr<IDxcUtils> _utils;
|
||||||
|
|
||||||
|
public D3D12ShaderCompiler()
|
||||||
|
{
|
||||||
|
// Initialize DXC _compiler.Get() and _utils.Get()
|
||||||
|
var dxccID = CLSID.CLSID_DxcCompiler;
|
||||||
|
var dxcuID = CLSID.CLSID_DxcUtils;
|
||||||
|
|
||||||
IDxcCompiler3* pCompiler = default;
|
IDxcCompiler3* pCompiler = default;
|
||||||
IDxcUtils* pUtils = default;
|
IDxcUtils* pUtils = default;
|
||||||
|
ThrowIfFailed(DxcCreateInstance(&dxccID, __uuidof(pCompiler), (void**)&pCompiler));
|
||||||
|
ThrowIfFailed(DxcCreateInstance(&dxcuID, __uuidof(pUtils), (void**)&pUtils));
|
||||||
|
|
||||||
|
_compiler.Attach(pCompiler);
|
||||||
|
_utils.Attach(pUtils);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<CompileResult> Compile(ref readonly CompilerConfig config, Allocator allocator, void** ppReflection)
|
||||||
|
{
|
||||||
|
// NOTE: Should we cache the _compiler.Get() and _utils.Get() instances for better performance?
|
||||||
IDxcIncludeHandler* pIncludeHandler = default;
|
IDxcIncludeHandler* pIncludeHandler = default;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Create DXC pCompiler and pUtils
|
// Create DXC _compiler.Get() and _utils.Get()
|
||||||
var dxccID = CLSID.CLSID_DxcCompiler;
|
var dxccID = CLSID.CLSID_DxcCompiler;
|
||||||
var dxcuID = CLSID.CLSID_DxcUtils;
|
var dxcuID = CLSID.CLSID_DxcUtils;
|
||||||
|
|
||||||
ThrowIfFailed(DxcCreateInstance(&dxccID, __uuidof(pCompiler), (void**)&pCompiler));
|
|
||||||
ThrowIfFailed(DxcCreateInstance(&dxcuID, __uuidof(pUtils), (void**)&pUtils));
|
|
||||||
|
|
||||||
ThrowIfFailed(pUtils->CreateDefaultIncludeHandler(&pIncludeHandler));
|
ThrowIfFailed(_utils.Get()->CreateDefaultIncludeHandler(&pIncludeHandler));
|
||||||
|
|
||||||
// Create source blob
|
// Create source blob
|
||||||
using ComPtr<IDxcBlobEncoding> sourceBlob = default;
|
using ComPtr<IDxcBlobEncoding> sourceBlob = default;
|
||||||
fixed (char* pPath = config.shaderPath)
|
fixed (char* pPath = config.shaderPath)
|
||||||
{
|
{
|
||||||
if (pUtils->LoadFile(pPath, null, sourceBlob.GetAddressOf()).FAILED)
|
if (_utils.Get()->LoadFile(pPath, null, sourceBlob.GetAddressOf()).FAILED)
|
||||||
{
|
{
|
||||||
return Result.Fail($"Failed to load shader file: {config.shaderPath}");
|
return Result.Fail($"Failed to load shader file: {config.shaderPath}");
|
||||||
}
|
}
|
||||||
@@ -197,7 +168,7 @@ internal static unsafe class D3D12ShaderCompiler
|
|||||||
Encoding = DXC_CP_UTF8
|
Encoding = DXC_CP_UTF8
|
||||||
};
|
};
|
||||||
|
|
||||||
ThrowIfFailed(pCompiler->Compile(&buffer, argPtrs, (uint)argsArray.Count, pIncludeHandler, __uuidof(pResult), (void**)&pResult));
|
ThrowIfFailed(_compiler.Get()->Compile(&buffer, argPtrs, (uint)argsArray.Count, pIncludeHandler, __uuidof(pResult), (void**)&pResult));
|
||||||
|
|
||||||
// Check compilation pResult
|
// Check compilation pResult
|
||||||
HRESULT hrStatus;
|
HRESULT hrStatus;
|
||||||
@@ -224,9 +195,9 @@ internal static unsafe class D3D12ShaderCompiler
|
|||||||
ThrowIfFailed(pResult->GetResult(bytecodeBlob.GetAddressOf()));
|
ThrowIfFailed(pResult->GetResult(bytecodeBlob.GetAddressOf()));
|
||||||
|
|
||||||
// Get pReflection data using DXC API
|
// Get pReflection data using DXC API
|
||||||
if (ppReflectionBlob != null)
|
if (ppReflection != null)
|
||||||
{
|
{
|
||||||
ThrowIfFailed(pResult->GetOutput(DXC_OUT_KIND.DXC_OUT_REFLECTION, __uuidof<IDxcBlob>(), (void**)ppReflectionBlob, null));
|
ThrowIfFailed(pResult->GetOutput(DXC_OUT_KIND.DXC_OUT_REFLECTION, __uuidof<IDxcBlob>(), ppReflection, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
var bytecodeSize = bytecodeBlob.Get()->GetBufferSize();
|
var bytecodeSize = bytecodeBlob.Get()->GetBufferSize();
|
||||||
@@ -251,39 +222,37 @@ internal static unsafe class D3D12ShaderCompiler
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
pCompiler->Release();
|
|
||||||
pUtils->Release();
|
|
||||||
pIncludeHandler->Release();
|
pIncludeHandler->Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Since we are using fixed root signature layout, the pReflection pass should only validate the layout, not generate it.
|
// TODO: Since we are using fixed root signature layout, the pReflection pass should only validate the layout, not generate it.
|
||||||
// TODO: Ideally this should return a structured pReflection data instead of populating raw lists/dictionaries.
|
// TODO: Ideally this should return a structured pReflection data instead of populating raw lists/dictionaries.
|
||||||
public static Result<ShaderReflectionData> PerformDXCReflection(IDxcBlob* reflectionBlob)
|
public Result<ShaderReflectionData> PerformDXCReflection<T>(T* pReflectionBlob)
|
||||||
|
where T : unmanaged
|
||||||
{
|
{
|
||||||
if (reflectionBlob == null)
|
if (typeof(T) != typeof(IDxcBlob))
|
||||||
{
|
{
|
||||||
return Result<ShaderReflectionData>.Fail("Reflection blob is null.");
|
return Result<ShaderReflectionData>.Fail("Unsupported reflection type. Only IDxcBlob is supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
IDxcUtils* pUtils = default;
|
|
||||||
ID3D12ShaderReflection* pReflection = default;
|
ID3D12ShaderReflection* pReflection = default;
|
||||||
|
IDxcBlob* pDxcReflectionBlob = (IDxcBlob*)pReflectionBlob;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Create DXC pUtils to parse pReflection data
|
// Create DXC _utils.Get() to parse pReflection data
|
||||||
var dxcuID = CLSID.CLSID_DxcUtils;
|
var dxcuID = CLSID.CLSID_DxcUtils;
|
||||||
ThrowIfFailed(DxcCreateInstance(&dxcuID, __uuidof(pUtils), (void**)&pUtils));
|
|
||||||
|
|
||||||
// Create pReflection interface from blob
|
// Create pReflection interface from blob
|
||||||
var reflectionBuffer = new DxcBuffer
|
var reflectionBuffer = new DxcBuffer
|
||||||
{
|
{
|
||||||
Ptr = reflectionBlob->GetBufferPointer(),
|
Ptr = pDxcReflectionBlob->GetBufferPointer(),
|
||||||
Size = reflectionBlob->GetBufferSize(),
|
Size = pDxcReflectionBlob->GetBufferSize(),
|
||||||
Encoding = DXC_CP_ACP
|
Encoding = DXC_CP_ACP
|
||||||
};
|
};
|
||||||
|
|
||||||
ThrowIfFailed(pUtils->CreateReflection(&reflectionBuffer, __uuidof(pReflection), (void**)&pReflection));
|
ThrowIfFailed(_utils.Get()->CreateReflection(&reflectionBuffer, __uuidof(pReflection), (void**)&pReflection));
|
||||||
|
|
||||||
D3D12_SHADER_DESC shaderDesc;
|
D3D12_SHADER_DESC shaderDesc;
|
||||||
ThrowIfFailed(pReflection->GetDesc(&shaderDesc));
|
ThrowIfFailed(pReflection->GetDesc(&shaderDesc));
|
||||||
@@ -301,6 +270,15 @@ internal static unsafe class D3D12ShaderCompiler
|
|||||||
return Result.Fail("Failed to get resource name from reflection data.");
|
return Result.Fail("Failed to get resource name from reflection data.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var info = new ResourceBindingInfo
|
||||||
|
{
|
||||||
|
Name = resourceName,
|
||||||
|
Type = ToInputType(bindDesc.Type),
|
||||||
|
BindPoint = bindDesc.BindPoint,
|
||||||
|
BindCount = bindDesc.BindCount,
|
||||||
|
Space = bindDesc.Space
|
||||||
|
};
|
||||||
|
|
||||||
switch (bindDesc.Type)
|
switch (bindDesc.Type)
|
||||||
{
|
{
|
||||||
case D3D_SHADER_INPUT_TYPE.D3D_SIT_CBUFFER:
|
case D3D_SHADER_INPUT_TYPE.D3D_SIT_CBUFFER:
|
||||||
@@ -332,41 +310,22 @@ internal static unsafe class D3D12ShaderCompiler
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
reflectionData.ConstantBuffers.Add(new CBufferInfo
|
info.Size = cbufferDesc.Size;
|
||||||
{
|
info.Properties = variables;
|
||||||
Name = resourceName,
|
|
||||||
RegisterSlot = bindDesc.BindPoint,
|
|
||||||
RegisterSpace = bindDesc.Space,
|
|
||||||
SizeInBytes = cbufferDesc.Size,
|
|
||||||
Properties = variables
|
|
||||||
});
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Currently we do not support resource bindings yet, everything access through bindless heaps.
|
// NOTE: Currently we do not support resource bindings yet, everything access through bindless heaps.
|
||||||
default:
|
|
||||||
{
|
|
||||||
reflectionData.OtherResources.Add(new ResourceBindingInfo
|
|
||||||
{
|
|
||||||
Name = resourceName,
|
|
||||||
Type = bindDesc.Type,
|
|
||||||
BindPoint = bindDesc.BindPoint,
|
|
||||||
BindCount = bindDesc.BindCount,
|
|
||||||
Space = bindDesc.Space
|
|
||||||
});
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reflectionData.ResourcesBindings.Add(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
return reflectionData;
|
return reflectionData;
|
||||||
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
pUtils->Release();
|
|
||||||
pReflection->Release();
|
pReflection->Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,23 +85,36 @@ internal struct GraphicsPipelineHash
|
|||||||
public TextureFormat rtvFormats;
|
public TextureFormat rtvFormats;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShaderPassKey id;
|
public ShaderPassKey Id
|
||||||
public rtv_array rtvFormats;
|
{
|
||||||
public uint rtvCount;
|
get; set;
|
||||||
public TextureFormat dsvFormat;
|
}
|
||||||
|
|
||||||
|
public rtv_array RtvFormats;
|
||||||
|
|
||||||
|
public uint RtvCount
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextureFormat DsvFormat
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
// Do we need to store blend state?
|
// Do we need to store blend state?
|
||||||
// TODO: Variants
|
// TODO: Variants
|
||||||
|
|
||||||
public readonly GraphicsPipelineKey GetKey()
|
public GraphicsPipelineKey GetKey()
|
||||||
{
|
{
|
||||||
Span<ulong> data = stackalloc ulong[3 + D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT];
|
Span<ulong> data = stackalloc ulong[3 + D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT];
|
||||||
data[0] = id.value;
|
data[0] = Id.value;
|
||||||
data[1] = rtvCount;
|
data[1] = RtvCount;
|
||||||
data[2] = (ulong)dsvFormat;
|
data[2] = (ulong)DsvFormat;
|
||||||
|
|
||||||
for (var i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
|
for (var i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
|
||||||
{
|
{
|
||||||
data[3 + i] = (ulong)rtvFormats[i];
|
data[3 + i] = (ulong)RtvFormats[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
var bytes = MemoryMarshal.AsBytes(data);
|
var bytes = MemoryMarshal.AsBytes(data);
|
||||||
@@ -111,15 +124,46 @@ internal struct GraphicsPipelineHash
|
|||||||
|
|
||||||
public ref struct GraphicsPSODescriptor
|
public ref struct GraphicsPSODescriptor
|
||||||
{
|
{
|
||||||
public ShaderPassKey passId;
|
public ShaderPassKey PassId
|
||||||
public ZTestOptions zTest;
|
{
|
||||||
public ZWriteOptions zWrite;
|
get; set;
|
||||||
public CullOptions cull;
|
}
|
||||||
public BlendOptions blend;
|
|
||||||
public uint colorMask;
|
|
||||||
|
|
||||||
public ReadOnlySpan<TextureFormat> rtvFormats;
|
public ZTestOptions ZTest
|
||||||
public TextureFormat dsvFormat;
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ZWriteOptions ZWrite
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CullOptions Cull
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlendOptions Blend
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint ColorMask
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ReadOnlySpan<TextureFormat> RtvFormats
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextureFormat DsvFormat
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly struct CBufferPropertyInfo
|
public readonly struct CBufferPropertyInfo
|
||||||
@@ -170,20 +214,60 @@ public readonly struct CBufferInfo
|
|||||||
|
|
||||||
public struct ViewportDesc
|
public struct ViewportDesc
|
||||||
{
|
{
|
||||||
public float x;
|
public float X
|
||||||
public float y;
|
{
|
||||||
public float width;
|
get; set;
|
||||||
public float height;
|
}
|
||||||
public float minDepth;
|
|
||||||
public float maxDepth;
|
public float Y
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float Width
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float Height
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float MinDepth
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float MaxDepth
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct RectDesc
|
public struct RectDesc
|
||||||
{
|
{
|
||||||
public uint left;
|
public uint Left
|
||||||
public uint top;
|
{
|
||||||
public uint right;
|
get; set;
|
||||||
public uint bottom;
|
}
|
||||||
|
|
||||||
|
public uint Top
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Right
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Bottom
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct SubResourceData
|
public struct SubResourceData
|
||||||
@@ -195,32 +279,68 @@ public struct SubResourceData
|
|||||||
|
|
||||||
public struct PassRenderTargetDesc
|
public struct PassRenderTargetDesc
|
||||||
{
|
{
|
||||||
public Handle<Texture> texture;
|
public Handle<Texture> Texture
|
||||||
public Color128 clearColor;
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color128 ClearColor
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct PassDepthStencilDesc
|
public struct PassDepthStencilDesc
|
||||||
{
|
{
|
||||||
public Handle<Texture> texture;
|
public Handle<Texture> Texture
|
||||||
public float clearDepth;
|
{
|
||||||
public byte clearStencil;
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float ClearDepth
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte ClearStencil
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Explicit)]
|
|
||||||
public struct ResourceDesc
|
public struct ResourceDesc
|
||||||
{
|
{
|
||||||
[FieldOffset(0)]
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
public TextureDesc textureDescription;
|
private struct resource_union
|
||||||
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public TextureDesc textureDescription;
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public BufferDesc bufferDescription;
|
||||||
|
}
|
||||||
|
|
||||||
[FieldOffset(0)]
|
private resource_union _desc;
|
||||||
public BufferDesc bufferDescription;
|
|
||||||
|
public TextureDesc TextureDescription
|
||||||
|
{
|
||||||
|
readonly get => _desc.textureDescription;
|
||||||
|
set => _desc.textureDescription = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferDesc BufferDescription
|
||||||
|
{
|
||||||
|
readonly get => _desc.bufferDescription;
|
||||||
|
set => _desc.bufferDescription = value;
|
||||||
|
}
|
||||||
|
|
||||||
public static ResourceDesc Buffer(BufferDesc desc)
|
public static ResourceDesc Buffer(BufferDesc desc)
|
||||||
{
|
{
|
||||||
return new ResourceDesc
|
return new ResourceDesc
|
||||||
{
|
{
|
||||||
bufferDescription = desc
|
BufferDescription = desc
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,7 +348,7 @@ public struct ResourceDesc
|
|||||||
{
|
{
|
||||||
return new ResourceDesc
|
return new ResourceDesc
|
||||||
{
|
{
|
||||||
textureDescription = desc
|
TextureDescription = desc
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,8 +391,7 @@ public struct RenderTargetDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public uint Width
|
public uint Width
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -280,8 +399,7 @@ public struct RenderTargetDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public uint Height
|
public uint Height
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -289,8 +407,7 @@ public struct RenderTargetDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public uint Slice
|
public uint Slice
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -298,8 +415,7 @@ public struct RenderTargetDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public RenderTargetType Type
|
public RenderTargetType Type
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -307,8 +423,7 @@ public struct RenderTargetDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public TextureFormat Format
|
public TextureFormat Format
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -316,8 +431,7 @@ public struct RenderTargetDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public TextureDimension Dimension
|
public TextureDimension Dimension
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -325,8 +439,7 @@ public struct RenderTargetDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public RenderTargetCreationFlags CreationFlags
|
public RenderTargetCreationFlags CreationFlags
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -334,8 +447,7 @@ public struct RenderTargetDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public uint MipLevels
|
public uint MipLevels
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -343,8 +455,7 @@ public struct RenderTargetDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public uint SampleCount
|
public uint SampleCount
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -423,8 +534,7 @@ public struct TextureDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public uint Width
|
public uint Width
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -432,8 +542,7 @@ public struct TextureDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public uint Height
|
public uint Height
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -441,8 +550,7 @@ public struct TextureDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public uint Slice
|
public uint Slice
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -450,8 +558,7 @@ public struct TextureDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public TextureFormat Format
|
public TextureFormat Format
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -468,8 +575,7 @@ public struct TextureDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public uint MipLevels
|
public uint MipLevels
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -477,8 +583,7 @@ public struct TextureDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public TextureUsage Usage
|
public TextureUsage Usage
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,14 +597,12 @@ public struct BufferDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ulong Size
|
public ulong Size
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint Stride
|
public uint Stride
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -507,8 +610,7 @@ public struct BufferDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public BufferUsage Usage
|
public BufferUsage Usage
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -516,8 +618,7 @@ public struct BufferDesc
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ResourceMemoryType MemoryType
|
public ResourceMemoryType MemoryType
|
||||||
{
|
{
|
||||||
get;
|
get; set;
|
||||||
set;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -725,49 +826,3 @@ public enum PrimitiveTopology
|
|||||||
Line,
|
Line,
|
||||||
Triangle,
|
Triangle,
|
||||||
}
|
}
|
||||||
|
|
||||||
// SDL compiler
|
|
||||||
|
|
||||||
internal ref struct CompilerConfig
|
|
||||||
{
|
|
||||||
public ReadOnlySpan<string> defines;
|
|
||||||
public string? include;
|
|
||||||
public string shaderPath;
|
|
||||||
public string entryPoint;
|
|
||||||
public ShaderStage stage;
|
|
||||||
public CompilerTier tier;
|
|
||||||
public CompilerOptimizeLevel optimizeLevel;
|
|
||||||
public CompilerOption options;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal enum CompilerTier
|
|
||||||
{
|
|
||||||
Tier0,
|
|
||||||
Tier1,
|
|
||||||
Tier2
|
|
||||||
}
|
|
||||||
|
|
||||||
internal enum CompilerOptimizeLevel
|
|
||||||
{
|
|
||||||
O0,
|
|
||||||
O1,
|
|
||||||
O2,
|
|
||||||
O3
|
|
||||||
}
|
|
||||||
|
|
||||||
[Flags]
|
|
||||||
internal enum CompilerOption
|
|
||||||
{
|
|
||||||
None = 0,
|
|
||||||
KeepDebugInfo = 1 << 0,
|
|
||||||
KeepReflections = 1 << 1,
|
|
||||||
WarnAsError = 1 << 2
|
|
||||||
}
|
|
||||||
|
|
||||||
internal enum ShaderStage
|
|
||||||
{
|
|
||||||
TaskShader,
|
|
||||||
MeshShader,
|
|
||||||
PixelShader,
|
|
||||||
ComputeShader
|
|
||||||
}
|
|
||||||
|
|||||||
130
Ghost.Graphics/RHI/IShaderCompiler.cs
Normal file
130
Ghost.Graphics/RHI/IShaderCompiler.cs
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
using Ghost.Core;
|
||||||
|
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
|
using Misaki.HighPerformance.LowLevel.Collections;
|
||||||
|
|
||||||
|
namespace Ghost.Graphics.RHI;
|
||||||
|
|
||||||
|
public struct CompileResult : IDisposable
|
||||||
|
{
|
||||||
|
public UnsafeArray<byte> bytecode;
|
||||||
|
|
||||||
|
public readonly bool IsCreated => bytecode.IsCreated;
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
bytecode.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ref struct CompilerConfig
|
||||||
|
{
|
||||||
|
public ReadOnlySpan<string> defines;
|
||||||
|
public string? include;
|
||||||
|
public string shaderPath;
|
||||||
|
public string entryPoint;
|
||||||
|
public ShaderStage stage;
|
||||||
|
public CompilerTier tier;
|
||||||
|
public CompilerOptimizeLevel optimizeLevel;
|
||||||
|
public CompilerOption options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CompilerTier
|
||||||
|
{
|
||||||
|
Tier0,
|
||||||
|
Tier1,
|
||||||
|
Tier2
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CompilerOptimizeLevel
|
||||||
|
{
|
||||||
|
O0,
|
||||||
|
O1,
|
||||||
|
O2,
|
||||||
|
O3
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum CompilerOption
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
KeepDebugInfo = 1 << 0,
|
||||||
|
KeepReflections = 1 << 1,
|
||||||
|
WarnAsError = 1 << 2
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ShaderStage
|
||||||
|
{
|
||||||
|
TaskShader,
|
||||||
|
MeshShader,
|
||||||
|
PixelShader,
|
||||||
|
ComputeShader
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ShaderInputType
|
||||||
|
{
|
||||||
|
ConstantBuffer,
|
||||||
|
Texture,
|
||||||
|
Sampler,
|
||||||
|
UAV,
|
||||||
|
StructuredBuffer,
|
||||||
|
ByteAddressBuffer,
|
||||||
|
RWStructuredBuffer,
|
||||||
|
RWByteAddressBuffer
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct ResourceBindingInfo
|
||||||
|
{
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShaderInputType Type
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint BindPoint
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint BindCount
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Space
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Size
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IReadOnlyList<CBufferPropertyInfo>? Properties
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly struct ShaderReflectionData
|
||||||
|
{
|
||||||
|
public List<ResourceBindingInfo> ResourcesBindings
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShaderReflectionData()
|
||||||
|
{
|
||||||
|
ResourcesBindings = new List<ResourceBindingInfo>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe interface IShaderCompiler
|
||||||
|
{
|
||||||
|
Result<CompileResult> Compile(ref readonly CompilerConfig config, Allocator allocator, void** ppReflection);
|
||||||
|
Result<ShaderReflectionData> PerformDXCReflection<T>(T* pReflectionBlob) where T : unmanaged;
|
||||||
|
}
|
||||||
@@ -47,7 +47,7 @@ public interface ISwapChain : IDisposable
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resizes the swap chain back buffers
|
/// Resizes the swap chain back buffers
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="width">New width</param>
|
/// <param name="width">New Width</param>
|
||||||
/// <param name="height">New height</param>
|
/// <param name="height">New Height</param>
|
||||||
public void Resize(uint width, uint height);
|
public void Resize(uint width, uint height);
|
||||||
}
|
}
|
||||||
@@ -27,8 +27,8 @@ void MSMain(
|
|||||||
out indices uint3 outTris[1])
|
out indices uint3 outTris[1])
|
||||||
{
|
{
|
||||||
// Fetch bindless buffers
|
// Fetch bindless buffers
|
||||||
ByteAddressBuffer vertexBuffer = ResourceDescriptorHeap[g_PerMaterialData.vertexBufferIndex];
|
ByteAddressBuffer vertexBuffer = ResourceDescriptorHeap[g_PerObjectData.vertexBuffer];
|
||||||
ByteAddressBuffer indexBuffer = ResourceDescriptorHeap[g_PerMaterialData.indexBufferIndex];
|
ByteAddressBuffer indexBuffer = ResourceDescriptorHeap[g_PerObjectData.indexBuffer];
|
||||||
|
|
||||||
// Compute the triangle’s vertex indices
|
// Compute the triangle’s vertex indices
|
||||||
uint vertexId = groupThreadID.x;
|
uint vertexId = groupThreadID.x;
|
||||||
@@ -46,6 +46,8 @@ void MSMain(
|
|||||||
|
|
||||||
SetMeshOutputCounts(3, 1);
|
SetMeshOutputCounts(3, 1);
|
||||||
|
|
||||||
|
v.position = mul(g_PerViewData.cameraMatrix, mul(g_PerObjectData.localToWorld, v.position));
|
||||||
|
|
||||||
// Write vertex output
|
// Write vertex output
|
||||||
outVerts[vertexId].position = v.position;
|
outVerts[vertexId].position = v.position;
|
||||||
outVerts[vertexId].color = v.color;
|
outVerts[vertexId].color = v.color;
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ shader "MyShader/Standard"
|
|||||||
tex2d_b texture2 = tex2d_b(white);
|
tex2d_b texture2 = tex2d_b(white);
|
||||||
tex2d_b texture3 = tex2d_b(grey);
|
tex2d_b texture3 = tex2d_b(grey);
|
||||||
tex2d_b texture4 = tex2d_b(normal);
|
tex2d_b texture4 = tex2d_b(normal);
|
||||||
uint vertexBufferIndex;
|
|
||||||
uint indexBufferIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline
|
pipeline
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
struct PerViewData
|
struct PerViewData
|
||||||
{
|
{
|
||||||
float4x4 cameraMatrix;
|
float4x4 cameraMatrix;
|
||||||
|
float4x4 cameraInverseMatrix;
|
||||||
float4 screenSize; // xy = size, zw = 1/size
|
float4 screenSize; // xy = size, zw = 1/size
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user