forked from Misaki/GhostEngine
Refactor pipeline state and render output abstractions
- Replace old pipeline enums/structs with new strongly-typed PipelineState and enums (ZTest, ZWrite, Cull, Blend, ColorWriteMask) - Redesign pipeline keying: introduce 128-bit GraphicsPipelineKey, MaterialPipelineKey, and PassPipelineKey for robust PSO caching - Replace IRenderTargetStrategy with IRenderOutput; add SwapChainRenderOutput and TextureRenderOutput - Update renderer and window code to use new render output abstraction and handle viewport/scissor updates - Make ShaderPass a readonly struct and Shader a struct; use ID-based pass lookup for efficiency - Materials now support per-pass pipeline overrides with new keying - Add defensive checks in D3D12CommandBuffer; update D3D12PipelineLibrary for new keying/state - Move test shader to test.gsdef and update for new pipeline state syntax - Remove obsolete files/interfaces and perform general code cleanups - Update all usages and parsing logic for new pipeline state system
This commit is contained in:
@@ -26,7 +26,9 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
private readonly D3D12DescriptorAllocator _descriptorAllocator;
|
||||
private readonly CommandBufferType _type;
|
||||
|
||||
#if !DEBUG
|
||||
private CommandError _lastError;
|
||||
#endif
|
||||
private ushort _commandCount;
|
||||
private bool _isRecording;
|
||||
private bool _disposed;
|
||||
@@ -166,10 +168,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
_commandList.Get()->Close();
|
||||
_isRecording = false;
|
||||
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return Result.Failure($"Command buffer ended with errors at {_lastError.CommandIndex}, command '{_lastError.CommandName}': {_lastError.Status}");
|
||||
}
|
||||
#endif
|
||||
|
||||
return Result.Success();
|
||||
}
|
||||
@@ -178,6 +182,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
var d3d12Rect = new RECT((int)rect.Left, (int)rect.Top, (int)rect.Right, (int)rect.Bottom);
|
||||
@@ -188,6 +198,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
var count = 0u;
|
||||
@@ -238,6 +254,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
if (stateBefore == stateAfter)
|
||||
@@ -264,6 +286,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
var recordResult = _resourceDatabase.GetResourceRecord(resource);
|
||||
@@ -290,6 +318,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
var pRtvHandles = stackalloc D3D12_CPU_DESCRIPTOR_HANDLE[renderTargets.Length];
|
||||
@@ -337,6 +371,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
var pRtvDescs = stackalloc D3D12_RENDER_PASS_RENDER_TARGET_DESC[rtDescs.Length];
|
||||
@@ -419,6 +459,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
_commandList.Get()->EndRenderPass();
|
||||
@@ -428,6 +474,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
var d3d12Viewport = new D3D12_VIEWPORT(viewport.X, viewport.Y, viewport.Width, viewport.Height, viewport.MinDepth, viewport.MaxDepth);
|
||||
@@ -438,14 +490,18 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
var psor = _pipelineLibrary.GetGraphicsPSO(pipelineKey);
|
||||
if (psor.Error != ErrorStatus.None)
|
||||
{
|
||||
#if DEBUG || GHOST_EDITOR
|
||||
Logger.LogError($"Failed to get graphics pipeline state object for key {pipelineKey}: {psor.Error}");
|
||||
#endif
|
||||
RecordError(nameof(SetPipelineState), psor.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -457,6 +513,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
var resource = _resourceDatabase.GetResource(buffer.AsResource());
|
||||
@@ -467,6 +529,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
var recordResult = _resourceDatabase.GetResourceRecord(buffer.AsResource());
|
||||
@@ -491,6 +559,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
var resource = _resourceDatabase.GetResource(buffer.AsResource());
|
||||
@@ -508,6 +582,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
var d3d12Topology = topology switch
|
||||
@@ -525,6 +605,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
_commandList.Get()->DrawInstanced(vertexCount, instanceCount, startVertex, startInstance);
|
||||
@@ -534,6 +620,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
_commandList.Get()->DrawIndexedInstanced(indexCount, instanceCount, startIndex, baseVertex, startInstance);
|
||||
@@ -543,6 +635,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
_commandList.Get()->Dispatch(threadGroupCountX, threadGroupCountY, threadGroupCountZ);
|
||||
@@ -552,6 +650,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
_commandList.Get()->DispatchMesh(threadGroupCountX, threadGroupCountY, threadGroupCountZ);
|
||||
@@ -573,6 +677,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
var sizeInBytes = (uint)(data.Length * sizeof(T));
|
||||
@@ -599,6 +709,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
var resource = _resourceDatabase.GetResource(texture.AsResource());
|
||||
@@ -634,6 +750,12 @@ internal unsafe class D3D12CommandBuffer : ICommandBuffer
|
||||
{
|
||||
ThrowIfDisposed();
|
||||
ThrowIfNotRecording();
|
||||
#if !DEBUG
|
||||
if (_lastError.Status != ErrorStatus.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
IncrementCommandCount();
|
||||
|
||||
var pDestResource = _resourceDatabase.GetResource(dest.AsResource());
|
||||
|
||||
@@ -233,23 +233,23 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary
|
||||
return Result.Success(cbufferInfo);
|
||||
}
|
||||
|
||||
private static D3D12_COMPARISON_FUNC ToD3DCompare(ZTestOptions z) => z switch
|
||||
private static D3D12_COMPARISON_FUNC ToD3DCompare(ZTest z) => z switch
|
||||
{
|
||||
ZTestOptions.Disabled => D3D12_COMPARISON_FUNC_NEVER,
|
||||
ZTestOptions.Less => D3D12_COMPARISON_FUNC_LESS,
|
||||
ZTestOptions.LessEqual => D3D12_COMPARISON_FUNC_LESS_EQUAL,
|
||||
ZTestOptions.Equal => D3D12_COMPARISON_FUNC_EQUAL,
|
||||
ZTestOptions.GreaterEqual => D3D12_COMPARISON_FUNC_GREATER_EQUAL,
|
||||
ZTestOptions.Greater => D3D12_COMPARISON_FUNC_GREATER,
|
||||
ZTestOptions.NotEqual => D3D12_COMPARISON_FUNC_NOT_EQUAL,
|
||||
ZTestOptions.Always => D3D12_COMPARISON_FUNC_ALWAYS,
|
||||
ZTest.Disabled => D3D12_COMPARISON_FUNC_NEVER,
|
||||
ZTest.Less => D3D12_COMPARISON_FUNC_LESS,
|
||||
ZTest.LessEqual => D3D12_COMPARISON_FUNC_LESS_EQUAL,
|
||||
ZTest.Equal => D3D12_COMPARISON_FUNC_EQUAL,
|
||||
ZTest.GreaterEqual => D3D12_COMPARISON_FUNC_GREATER_EQUAL,
|
||||
ZTest.Greater => D3D12_COMPARISON_FUNC_GREATER,
|
||||
ZTest.NotEqual => D3D12_COMPARISON_FUNC_NOT_EQUAL,
|
||||
ZTest.Always => D3D12_COMPARISON_FUNC_ALWAYS,
|
||||
_ => D3D12_COMPARISON_FUNC_LESS_EQUAL
|
||||
};
|
||||
|
||||
private static D3D12_DEPTH_STENCIL_DESC BuildDepthStencil(ZTestOptions ztest, ZWriteOptions zwrite)
|
||||
private static D3D12_DEPTH_STENCIL_DESC BuildDepthStencil(ZTest ztest, ZWrite zwrite)
|
||||
{
|
||||
var depthEnabled = ztest != ZTestOptions.Disabled;
|
||||
var writeEnabled = zwrite == ZWriteOptions.On;
|
||||
var depthEnabled = ztest != ZTest.Disabled;
|
||||
var writeEnabled = zwrite == ZWrite.On;
|
||||
var cmp = ToD3DCompare(ztest);
|
||||
return D3D12Utility.D3D12_DEPTH_STENCIL_DESC_CREATE(depthEnabled, writeEnabled, cmp);
|
||||
}
|
||||
@@ -295,23 +295,16 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary
|
||||
return psr.Value;
|
||||
}
|
||||
|
||||
var hash = new GraphicsPipelineHash
|
||||
if (descriptor.RtvFormats.Length > D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT)
|
||||
{
|
||||
Id = descriptor.PassId,
|
||||
RtvCount = (uint)descriptor.RtvFormats.Length,
|
||||
DsvFormat = descriptor.DsvFormat,
|
||||
};
|
||||
|
||||
var rtvCount = (uint)Math.Min(descriptor.RtvFormats.Length, D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT);
|
||||
|
||||
for (var i = 0; i < rtvCount && i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
|
||||
{
|
||||
hash.RtvFormats[i] = descriptor.RtvFormats[i];
|
||||
return Result.Failure($"RTV format count exceeds the maximum supported render target count of {D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT}.");
|
||||
}
|
||||
|
||||
var key = hash.GetKey();
|
||||
var passPipelineKey = new PassPipelineKey(descriptor.RtvFormats, descriptor.DsvFormat);
|
||||
var materialPipelineKey = new MaterialPipelineKey(descriptor.PassId, descriptor.PipelineOption);
|
||||
var pipelineKey = GraphicsPipelineKey.Combine(materialPipelineKey, passPipelineKey);
|
||||
|
||||
if (!_pipelineCache.ContainsKey(key))
|
||||
if (!_pipelineCache.ContainsKey(pipelineKey))
|
||||
{
|
||||
var result = ValidatePassReflectionData(in compiled);
|
||||
if (result.IsFailure)
|
||||
@@ -327,26 +320,26 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary
|
||||
PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE,
|
||||
SampleMask = UINT32_MAX,
|
||||
SampleDesc = new DXGI_SAMPLE_DESC(1, 0),
|
||||
NumRenderTargets = rtvCount,
|
||||
NumRenderTargets = (uint)descriptor.RtvFormats.Length,
|
||||
DSVFormat = descriptor.DsvFormat.ToDXGIFormat(),
|
||||
DepthStencilState = BuildDepthStencil(descriptor.ZTest, descriptor.ZWrite),
|
||||
DepthStencilState = BuildDepthStencil(descriptor.PipelineOption.ZTest, descriptor.PipelineOption.ZWrite),
|
||||
NodeMask = 0,
|
||||
Flags = D3D12_PIPELINE_STATE_FLAG_NONE,
|
||||
|
||||
BlendState = descriptor.Blend switch
|
||||
BlendState = descriptor.PipelineOption.Blend switch
|
||||
{
|
||||
BlendOptions.Opaque => D3D12Utility.D3D12_BLEND_DESC_OPAQUE,
|
||||
BlendOptions.Alpha => D3D12Utility.D3D12_BLEND_DESC_ALPHA_BLEND,
|
||||
BlendOptions.Additive => D3D12Utility.D3D12_BLEND_DESC_ADDITIVE,
|
||||
BlendOptions.Multiply => D3D12Utility.D3D12_BLEND_DESC_MULTIPLY,
|
||||
BlendOptions.PremultipliedAlpha => D3D12Utility.D3D12_BLEND_DESC_PREMULTIPLIED,
|
||||
Blend.Opaque => D3D12Utility.D3D12_BLEND_DESC_OPAQUE,
|
||||
Blend.Alpha => D3D12Utility.D3D12_BLEND_DESC_ALPHA_BLEND,
|
||||
Blend.Additive => D3D12Utility.D3D12_BLEND_DESC_ADDITIVE,
|
||||
Blend.Multiply => D3D12Utility.D3D12_BLEND_DESC_MULTIPLY,
|
||||
Blend.PremultipliedAlpha => D3D12Utility.D3D12_BLEND_DESC_PREMULTIPLIED,
|
||||
_ => D3D12Utility.D3D12_BLEND_DESC_OPAQUE
|
||||
},
|
||||
RasterizerState = descriptor.Cull switch
|
||||
RasterizerState = descriptor.PipelineOption.Cull switch
|
||||
{
|
||||
CullOptions.Off => D3D12Utility.D3D12_RASTERIZER_DESC_CULL_NONE,
|
||||
CullOptions.Front => D3D12Utility.D3D12_RASTERIZER_DESC_CULL_CLOCKWISE,
|
||||
CullOptions.Back => D3D12Utility.D3D12_RASTERIZER_DESC_CULL_COUNTER_CLOCKWISE,
|
||||
Cull.Off => D3D12Utility.D3D12_RASTERIZER_DESC_CULL_NONE,
|
||||
Cull.Front => D3D12Utility.D3D12_RASTERIZER_DESC_CULL_CLOCKWISE,
|
||||
Cull.Back => D3D12Utility.D3D12_RASTERIZER_DESC_CULL_COUNTER_CLOCKWISE,
|
||||
_ => D3D12Utility.D3D12_RASTERIZER_DESC_CULL_NONE
|
||||
},
|
||||
};
|
||||
@@ -356,10 +349,10 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary
|
||||
desc.AS = new D3D12_SHADER_BYTECODE(compiled.tsResult.bytecode.GetUnsafePtr(), (nuint)compiled.tsResult.bytecode.Count);
|
||||
}
|
||||
|
||||
for (var i = 0; i < rtvCount && i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
|
||||
for (var i = 0; i < descriptor.RtvFormats.Length; i++)
|
||||
{
|
||||
desc.RTVFormats[i] = descriptor.RtvFormats[i].ToDXGIFormat();
|
||||
desc.BlendState.RenderTarget[i].RenderTargetWriteMask = (byte)(descriptor.ColorMask & 0x0F);
|
||||
desc.BlendState.RenderTarget[i].RenderTargetWriteMask = (byte)((int)descriptor.PipelineOption.ColorMask & 0x0F);
|
||||
}
|
||||
|
||||
var meshStream = new CD3DX12_PIPELINE_MESH_STATE_STREAM(in desc);
|
||||
@@ -373,7 +366,7 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary
|
||||
|
||||
var pKeyStr = stackalloc char[GraphicsPipelineKey.KEY_STRING_LENGTH];
|
||||
var keySpan = new Span<char>(pKeyStr, GraphicsPipelineKey.KEY_STRING_LENGTH);
|
||||
var kr = key.GetString(keySpan);
|
||||
var kr = pipelineKey.GetString(keySpan);
|
||||
if (kr.IsFailure)
|
||||
{
|
||||
return kr;
|
||||
@@ -396,10 +389,15 @@ internal unsafe class D3D12PipelineLibrary : IPipelineLibrary
|
||||
pso.psoDesc = desc;
|
||||
pso.pso.Attach(pPipelineState);
|
||||
|
||||
_pipelineCache[key] = pso;
|
||||
_pipelineCache[pipelineKey] = pso;
|
||||
}
|
||||
|
||||
return key;
|
||||
return pipelineKey;
|
||||
}
|
||||
|
||||
public bool HasPipeline(GraphicsPipelineKey key)
|
||||
{
|
||||
return _pipelineCache.ContainsKey(key);
|
||||
}
|
||||
|
||||
public Result<SharedPtr<ID3D12PipelineState>, ErrorStatus> GetGraphicsPSO(GraphicsPipelineKey key)
|
||||
|
||||
@@ -22,7 +22,7 @@ internal class D3D12Renderer : IRenderer
|
||||
// NOTE: Testing only.
|
||||
private readonly MeshRenderPass _pass;
|
||||
|
||||
public IRenderTargetStrategy? RenderTargetStrategy
|
||||
public IRenderOutput? RenderOutput
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
@@ -47,31 +47,31 @@ internal class D3D12Renderer : IRenderer
|
||||
|
||||
public Result Render(ICommandAllocator commandAllocator)
|
||||
{
|
||||
if (RenderTargetStrategy is null)
|
||||
if (RenderOutput is null)
|
||||
{
|
||||
return Result.Failure("Render target strategy is not set.");
|
||||
}
|
||||
|
||||
var target = RenderTargetStrategy.GetRenderTarget();
|
||||
var target = RenderOutput.GetRenderTarget();
|
||||
if (target.IsInvalid)
|
||||
{
|
||||
return Result.Failure("Render target is invalid.");
|
||||
}
|
||||
|
||||
_commandBuffer.Begin(commandAllocator);
|
||||
RenderTargetStrategy.BeginRender(_commandBuffer);
|
||||
RenderOutput.BeginRender(_commandBuffer);
|
||||
|
||||
// NOTE: Temperary solution: render directly to the swap chain back buffer if available.
|
||||
// HACK: This is hard coded for testing purposes only.
|
||||
|
||||
var error = RenderScene(target, RenderTargetStrategy.Viewport, RenderTargetStrategy.Scissor);
|
||||
var error = RenderScene(target, RenderOutput.Viewport, RenderOutput.Scissor);
|
||||
if (error != ErrorStatus.None)
|
||||
{
|
||||
_commandBuffer.End();
|
||||
return Result.Failure(error);
|
||||
}
|
||||
|
||||
RenderTargetStrategy.EndRender(_commandBuffer);
|
||||
RenderOutput.EndRender(_commandBuffer);
|
||||
var r = _commandBuffer.End();
|
||||
if (r.IsFailure)
|
||||
{
|
||||
@@ -79,7 +79,7 @@ internal class D3D12Renderer : IRenderer
|
||||
}
|
||||
|
||||
_graphicsEngine.Device.GraphicsQueue.Submit(_commandBuffer);
|
||||
RenderTargetStrategy.Present();
|
||||
RenderOutput.Present();
|
||||
|
||||
return Result.Success();
|
||||
}
|
||||
|
||||
@@ -100,8 +100,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
||||
private UnsafeHashMap<SamplerDesc, Identifier<Sampler>> _samplers;
|
||||
private UnsafeSlotMap<Mesh> _meshes;
|
||||
private UnsafeSlotMap<Material> _materials;
|
||||
private readonly DynamicArray<Shader?> _shaders; // NOTE: We use a simple list since shader is not frequently added/removed. This can save 4 bytes for each ecs component.
|
||||
// private UnsafeHashMap<ShaderPassKey, ShaderPass> _shaderPasses; // NOTE: The reason we use Dictionary here is that ShaderPassKey is a presistence identifier across multiple application sessions.
|
||||
private readonly DynamicArray<Shader> _shaders; // TODO: Use SlotMap?
|
||||
|
||||
private bool _disposed;
|
||||
|
||||
@@ -116,7 +115,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
||||
_samplers = new UnsafeHashMap<SamplerDesc, Identifier<Sampler>>(32, Allocator.Persistent);
|
||||
_meshes = new UnsafeSlotMap<Mesh>(64, Allocator.Persistent, AllocationOption.Clear);
|
||||
_materials = new UnsafeSlotMap<Material>(16, Allocator.Persistent, AllocationOption.Clear);
|
||||
_shaders = new DynamicArray<Shader?>(16);
|
||||
_shaders = new DynamicArray<Shader>(16);
|
||||
// _shaderPasses = new UnsafeHashMap<ShaderPassKey, ShaderPass>(32, Allocator.Persistent);
|
||||
}
|
||||
|
||||
@@ -410,10 +409,10 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
||||
public bool HasShader(Identifier<Shader> id)
|
||||
{
|
||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||
return id.Value >= 0 && id.Value < _shaders.Count && _shaders[id.Value] != null;
|
||||
return id.Value >= 0 && id.Value < _shaders.Count;
|
||||
}
|
||||
|
||||
public Shader GetShaderReference(Identifier<Shader> id)
|
||||
public ref Shader GetShaderReference(Identifier<Shader> id)
|
||||
{
|
||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||
|
||||
@@ -422,8 +421,7 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
||||
throw new ArgumentOutOfRangeException(nameof(id), $"Shader id {id} is invalid.");
|
||||
}
|
||||
|
||||
var shader = _shaders[id.Value]!;
|
||||
return shader;
|
||||
return ref _shaders[id.Value];
|
||||
}
|
||||
|
||||
public void ReleaseShader(Identifier<Shader> id)
|
||||
@@ -470,11 +468,6 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
||||
for (var i = 0; i < _shaders.Count; i++)
|
||||
{
|
||||
ref var shader = ref _shaders[i];
|
||||
if (shader == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ReleaseResource(ref shader);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user