Refactor instance update flow, asset registry, and texture IO

- Renamed AddInstanceRequest to UpdateInstanceRequest; unified add/update logic for GPU instances
- Introduced UpdateGPUInstanceSystem to handle changed MeshInstance components
- Replaced QueryBuilder.Create() with QueryBuilder.New() for consistency
- Switched versioning in ChunkView HasChanged/HasStructuralChanged to uint
- Added extension-to-AssetType mapping in AssetHandlerRegistry
- Changed TextureAssetHandler/Processor to use nint for image data
- Enhanced DDS cache: read mipmap count, handle invalid files
- Updated ProjectBrowserViewModel to use IAssetRegistry
- Upgraded Misaki.HighPerformance and System.IO.Hashing packages
- Set DependencyChainCapacity in JobSchedulerDesc
- Fixed instance buffer logic in GhostRenderPipeline
- Miscellaneous cleanups and namespace improvements
This commit is contained in:
2026-04-22 15:36:49 +09:00
parent cb4092179f
commit 884611181a
19 changed files with 150 additions and 55 deletions

View File

@@ -10,7 +10,7 @@ namespace Ghost.Engine.RenderPipeline;
internal sealed class GhostRenderPayload : IRenderPayload
{
public struct AddInstanceRequest
public struct UpdateInstanceRequest
{
public MeshInstance meshInstance;
public float4x4 localToWorld;
@@ -27,7 +27,7 @@ internal sealed class GhostRenderPayload : IRenderPayload
private UnsafeList<RenderRequest> _renderRequests;
private readonly ConcurrentQueue<AddInstanceRequest> _addRequest;
private readonly ConcurrentQueue<UpdateInstanceRequest> _updateRequest;
private readonly ConcurrentQueue<RemoveInstanceRequest> _removeRequest;
private uint _instanceCountBefore;
@@ -35,7 +35,7 @@ internal sealed class GhostRenderPayload : IRenderPayload
public ReadOnlySpan<RenderRequest> RenderRequests => _renderRequests;
public ConcurrentQueue<AddInstanceRequest> AddRequest => _addRequest;
public ConcurrentQueue<UpdateInstanceRequest> UpdateRequest => _updateRequest;
public ConcurrentQueue<RemoveInstanceRequest> RemoveRequest => _removeRequest;
public uint InstanceCountBefore => _instanceCountBefore;
public uint InstanceCount => _instanceCount;
@@ -45,7 +45,7 @@ internal sealed class GhostRenderPayload : IRenderPayload
_renderPipeline = renderPipeline;
_renderRequests = new UnsafeList<RenderRequest>(4, Misaki.HighPerformance.LowLevel.Buffer.AllocationHandle.Persistent);
_addRequest = new ConcurrentQueue<AddInstanceRequest>();
_updateRequest = new ConcurrentQueue<UpdateInstanceRequest>();
_removeRequest = new ConcurrentQueue<RemoveInstanceRequest>();
}
@@ -59,10 +59,15 @@ internal sealed class GhostRenderPayload : IRenderPayload
{
var index = _renderPipeline.GPUScene.AddInstance();
_addRequest.Enqueue(new AddInstanceRequest { instanceId = index, localToWorld = ltw, meshInstance = meshInstance });
_updateRequest.Enqueue(new UpdateInstanceRequest { instanceId = index, localToWorld = ltw, meshInstance = meshInstance });
return index;
}
public void UpdateInstance(uint instanceId, float4x4 ltw, ref readonly MeshInstance meshInstance)
{
_updateRequest.Enqueue(new UpdateInstanceRequest { instanceId = instanceId, localToWorld = ltw, meshInstance = meshInstance });
}
public void RemoveInstance(uint instanceId)
{
var swapWithInstanceId = _renderPipeline.GPUScene.RemoveInstance(instanceId);
@@ -81,13 +86,13 @@ internal sealed class GhostRenderPayload : IRenderPayload
{
// We capture the count here to prevent that main thread continues to add more requests for next frame while the render thread is still processing current frame's requests.
_instanceCount = _renderPipeline.GPUScene.InstanceCount;
Logger.DebugAssert(_instanceCount == _instanceCountBefore + (uint)_addRequest.Count - (uint)_removeRequest.Count);
Logger.DebugAssert(_instanceCount == _instanceCountBefore + (uint)_updateRequest.Count - (uint)_removeRequest.Count);
}
public void Reset()
{
_renderRequests.Clear();
_addRequest.Clear();
_updateRequest.Clear();
_removeRequest.Clear();
}