Update asset system for deferred allocation & add unit tests
Modernize Misaki.HighPerformance dependencies. Refactor texture asset creation to use deferred resource slots via CreateEmpty(). Remove fallback resource fields and update texture resolution logic. Add CreateEmpty() to resource database interfaces. Introduce comprehensive unit tests with mocks for asset management. Enable unsafe code in tests.
This commit is contained in:
@@ -20,14 +20,14 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Misaki.HighPerformance" Version="1.0.8" />
|
||||
<PackageReference Include="Misaki.HighPerformance.Jobs" Version="3.1.2" />
|
||||
<PackageReference Include="Misaki.HighPerformance.LowLevel" Version="1.6.16">
|
||||
<PackageReference Include="Misaki.HighPerformance" Version="1.0.9" />
|
||||
<PackageReference Include="Misaki.HighPerformance.Jobs" Version="3.1.3" />
|
||||
<PackageReference Include="Misaki.HighPerformance.LowLevel" Version="1.6.17">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Misaki.HighPerformance.Mathematics" Version="1.3.3" />
|
||||
<PackageReference Include="Misaki.HighPerformance.Mathematics.SPMD" Version="1.3.2" />
|
||||
<PackageReference Include="Misaki.HighPerformance.Mathematics.SPMD" Version="1.3.4" />
|
||||
<PackageReference Include="System.IO.Hashing" Version="10.0.7" />
|
||||
<PackageReference Include="TerraFX.Interop.Mimalloc" Version="1.6.7.2" />
|
||||
<PackageReference Include="TerraFX.Interop.Windows" Version="10.0.26100.6" />
|
||||
|
||||
@@ -34,7 +34,7 @@ internal partial class AssetEntry
|
||||
{
|
||||
// This will create a new slot in the database, but not allocation any GPU resource.
|
||||
// Everything in the slot will have the same value as the fallback texture, expect the slot will be marked as shared.
|
||||
var handle = e._resourceDatabase.CreateShared(e._assetManager.FallbackTexture.AsResource()).AsTexture();
|
||||
var handle = e._resourceDatabase.CreateEmpty().AsTexture();
|
||||
e.SetStorage(handle);
|
||||
};
|
||||
|
||||
@@ -155,7 +155,7 @@ internal partial class AssetManager
|
||||
{
|
||||
if (assetID == Guid.Empty)
|
||||
{
|
||||
return _fallbackTexture;
|
||||
return Handle<GPUTexture>.Invalid;
|
||||
}
|
||||
|
||||
var entry = GetOrCreateEntry(assetID);
|
||||
|
||||
@@ -295,17 +295,9 @@ internal partial class AssetManager : IDisposable
|
||||
|
||||
private readonly ConcurrentDictionary<Guid, AssetEntry> _entries;
|
||||
|
||||
// TODO
|
||||
private Handle<GPUTexture> _fallbackTexture;
|
||||
private Handle<GPUTexture> _fallbackNormalMap;
|
||||
private Handle<Mesh> _fallbackMesh;
|
||||
private Handle<Material> _fallbackMaterial;
|
||||
|
||||
public IContentProvider ContentProvider => _contentProvider;
|
||||
public ResourceStreamingProcessor StreamingProcessor => _streamingProcessor;
|
||||
|
||||
public Handle<GPUTexture> FallbackTexture => _fallbackTexture;
|
||||
|
||||
internal AssetManager(IResourceDatabase resourceDatabase, IContentProvider contentProvider, ResourceStreamingProcessor streamingProcessor, JobScheduler jobScheduler)
|
||||
{
|
||||
_resourceDatabase = resourceDatabase;
|
||||
@@ -378,10 +370,10 @@ internal partial class AssetManager : IDisposable
|
||||
for (var i = list.Count - 1; i >= 0; i--)
|
||||
{
|
||||
// This should create the entry and schedule the job on those assets does not have any dependency first.
|
||||
var handle = GetOrCreateEntry(list[i]).LoadJobHandle;
|
||||
Logger.DebugAssert(handle.IsValid);
|
||||
var depHandle = GetOrCreateEntry(list[i]).LoadJobHandle;
|
||||
Logger.DebugAssert(depHandle.IsValid);
|
||||
|
||||
depHandles.Add(handle);
|
||||
depHandles.Add(depHandle);
|
||||
}
|
||||
|
||||
dependency = _jobScheduler.CombineDependencies(depHandles);
|
||||
@@ -394,7 +386,8 @@ internal partial class AssetManager : IDisposable
|
||||
assetManager = this,
|
||||
};
|
||||
|
||||
entry.SetLoadJobHandle(_jobScheduler.Schedule(ref job, JobPriority.Low, dependency)); // Use low priority to avoid blocking main thread critical tasks like rendering and physics.
|
||||
var handle = _jobScheduler.Schedule(ref job, JobPriority.Low, dependency);
|
||||
entry.SetLoadJobHandle(handle); // Use low priority to avoid blocking main thread critical tasks like rendering and physics.
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Ghost.Core;
|
||||
using Ghost.Graphics;
|
||||
using SharpCompress.Common;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace Ghost.Engine;
|
||||
|
||||
@@ -442,6 +442,15 @@ internal unsafe class D3D12ResourceDatabase : IResourceDatabase
|
||||
}
|
||||
}
|
||||
|
||||
public Handle<GPUResource> CreateEmpty()
|
||||
{
|
||||
lock (_writeLock)
|
||||
{
|
||||
var id = _resources.Add(default, out var generation);
|
||||
return new Handle<GPUResource>(id, generation);
|
||||
}
|
||||
}
|
||||
|
||||
public void* MapResource(Handle<GPUResource> handle, uint subResource, ResourceRange? readRange)
|
||||
{
|
||||
var r = GetResourceRecord(handle);
|
||||
|
||||
@@ -142,6 +142,12 @@ public unsafe interface IResourceDatabase : IDisposable
|
||||
/// <returns>The handle to the newly created shared resource.</returns>
|
||||
Handle<GPUResource> CreateShared(Handle<GPUResource> src);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a slot in the resource database that contains no GPU resource, and returns a handle to that slot. This can be used as a placeholder for a resource that will be created or assigned later, allowing for deferred resource creation and management.
|
||||
/// </summary>
|
||||
/// <returns>The handle to the newly created empty resource slot.</returns>
|
||||
Handle<GPUResource> CreateEmpty();
|
||||
|
||||
/// <summary>
|
||||
/// Maps a subresource of a GPU resource for CPU access, specifying read and write ranges.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user