forked from Misaki/GhostEngine
Added IShaderCompiler
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
using Ghost.Core;
|
||||
using Ghost.Core.Graphics;
|
||||
using Ghost.Core.Utilities;
|
||||
using Ghost.Graphics.Core;
|
||||
using Ghost.Graphics.D3D12.Utilities;
|
||||
using Ghost.Graphics.RHI;
|
||||
using Misaki.HighPerformance.LowLevel;
|
||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
||||
using System.Runtime.CompilerServices;
|
||||
using TerraFX.Interop.DirectX;
|
||||
@@ -13,10 +14,9 @@ using static TerraFX.Aliases.DXGI_Alias;
|
||||
|
||||
namespace Ghost.Graphics.D3D12;
|
||||
|
||||
internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
internal unsafe class D3D12CommandBuffer : D3D12RHIObject<ID3D12GraphicsCommandList10>, ICommandBuffer
|
||||
{
|
||||
private ComPtr<ID3D12CommandAllocator> _allocator;
|
||||
private ComPtr<ID3D12GraphicsCommandList10> _commandList;
|
||||
|
||||
private readonly D3D12PipelineLibrary _pipelineLibrary;
|
||||
private readonly D3D12ResourceDatabase _resourceDatabase;
|
||||
@@ -24,26 +24,14 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
private readonly D3D12DescriptorAllocator _descriptorAllocator;
|
||||
private readonly CommandBufferType _type;
|
||||
|
||||
private string _name;
|
||||
private ushort _commandCount;
|
||||
private bool _isRecording;
|
||||
private bool _disposed;
|
||||
|
||||
public ID3D12GraphicsCommandList10* NativeCommandList => _commandList.Get();
|
||||
public ID3D12GraphicsCommandList10* NativeCommandList => nativeObject.Get();
|
||||
|
||||
public CommandBufferType Type => _type;
|
||||
public bool IsEmpty => _commandCount == 0;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set
|
||||
{
|
||||
_name = value;
|
||||
_commandList.Get()->SetName(value);
|
||||
}
|
||||
}
|
||||
|
||||
public D3D12CommandBuffer(
|
||||
D3D12RenderDevice device,
|
||||
D3D12PipelineLibrary stateController,
|
||||
@@ -52,7 +40,6 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
D3D12DescriptorAllocator descriptorAllocator,
|
||||
CommandBufferType type)
|
||||
{
|
||||
_name = string.Empty;
|
||||
_type = type;
|
||||
|
||||
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);
|
||||
|
||||
_allocator.Attach(pAllocator);
|
||||
_commandList.Attach(pCommandList);
|
||||
nativeObject.Attach(pCommandList);
|
||||
|
||||
_pipelineLibrary = stateController;
|
||||
_resourceDatabase = resourceDatabase;
|
||||
@@ -71,12 +58,6 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
_descriptorAllocator = descriptorAllocator;
|
||||
|
||||
_isRecording = false;
|
||||
_disposed = false;
|
||||
}
|
||||
|
||||
~D3D12CommandBuffer()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
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)]
|
||||
private void ThrowIfRecording()
|
||||
{
|
||||
@@ -125,7 +100,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
void ResetCommandList()
|
||||
{
|
||||
ThrowIfFailed(_allocator.Get()->Reset());
|
||||
ThrowIfFailed(_commandList.Get()->Reset(_allocator.Get(), null));
|
||||
ThrowIfFailed(nativeObject.Get()->Reset(_allocator.Get(), null));
|
||||
}
|
||||
|
||||
void SetBindlessHeap()
|
||||
@@ -133,7 +108,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
var heaps = stackalloc ID3D12DescriptorHeap*[2];
|
||||
heaps[0] = _descriptorAllocator.GetCbvSrvUavHeap(); // Bindless resource heap
|
||||
heaps[1] = _descriptorAllocator.GetSamplerHeap(); // Bindless sampler heap
|
||||
_commandList.Get()->SetDescriptorHeaps(2, heaps);
|
||||
nativeObject.Get()->SetDescriptorHeaps(2, heaps);
|
||||
}
|
||||
|
||||
ThrowIfDisposed();
|
||||
@@ -151,7 +126,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
|
||||
_commandList.Get()->Close();
|
||||
nativeObject.Get()->Close();
|
||||
_isRecording = false;
|
||||
}
|
||||
|
||||
@@ -161,8 +136,8 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
ThrowIfNotRecording();
|
||||
IncrementCommandCount();
|
||||
|
||||
var d3d12Rect = new RECT((int)rect.left, (int)rect.top, (int)rect.right, (int)rect.bottom);
|
||||
_commandList.Get()->RSSetScissorRects(1, &d3d12Rect);
|
||||
var d3d12Rect = new RECT((int)rect.Left, (int)rect.Top, (int)rect.Right, (int)rect.Bottom);
|
||||
nativeObject.Get()->RSSetScissorRects(1, &d3d12Rect);
|
||||
}
|
||||
|
||||
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,
|
||||
before.ToD3D12States(), after.ToD3D12States());
|
||||
|
||||
_commandList.Get()->ResourceBarrier(1, &barrier);
|
||||
nativeObject.Get()->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
_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)
|
||||
@@ -216,12 +191,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
for (var i = 0; i < rtDescs.Length; 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");
|
||||
}
|
||||
|
||||
var resourceInfo = _resourceDatabase.GetResourceInfo(rtDesc.texture.AsResource());
|
||||
var resourceInfo = _resourceDatabase.GetResourceInfo(rtDesc.Texture.AsResource());
|
||||
var cpuHandle = _descriptorAllocator.GetCpuHandle(resourceInfo.viewGroup.rtv);
|
||||
|
||||
var desc = new D3D12_RENDER_PASS_RENDER_TARGET_DESC
|
||||
@@ -234,24 +209,24 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
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[1] = rtDesc.clearColor.g;
|
||||
desc.BeginningAccess.Clear.ClearValue.Color[2] = rtDesc.clearColor.b;
|
||||
desc.BeginningAccess.Clear.ClearValue.Color[3] = rtDesc.clearColor.a;
|
||||
desc.BeginningAccess.Clear.ClearValue.Color[0] = rtDesc.ClearColor.r;
|
||||
desc.BeginningAccess.Clear.ClearValue.Color[1] = rtDesc.ClearColor.g;
|
||||
desc.BeginningAccess.Clear.ClearValue.Color[2] = rtDesc.ClearColor.b;
|
||||
desc.BeginningAccess.Clear.ClearValue.Color[3] = rtDesc.ClearColor.a;
|
||||
|
||||
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)
|
||||
{
|
||||
var resourceInfo = _resourceDatabase.GetResourceInfo(depthDesc.texture.AsResource());
|
||||
var resourceInfo = _resourceDatabase.GetResourceInfo(depthDesc.Texture.AsResource());
|
||||
var cpuHandle = _descriptorAllocator.GetCpuHandle(resourceInfo.viewGroup.dsv);
|
||||
|
||||
var desc = new D3D12_RENDER_PASS_DEPTH_STENCIL_DESC
|
||||
@@ -264,11 +239,11 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ClearValue = new D3D12_CLEAR_VALUE
|
||||
{
|
||||
Format = resourceInfo.desc.textureDescription.Format.ToDXGIFormat(),
|
||||
Format = resourceInfo.desc.TextureDescription.Format.ToDXGIFormat(),
|
||||
DepthStencil = new D3D12_DEPTH_STENCIL_VALUE
|
||||
{
|
||||
Depth = depthDesc.clearDepth,
|
||||
Stencil = depthDesc.clearStencil
|
||||
Depth = depthDesc.ClearDepth,
|
||||
Stencil = depthDesc.ClearStencil
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -278,7 +253,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -288,7 +263,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
ThrowIfNotRecording();
|
||||
IncrementCommandCount();
|
||||
|
||||
_commandList.Get()->EndRenderPass();
|
||||
nativeObject.Get()->EndRenderPass();
|
||||
}
|
||||
|
||||
public void SetViewport(ViewportDesc viewport)
|
||||
@@ -297,8 +272,8 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
ThrowIfNotRecording();
|
||||
IncrementCommandCount();
|
||||
|
||||
var d3d12Viewport = new D3D12_VIEWPORT(viewport.width, viewport.height, viewport.x, viewport.y, viewport.minDepth, viewport.maxDepth);
|
||||
_commandList.Get()->RSSetViewports(1, &d3d12Viewport);
|
||||
var d3d12Viewport = new D3D12_VIEWPORT(viewport.Width, viewport.Height, viewport.X, viewport.Y, viewport.MinDepth, viewport.MaxDepth);
|
||||
nativeObject.Get()->RSSetViewports(1, &d3d12Viewport);
|
||||
}
|
||||
|
||||
public void SetPipelineState(GraphicsPipelineKey pipelineKey)
|
||||
@@ -308,7 +283,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
IncrementCommandCount();
|
||||
|
||||
var shaderPipeline = _pipelineLibrary.GetGraphicsPSO(pipelineKey).GetValueOrThrow();
|
||||
_commandList.Get()->SetPipelineState(shaderPipeline.value);
|
||||
nativeObject.Get()->SetPipelineState(shaderPipeline.value);
|
||||
}
|
||||
|
||||
public void SetConstantBufferView(uint slot, Handle<GraphicsBuffer> buffer)
|
||||
@@ -318,7 +293,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
IncrementCommandCount();
|
||||
|
||||
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)
|
||||
@@ -332,10 +307,10 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
BufferLocation = pResource->GetGPUVirtualAddress() + 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)
|
||||
@@ -352,7 +327,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
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)
|
||||
@@ -369,7 +344,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
_ => 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)
|
||||
@@ -378,7 +353,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
ThrowIfNotRecording();
|
||||
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)
|
||||
@@ -387,7 +362,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
ThrowIfNotRecording();
|
||||
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)
|
||||
@@ -396,7 +371,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
ThrowIfNotRecording();
|
||||
IncrementCommandCount();
|
||||
|
||||
_commandList.Get()->Dispatch(threadGroupCountX, threadGroupCountY, threadGroupCountZ);
|
||||
nativeObject.Get()->Dispatch(threadGroupCountX, threadGroupCountY, threadGroupCountZ);
|
||||
}
|
||||
|
||||
public void DispatchMesh(uint threadGroupCountX, uint threadGroupCountY, uint threadGroupCountZ)
|
||||
@@ -405,7 +380,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
ThrowIfNotRecording();
|
||||
IncrementCommandCount();
|
||||
|
||||
_commandList.Get()->DispatchMesh(threadGroupCountX, threadGroupCountY, threadGroupCountZ);
|
||||
nativeObject.Get()->DispatchMesh(threadGroupCountX, threadGroupCountY, threadGroupCountZ);
|
||||
}
|
||||
|
||||
public void DispatchRay()
|
||||
@@ -416,7 +391,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
// ThrowIfNotRecording();
|
||||
// IncrementCommandCount();
|
||||
|
||||
// _commandList.Get()->DispatchRays();
|
||||
// nativeObject.Get()->DispatchRays();
|
||||
}
|
||||
|
||||
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());
|
||||
|
||||
_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)
|
||||
@@ -470,7 +445,7 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
}
|
||||
|
||||
UpdateSubresources(
|
||||
(ID3D12GraphicsCommandList*)_commandList.Get(),
|
||||
(ID3D12GraphicsCommandList*)nativeObject.Get(),
|
||||
pResource,
|
||||
pUploadResource,
|
||||
0,
|
||||
@@ -494,17 +469,17 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
|
||||
if (numBytes == 0)
|
||||
{
|
||||
_commandList.Get()->CopyResource(pDestResource, pSrcResource);
|
||||
nativeObject.Get()->CopyResource(pDestResource, pSrcResource);
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -514,12 +489,9 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
throw new InvalidOperationException("Command buffer is still recording");
|
||||
}
|
||||
|
||||
_commandList.Dispose();
|
||||
_allocator.Dispose();
|
||||
_isRecording = false;
|
||||
MemoryLeakException.ThrowIfRefCountNonZero(_allocator.Reset());
|
||||
_commandCount = 0;
|
||||
_disposed = true;
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using Ghost.Core;
|
||||
using Ghost.Core.Graphics;
|
||||
using Ghost.Core.Utilities;
|
||||
using Ghost.Graphics.Core;
|
||||
using Ghost.Graphics.D3D12.Utilities;
|
||||
using Ghost.Graphics.RHI;
|
||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||
@@ -45,14 +46,6 @@ internal struct D3D12PipelineState : 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 D3D12ResourceDatabase _resourceDatabase;
|
||||
|
||||
@@ -81,7 +74,7 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
||||
_defaultRootSignature = default;
|
||||
|
||||
// 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
|
||||
{
|
||||
ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV,
|
||||
@@ -144,7 +137,7 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
||||
|
||||
var rootSignatureDesc = new D3D12_ROOT_SIGNATURE_DESC1
|
||||
{
|
||||
NumParameters = rootParamCount,
|
||||
NumParameters = RootSignatureLayout.ROOT_PARAMETER_COUNT,
|
||||
pParameters = rootParameters,
|
||||
NumStaticSamplers = 0,
|
||||
pStaticSamplers = null,
|
||||
@@ -215,19 +208,38 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
||||
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)
|
||||
{
|
||||
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];
|
||||
return Result.Fail("Per-material constant buffer not found in shader reflection data.");
|
||||
|
||||
// TODO: Validate Cbuffer sizes and bindings.
|
||||
}
|
||||
@@ -242,11 +254,11 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
||||
try
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
var reflection = D3D12ShaderCompiler.PerformDXCReflection(reflectionBlob).GetValueOrThrow();
|
||||
cbufferInfo = ValidateReflectionData(descriptor, reflection);
|
||||
cbufferInfo = ValidateReflectionData(descriptor, reflection).GetValueOrThrow();
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -361,7 +373,7 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
||||
|
||||
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
|
||||
{
|
||||
@@ -372,12 +384,12 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
||||
SampleMask = UINT32_MAX,
|
||||
SampleDesc = new DXGI_SAMPLE_DESC(1, 0),
|
||||
NumRenderTargets = rtvCount,
|
||||
DSVFormat = descriptor.dsvFormat.ToDXGIFormat(),
|
||||
DepthStencilState = BuildDepthStencil(descriptor.zTest, descriptor.zWrite),
|
||||
DSVFormat = descriptor.DsvFormat.ToDXGIFormat(),
|
||||
DepthStencilState = BuildDepthStencil(descriptor.ZTest, descriptor.ZWrite),
|
||||
NodeMask = 0,
|
||||
Flags = D3D12_PIPELINE_STATE_FLAG_NONE,
|
||||
|
||||
BlendState = descriptor.blend switch
|
||||
BlendState = descriptor.Blend switch
|
||||
{
|
||||
BlendOptions.Opaque => D3D12Utility.D3D12_BLEND_DESC_OPAQUE,
|
||||
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,
|
||||
_ => D3D12Utility.D3D12_BLEND_DESC_OPAQUE
|
||||
},
|
||||
RasterizerState = descriptor.cull switch
|
||||
RasterizerState = descriptor.Cull switch
|
||||
{
|
||||
CullOptions.Off => D3D12Utility.D3D12_RASTERIZER_DESC_CULL_NONE,
|
||||
CullOptions.Front => D3D12Utility.D3D12_RASTERIZER_DESC_CULL_CLOCKWISE,
|
||||
@@ -402,16 +414,16 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
||||
|
||||
var hash = new GraphicsPipelineHash
|
||||
{
|
||||
id = descriptor.passId,
|
||||
rtvCount = (uint)descriptor.rtvFormats.Length,
|
||||
dsvFormat = descriptor.dsvFormat,
|
||||
Id = descriptor.PassId,
|
||||
RtvCount = (uint)descriptor.RtvFormats.Length,
|
||||
DsvFormat = descriptor.DsvFormat,
|
||||
};
|
||||
|
||||
for (var i = 0; i < rtvCount && i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
|
||||
{
|
||||
desc.RTVFormats[i] = descriptor.rtvFormats[i].ToDXGIFormat();
|
||||
desc.BlendState.RenderTarget[i].RenderTargetWriteMask = (byte)(descriptor.colorMask & 0x0F);
|
||||
hash.rtvFormats[i] = descriptor.rtvFormats[i];
|
||||
desc.RTVFormats[i] = descriptor.RtvFormats[i].ToDXGIFormat();
|
||||
desc.BlendState.RenderTarget[i].RenderTargetWriteMask = (byte)(descriptor.ColorMask & 0x0F);
|
||||
hash.RtvFormats[i] = descriptor.RtvFormats[i];
|
||||
}
|
||||
|
||||
var key = hash.GetKey();
|
||||
@@ -468,15 +480,15 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary, IDisposable
|
||||
|
||||
var psoDes = new GraphicsPSODescriptor
|
||||
{
|
||||
passId = new ShaderPassKey(fullPass.Identifier),
|
||||
zTest = fullPass.localPipeline.zTest,
|
||||
zWrite = fullPass.localPipeline.zWrite,
|
||||
cull = fullPass.localPipeline.cull,
|
||||
blend = fullPass.localPipeline.blend,
|
||||
colorMask = fullPass.localPipeline.colorMask,
|
||||
PassId = new ShaderPassKey(fullPass.Identifier),
|
||||
ZTest = fullPass.localPipeline.zTest,
|
||||
ZWrite = fullPass.localPipeline.zWrite,
|
||||
Cull = fullPass.localPipeline.cull,
|
||||
Blend = fullPass.localPipeline.blend,
|
||||
ColorMask = fullPass.localPipeline.colorMask,
|
||||
|
||||
rtvFormats = rtvs,
|
||||
dsvFormat = dsv,
|
||||
RtvFormats = rtvs,
|
||||
DsvFormat = dsv,
|
||||
};
|
||||
|
||||
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];
|
||||
rtDesc[0] = new PassRenderTargetDesc
|
||||
{
|
||||
texture = target,
|
||||
clearColor = clearColor,
|
||||
Texture = target,
|
||||
ClearColor = clearColor,
|
||||
};
|
||||
|
||||
var depthDesc = new PassDepthStencilDesc
|
||||
{
|
||||
texture = Handle<Texture>.Invalid,
|
||||
clearDepth = 1.0f,
|
||||
clearStencil = 0,
|
||||
Texture = Handle<Texture>.Invalid,
|
||||
ClearDepth = 1.0f,
|
||||
ClearStencil = 0,
|
||||
};
|
||||
|
||||
// NOTE: Testing only.
|
||||
@@ -219,8 +219,8 @@ internal unsafe class D3D12Renderer : IRenderer
|
||||
|
||||
cmd.BeginRenderPass(rtDesc, depthDesc, false);
|
||||
|
||||
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 viewport = new ViewportDesc { Width = _currentSize.x, Height = _currentSize.y, MinDepth = 0, MaxDepth = 1 };
|
||||
var scissor = new RectDesc { Right = _currentSize.x, Bottom = _currentSize.y };
|
||||
|
||||
cmd.SetViewport(viewport);
|
||||
cmd.SetScissorRect(scissor);
|
||||
|
||||
@@ -10,70 +10,7 @@ using static TerraFX.Interop.DirectX.DXC;
|
||||
|
||||
namespace Ghost.Graphics.D3D12;
|
||||
|
||||
internal struct CompileResult : IDisposable
|
||||
{
|
||||
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
|
||||
internal partial class D3D12ShaderCompiler
|
||||
{
|
||||
private static string GetProfileString(ShaderStage stage, CompilerTier version)
|
||||
{
|
||||
@@ -150,29 +87,63 @@ internal static unsafe class D3D12ShaderCompiler
|
||||
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;
|
||||
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;
|
||||
|
||||
try
|
||||
{
|
||||
// Create DXC pCompiler and pUtils
|
||||
// Create DXC _compiler.Get() and _utils.Get()
|
||||
var dxccID = CLSID.CLSID_DxcCompiler;
|
||||
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
|
||||
using ComPtr<IDxcBlobEncoding> sourceBlob = default;
|
||||
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}");
|
||||
}
|
||||
@@ -197,7 +168,7 @@ internal static unsafe class D3D12ShaderCompiler
|
||||
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
|
||||
HRESULT hrStatus;
|
||||
@@ -224,9 +195,9 @@ internal static unsafe class D3D12ShaderCompiler
|
||||
ThrowIfFailed(pResult->GetResult(bytecodeBlob.GetAddressOf()));
|
||||
|
||||
// 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();
|
||||
@@ -251,39 +222,37 @@ internal static unsafe class D3D12ShaderCompiler
|
||||
}
|
||||
finally
|
||||
{
|
||||
pCompiler->Release();
|
||||
pUtils->Release();
|
||||
pIncludeHandler->Release();
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
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;
|
||||
IDxcBlob* pDxcReflectionBlob = (IDxcBlob*)pReflectionBlob;
|
||||
|
||||
try
|
||||
{
|
||||
// Create DXC pUtils to parse pReflection data
|
||||
// Create DXC _utils.Get() to parse pReflection data
|
||||
var dxcuID = CLSID.CLSID_DxcUtils;
|
||||
ThrowIfFailed(DxcCreateInstance(&dxcuID, __uuidof(pUtils), (void**)&pUtils));
|
||||
|
||||
// Create pReflection interface from blob
|
||||
var reflectionBuffer = new DxcBuffer
|
||||
{
|
||||
Ptr = reflectionBlob->GetBufferPointer(),
|
||||
Size = reflectionBlob->GetBufferSize(),
|
||||
Ptr = pDxcReflectionBlob->GetBufferPointer(),
|
||||
Size = pDxcReflectionBlob->GetBufferSize(),
|
||||
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;
|
||||
ThrowIfFailed(pReflection->GetDesc(&shaderDesc));
|
||||
@@ -301,6 +270,15 @@ internal static unsafe class D3D12ShaderCompiler
|
||||
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)
|
||||
{
|
||||
case D3D_SHADER_INPUT_TYPE.D3D_SIT_CBUFFER:
|
||||
@@ -332,41 +310,22 @@ internal static unsafe class D3D12ShaderCompiler
|
||||
});
|
||||
}
|
||||
|
||||
reflectionData.ConstantBuffers.Add(new CBufferInfo
|
||||
{
|
||||
Name = resourceName,
|
||||
RegisterSlot = bindDesc.BindPoint,
|
||||
RegisterSpace = bindDesc.Space,
|
||||
SizeInBytes = cbufferDesc.Size,
|
||||
Properties = variables
|
||||
});
|
||||
info.Size = cbufferDesc.Size;
|
||||
info.Properties = variables;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
pUtils->Release();
|
||||
pReflection->Release();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user