-
-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[DX12] Move root signature construction to RootSignatureBuilderDX12
[DX12] Removed PipelineStateBuilderDX12.BuildRootSignature() [DX12] Added RootSignatureBuilderDX12
- Loading branch information
1 parent
ce733c2
commit a76fd30
Showing
2 changed files
with
87 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
Molten.Graphics.DX12/Pipeline/State/RootSignatureBuilderDX12.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using Silk.NET.Core.Native; | ||
using Silk.NET.Direct3D12; | ||
|
||
namespace Molten.Graphics.DX12; | ||
internal unsafe class RootSignatureBuilderDX12 | ||
{ | ||
static readonly char[] _errorDelimiters = ['\r', '\n']; | ||
|
||
static readonly Dictionary<D3DRootSignatureVersion, RootSignaturePopulatorDX12> _rootPopulators = new() | ||
{ | ||
[D3DRootSignatureVersion.Version10] = new RootSigPopulator1_0(), | ||
[D3DRootSignatureVersion.Version11] = new RootSigPopulator1_1(), | ||
}; | ||
|
||
D3DRootSignatureVersion _rootSignatureVersion; | ||
RootSignaturePopulatorDX12 _rootParser; | ||
|
||
internal RootSignatureBuilderDX12(DeviceDX12 device) | ||
{ | ||
_rootSignatureVersion = device.CapabilitiesDX12.RootSignatureVersion; | ||
|
||
// Decrease root signature version until we find one the engine supports. | ||
while (!_rootPopulators.TryGetValue(_rootSignatureVersion, out _rootParser)) | ||
{ | ||
_rootSignatureVersion--; | ||
if (_rootSignatureVersion <= 0) | ||
throw new NotSupportedException("The current device does not support any known root signature versions."); | ||
} | ||
} | ||
|
||
internal RootSignatureDX12 Build(ShaderPassDX12 pass, PipelineInputLayoutDX12 layout, ref readonly GraphicsPipelineStateDesc psoDesc) | ||
{ | ||
DeviceDX12 device = pass.Device as DeviceDX12; | ||
|
||
// TODO Check root signature cache for existing root signature. | ||
|
||
VersionedRootSignatureDesc sigDesc = new(_rootSignatureVersion); | ||
RootSigMetaDX12 rootMeta = _rootParser.Populate(ref sigDesc, in psoDesc, pass, layout); | ||
|
||
// Serialize the root signature. | ||
ID3D10Blob* signature = null; | ||
ID3D10Blob* errors = null; | ||
|
||
HResult hr = device.Renderer.Api.SerializeVersionedRootSignature(&sigDesc, &signature, &errors); | ||
if (!device.Log.CheckResult(hr, () => "Failed to serialize root signature")) | ||
{ | ||
ParseErrors(pass, hr, errors); | ||
hr.Throw(); | ||
} | ||
|
||
// TODO Implement root signature caching - Store the serialized signature blob in cache file. | ||
|
||
// Create the root signature. | ||
Guid guid = ID3D12RootSignature.Guid; | ||
void* ptr = null; | ||
hr = device.Handle->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), &guid, &ptr); | ||
if (!device.Log.CheckResult(hr, () => "Failed to create root signature")) | ||
hr.Throw(); | ||
|
||
return new RootSignatureDX12(device, (ID3D12RootSignature*)ptr, rootMeta); | ||
} | ||
|
||
private unsafe void ParseErrors(ShaderPassDX12 pass, HResult hr, ID3D10Blob* errors) | ||
{ | ||
if (errors == null) | ||
return; | ||
|
||
void* ptrErrors = errors->GetBufferPointer(); | ||
nuint numBytes = errors->GetBufferSize(); | ||
string strErrors = SilkMarshal.PtrToString((nint)ptrErrors, NativeStringEncoding.UTF8); | ||
string[] errorList = strErrors.Split(_errorDelimiters, StringSplitOptions.RemoveEmptyEntries); | ||
|
||
if (hr.IsSuccess) | ||
{ | ||
for (int i = 0; i < errorList.Length; i++) | ||
pass.Device.Log.Warning($"[{nameof(PipelineStateBuilderDX12)}] {errorList[i]}"); | ||
} | ||
else | ||
{ | ||
for (int i = 0; i < errorList.Length; i++) | ||
pass.Device.Log.Error($"[{nameof(PipelineStateBuilderDX12)}] {errorList[i]}"); | ||
} | ||
} | ||
} |