Skip to content

Commit

Permalink
[DX12] Implemented root signature metadata
Browse files Browse the repository at this point in the history
[DX12] Added RootSignatureDX12.Meta property
  • Loading branch information
Syncaidius committed May 6, 2024
1 parent 3eaa659 commit ce733c2
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,6 @@ internal unsafe void PrepareGpuHeap(ShaderPassDX12 pass, PipelineStateDX12 state
// Increment GPU heap handle
resBindCount++;
}
else
{

}

gpuResHandle.Ptr += resHeap.IncrementSize;
}
Expand All @@ -148,7 +144,7 @@ internal unsafe void PrepareGpuHeap(ShaderPassDX12 pass, PipelineStateDX12 state
}
}

state.RootSignature.LayoutToLog();
state.RootSignature.Meta.ToLog(Device.Log);

// Populate SRV, UAV, and CBV descriptors first.
// TODO Pull descriptor info from our pass, render targets, samplers, depth-stencil, etc.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ public bool Equals(CacheKey other)
};

D3DRootSignatureVersion _rootSignatureVersion;
RootSignaturePopulatorDX12 _rootSigPopulator;
RootSignaturePopulatorDX12 _rootParser;

internal PipelineStateBuilderDX12(DeviceDX12 device)
{
_rootSignatureVersion = device.CapabilitiesDX12.RootSignatureVersion;

// Decrease root signature version until we find one the engine supports.
while (!_rootPopulators.TryGetValue(_rootSignatureVersion, out _rootSigPopulator))
while (!_rootPopulators.TryGetValue(_rootSignatureVersion, out _rootParser))
{
_rootSignatureVersion--;
if(_rootSignatureVersion <= 0)
Expand Down Expand Up @@ -200,7 +200,7 @@ private unsafe RootSignatureDX12 BuildRootSignature(ShaderPassDX12 pass, Pipelin
// TODO Check root signature cache for existing root signature.

VersionedRootSignatureDesc sigDesc = new(_rootSignatureVersion);
_rootSigPopulator.Populate(ref sigDesc, in psoDesc, pass, layout);
RootSigMetaDX12 rootMeta = _rootParser.Populate(ref sigDesc, in psoDesc, pass, layout);

// Serialize the root signature.
ID3D10Blob* signature = null;
Expand All @@ -222,7 +222,7 @@ private unsafe RootSignatureDX12 BuildRootSignature(ShaderPassDX12 pass, Pipelin
if (!device.Log.CheckResult(hr, () => "Failed to create root signature"))
hr.Throw();

return new RootSignatureDX12(device, (ID3D12RootSignature*)ptr, sigDesc);
return new RootSignatureDX12(device, (ID3D12RootSignature*)ptr, rootMeta);
}

private unsafe void ParseErrors(ShaderPassDX12 pass, HResult hr, ID3D10Blob* errors)
Expand Down
98 changes: 98 additions & 0 deletions Molten.Graphics.DX12/Pipeline/State/RootSigMetaDX12.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using Silk.NET.Direct3D12;
using System.Runtime.InteropServices;

namespace Molten.Graphics.DX12;
internal unsafe class RootSigMetaDX12 : IDisposable
{
internal struct BindDescriptorTable
{
public uint NumRanges;

public BindDescriptorRange* Ranges;
}

internal struct BindDescriptorRange
{
public uint NumDescriptors;

public DescriptorRangeType Type;

public uint BaseShaderRegister;

public uint RegisterSpace;

/// <summary>
/// Offset by number of descriptors from start of the descriptor table.
/// </summary>
public uint OffsetInDescriptorsFromTableStart;

public DescriptorRangeFlags Flags;
}

[StructLayout(LayoutKind.Explicit)]
internal struct BindParameter
{
[FieldOffset(0)]
public RootParameterType Type;

[FieldOffset(8)]
public BindDescriptorTable DescriptorTable;
}

internal BindParameter[] Parameters;

internal BindDescriptorRange* Ranges;

internal RootSigMetaDX12(uint numParameters, uint numRanges, D3DRootSignatureVersion version)
{
Parameters = new BindParameter[numParameters];
NumRanges = numRanges;
Ranges = EngineUtil.AllocArray<BindDescriptorRange>(numRanges);
Version = version;
}

~RootSigMetaDX12()
{
Dispose();
}

public void Dispose()
{
EngineUtil.Free(ref Ranges);
}

/// <summary>
/// Outputs a root signature layout to the log, based on data held in the current <see cref="RootSigMetaDX12"/>.
/// </summary>
/// <param name="log"></param>
internal void ToLog(Logger log)
{
log.Debug($"Bound Root-Signature ({Version}) with {Parameters.Length} parameter(s):");

for (uint i = 0; i < Parameters.Length; i++)
{
ref BindParameter rootParam = ref Parameters[i];
log.Debug($"\tRoot parameter {i} - Type: {rootParam.Type}");

if (rootParam.Type == RootParameterType.TypeDescriptorTable)
{
ref BindDescriptorTable table = ref rootParam.DescriptorTable;
for (int j = 0; j < table.NumRanges; j++)
{
ref BindDescriptorRange range = ref table.Ranges[j];
log.Debug($"\t\tRange {j} - Type: {range.Type}, Descriptor(s): {range.NumDescriptors}, Flags: {range.Flags}");
for (uint k = 0; k < range.NumDescriptors; k++)
{
uint offsetFromStart = range.OffsetInDescriptorsFromTableStart + k;
uint register = range.BaseShaderRegister + k;
log.Debug($"\t\t\tDescriptor {k} - Offset: {offsetFromStart} - Register: {register}");
}
}
}
}
}

internal D3DRootSignatureVersion Version { get; }

internal uint NumRanges { get; }
}
38 changes: 37 additions & 1 deletion Molten.Graphics.DX12/Pipeline/State/RootSigPopulator1_0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace Molten.Graphics.DX12;
internal class RootSigPopulator1_0 : RootSignaturePopulatorDX12
{
internal override unsafe void Populate(ref VersionedRootSignatureDesc versionedDesc,
internal override unsafe RootSigMetaDX12 Populate(ref VersionedRootSignatureDesc versionedDesc,
ref readonly GraphicsPipelineStateDesc psoDesc,
ShaderPassDX12 pass,
PipelineInputLayoutDX12 layout)
Expand Down Expand Up @@ -35,6 +35,42 @@ internal override unsafe void Populate(ref VersionedRootSignatureDesc versionedD
Span<DescriptorRange> rangeSpan = CollectionsMarshal.AsSpan(ranges);
Span<DescriptorRange> tableRanges = new(param.DescriptorTable.PDescriptorRanges, ranges.Count);
rangeSpan.CopyTo(tableRanges);

RootSigMetaDX12 meta = new(desc.NumParameters, (uint)ranges.Count, D3DRootSignatureVersion.Version10);
RootSigMetaDX12.BindDescriptorRange* baseRange = meta.Ranges;

// Populate metadata
uint rangeIndex = 0;
for (int i = 0; i < desc.NumParameters; i++)
{
ref RootParameter pDesc = ref desc.PParameters[i];
ref RootSigMetaDX12.BindParameter pMeta = ref meta.Parameters[i];
pMeta.Type = pDesc.ParameterType;

// Parse as descriptor table
if (pMeta.Type == RootParameterType.TypeDescriptorTable)
{
ref RootDescriptorTable pTable = ref pDesc.DescriptorTable;
ref RootSigMetaDX12.BindDescriptorTable metaTable = ref pMeta.DescriptorTable;
metaTable.NumRanges = pTable.NumDescriptorRanges;
metaTable.Ranges = baseRange + rangeIndex;

for (int r = 0; r < pTable.NumDescriptorRanges; r++)
{
ref DescriptorRange rangeDesc = ref pTable.PDescriptorRanges[r];
ref RootSigMetaDX12.BindDescriptorRange rangeMeta = ref meta.Ranges[r];
rangeMeta.Type = rangeDesc.RangeType;
rangeMeta.Flags = DescriptorRangeFlags.None;
rangeMeta.NumDescriptors = rangeDesc.NumDescriptors;
rangeMeta.BaseShaderRegister = rangeDesc.BaseShaderRegister;
rangeMeta.RegisterSpace = rangeDesc.RegisterSpace;
rangeMeta.OffsetInDescriptorsFromTableStart = rangeDesc.OffsetInDescriptorsFromTableStart;
rangeIndex++;
}
}
}

return meta;
}

private void PopulateRanges<V>(DescriptorRangeType type, List<DescriptorRange> ranges, ShaderBind<V>[] variables, ref uint numDescriptors)
Expand Down
40 changes: 38 additions & 2 deletions Molten.Graphics.DX12/Pipeline/State/RootSigPopulator1_1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
namespace Molten.Graphics.DX12;
internal class RootSigPopulator1_1 : RootSignaturePopulatorDX12
{
internal override unsafe void Populate(ref VersionedRootSignatureDesc versionedDesc,
ref readonly GraphicsPipelineStateDesc psoDesc,
internal override unsafe RootSigMetaDX12 Populate(ref VersionedRootSignatureDesc versionedDesc,
ref readonly GraphicsPipelineStateDesc psoDesc,
ShaderPassDX12 pass,
PipelineInputLayoutDX12 layout)
{
Expand Down Expand Up @@ -35,6 +35,42 @@ internal override unsafe void Populate(ref VersionedRootSignatureDesc versionedD
Span<DescriptorRange1> rangeSpan = CollectionsMarshal.AsSpan(ranges);
Span<DescriptorRange1> tableRanges = new(param.DescriptorTable.PDescriptorRanges, ranges.Count);
rangeSpan.CopyTo(tableRanges);

RootSigMetaDX12 meta = new(desc.NumParameters, (uint)ranges.Count, D3DRootSignatureVersion.Version10);
RootSigMetaDX12.BindDescriptorRange* baseRange = meta.Ranges;

// Populate metadata
uint rangeIndex = 0;
for (int i = 0; i < desc.NumParameters; i++)
{
ref RootParameter1 pDesc = ref desc.PParameters[i];
ref RootSigMetaDX12.BindParameter pMeta = ref meta.Parameters[i];
pMeta.Type = pDesc.ParameterType;

// Parse as descriptor table
if (pMeta.Type == RootParameterType.TypeDescriptorTable)
{
ref RootDescriptorTable1 pTable = ref pDesc.DescriptorTable;
ref RootSigMetaDX12.BindDescriptorTable metaTable = ref pMeta.DescriptorTable;
metaTable.NumRanges = pTable.NumDescriptorRanges;
metaTable.Ranges = baseRange + rangeIndex;

for (int r = 0; r < pTable.NumDescriptorRanges; r++)
{
ref DescriptorRange1 rangeDesc = ref pTable.PDescriptorRanges[r];
ref RootSigMetaDX12.BindDescriptorRange rangeMeta = ref meta.Ranges[r];
rangeMeta.Type = rangeDesc.RangeType;
rangeMeta.Flags = rangeDesc.Flags;
rangeMeta.NumDescriptors = rangeDesc.NumDescriptors;
rangeMeta.BaseShaderRegister = rangeDesc.BaseShaderRegister;
rangeMeta.RegisterSpace = rangeDesc.RegisterSpace;
rangeMeta.OffsetInDescriptorsFromTableStart = rangeDesc.OffsetInDescriptorsFromTableStart;
rangeIndex++;
}
}
}

return meta;
}

private void PopulateRanges<V>(DescriptorRangeType type, List<DescriptorRange1> ranges, ShaderBind<V>[] variables, ref uint numDescriptors)
Expand Down
74 changes: 5 additions & 69 deletions Molten.Graphics.DX12/Pipeline/State/RootSignatureDX12.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,88 +5,24 @@ namespace Molten.Graphics.DX12;
internal unsafe class RootSignatureDX12 : GpuObject<DeviceDX12>
{
ID3D12RootSignature* _handle;
VersionedRootSignatureDesc _desc;
RootSigMetaDX12 _meta;

internal RootSignatureDX12(DeviceDX12 device, ID3D12RootSignature* handle, VersionedRootSignatureDesc desc) :
internal RootSignatureDX12(DeviceDX12 device, ID3D12RootSignature* handle, RootSigMetaDX12 meta) :
base(device)
{
_handle = handle;
_desc = desc;
}

/// <summary>
/// Outputs the layout of the current <see cref="RootSignatureDX12"/> to it's parent <see cref="DeviceDX12"/> log.
/// </summary>
internal unsafe void LayoutToLog()
{
// Validate GPU heap
if (_desc.Version == D3DRootSignatureVersion.Version10)
LogLayout1_0();
else if (_desc.Version == D3DRootSignatureVersion.Version11)
LogLayout1_1();
}

private void LogLayout1_0()
{
throw new NotImplementedException($"{nameof(LayoutToLog)}: Logging of V1.0 root signatures is not yet supported.");
}

private void LogLayout1_1()
{
ref RootSignatureDesc1 desc = ref _desc.Desc11;
Device.Log.Debug($"Bound Root-Sigature (V1.1) with {desc.NumParameters} parameter(s):");

for (uint i = 0; i < desc.NumParameters; i++)
{
ref RootParameter1 rootParam = ref desc.PParameters[i];
Device.Log.Debug($"\tRoot parameter {i} - Type: {rootParam.ParameterType}");

if (rootParam.ParameterType == RootParameterType.TypeDescriptorTable)
{
ref RootDescriptorTable1 table = ref rootParam.DescriptorTable;
for (uint j = 0; j < table.NumDescriptorRanges; j++)
{
ref DescriptorRange1 range = ref table.PDescriptorRanges[j];
Device.Log.Debug($"\t\tRange {j} - Type: {range.RangeType}, Descriptor(s): {range.NumDescriptors}");
for (uint k = 0; k < range.NumDescriptors; k++)
{
uint offsetFromStart = range.OffsetInDescriptorsFromTableStart + k;
Device.Log.Debug($"\t\t\tDescriptor {k} - Offset: {offsetFromStart}");
}
}
}
}
Meta = meta;
}

protected override void OnGpuRelease()
{
NativeUtil.ReleasePtr(ref _handle);

if (_desc.Version == D3DRootSignatureVersion.Version11)
{
ref RootSignatureDesc1 desc = ref _desc.Desc11;

for (int i = 0; i < desc.NumParameters; i++)
EngineUtil.Free(ref desc.PParameters[i].DescriptorTable.PDescriptorRanges);

EngineUtil.Free(ref desc.PParameters);
EngineUtil.Free(ref desc.PStaticSamplers);
}
else if (_desc.Version == D3DRootSignatureVersion.Version10)
{
ref RootSignatureDesc desc = ref _desc.Desc10;

for (int i = 0; i < desc.NumParameters; i++)
EngineUtil.Free(ref desc.PParameters[i].DescriptorTable.PDescriptorRanges);

EngineUtil.Free(ref desc.PParameters);
EngineUtil.Free(ref desc.PStaticSamplers);
}
_meta.Dispose();
}

public static implicit operator ID3D12RootSignature*(RootSignatureDX12 sig) => sig._handle;

public ref readonly ID3D12RootSignature* Handle => ref _handle;

public ref readonly VersionedRootSignatureDesc Desc => ref _desc;
public RootSigMetaDX12 Meta { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ internal abstract class RootSignaturePopulatorDX12
/// <param name="psoDesc"></param>
/// <param name="versionedDesc"></param>
/// <returns></returns>
internal abstract void Populate(ref VersionedRootSignatureDesc versionedDesc,
internal abstract RootSigMetaDX12 Populate(ref VersionedRootSignatureDesc versionedDesc,
ref readonly GraphicsPipelineStateDesc psoDesc,
ShaderPassDX12 pass,
PipelineInputLayoutDX12 layout);
Expand Down

0 comments on commit ce733c2

Please sign in to comment.