Refactor MeshInstance
This commit is contained in:
@@ -1,47 +1,15 @@
|
|||||||
using Ghost.Core;
|
using Ghost.Core;
|
||||||
using Ghost.Entities;
|
using Ghost.Entities;
|
||||||
using Ghost.Graphics.Core;
|
using Ghost.Graphics.Core;
|
||||||
using Misaki.HighPerformance.LowLevel.Collections;
|
|
||||||
|
|
||||||
namespace Ghost.Engine.Components;
|
namespace Ghost.Engine.Components;
|
||||||
|
|
||||||
public struct MeshPalette : ISharedComponent, IEquatable<MeshPalette>
|
|
||||||
{
|
|
||||||
public UnsafeArray<Handle<Mesh>> meshes;
|
|
||||||
public UnsafeArray<Handle<Material>> materials;
|
|
||||||
|
|
||||||
public bool Equals(MeshPalette other)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int GetHashCode()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object? obj)
|
|
||||||
{
|
|
||||||
return obj is MeshPalette palette && Equals(palette);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator ==(MeshPalette left, MeshPalette right)
|
|
||||||
{
|
|
||||||
return left.Equals(right);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool operator !=(MeshPalette left, MeshPalette right)
|
|
||||||
{
|
|
||||||
return !(left == right);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct MeshInstance : IComponent
|
public struct MeshInstance : IComponent
|
||||||
{
|
{
|
||||||
public int meshIndex;
|
public Handle<Mesh> mesh;
|
||||||
public int materialIndex;
|
// NOTE: This will be the first material, we can access other materials by the bindless index of the first material + the local index stored in the meshlet.
|
||||||
|
public Handle<Material> materialStart;
|
||||||
public ShadowCastingMode shadowCastingMode;
|
public ShadowCastingMode shadowCastingMode;
|
||||||
public RenderingLayerMask renderingLayerMask;
|
public RenderingLayerMask renderingLayerMask;
|
||||||
public byte subMeshIndex;
|
|
||||||
public bool staticShadowCaster;
|
public bool staticShadowCaster;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Ghost.Engine.Components;
|
|||||||
using Ghost.Entities;
|
using Ghost.Entities;
|
||||||
using Ghost.Graphics.Core;
|
using Ghost.Graphics.Core;
|
||||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
using Misaki.HighPerformance.LowLevel.Utilities;
|
|
||||||
|
|
||||||
namespace Ghost.Engine.Systems;
|
namespace Ghost.Engine.Systems;
|
||||||
|
|
||||||
@@ -14,7 +13,6 @@ public class RenderExtractionSystem : ISystem
|
|||||||
public void Initialize(ref readonly SystemAPI systemAPI)
|
public void Initialize(ref readonly SystemAPI systemAPI)
|
||||||
{
|
{
|
||||||
_queryID = new QueryBuilder()
|
_queryID = new QueryBuilder()
|
||||||
// TODO: We also need to filter by MeshPalette.
|
|
||||||
.WithAll<MeshInstance, LocalToWorld>()
|
.WithAll<MeshInstance, LocalToWorld>()
|
||||||
.Build(systemAPI.World);
|
.Build(systemAPI.World);
|
||||||
}
|
}
|
||||||
@@ -30,6 +28,7 @@ public class RenderExtractionSystem : ISystem
|
|||||||
var renderList = new RenderList(1, 64, Allocator.Temp);
|
var renderList = new RenderList(1, 64, Allocator.Temp);
|
||||||
|
|
||||||
// TODO: We should extract the render record for each camera because different cameras may have different culling results.
|
// TODO: We should extract the render record for each camera because different cameras may have different culling results.
|
||||||
|
// TODO: This chould be done in parallel jobs.
|
||||||
foreach (var chunk in query.GetChunkIterator())
|
foreach (var chunk in query.GetChunkIterator())
|
||||||
{
|
{
|
||||||
var meshInstances = chunk.GetComponentData<MeshInstance>();
|
var meshInstances = chunk.GetComponentData<MeshInstance>();
|
||||||
@@ -47,7 +46,6 @@ public class RenderExtractionSystem : ISystem
|
|||||||
// mesh = meshInstance.meshIndex,
|
// mesh = meshInstance.meshIndex,
|
||||||
// material = meshInstance.materialIndex,
|
// material = meshInstance.materialIndex,
|
||||||
renderingLayerMask = meshInstance.renderingLayerMask,
|
renderingLayerMask = meshInstance.renderingLayerMask,
|
||||||
subMeshIndex = meshInstance.subMeshIndex,
|
|
||||||
|
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -341,6 +341,23 @@ internal class D3D12ResourceDatabase : IResourceDatabase
|
|||||||
_descriptorAllocator.Release(new Identifier<SamplerDescriptor>(id.Value));
|
_descriptorAllocator.Release(new Identifier<SamplerDescriptor>(id.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Error Swap(Handle<GPUResource> handleA, Handle<GPUResource> handleB)
|
||||||
|
{
|
||||||
|
ref var recordA = ref _resources.GetElementReferenceAt(handleA.ID, handleA.Generation, out var existA);
|
||||||
|
ref var recordB = ref _resources.GetElementReferenceAt(handleB.ID, handleB.Generation, out var existB);
|
||||||
|
|
||||||
|
if (!existA || !existB)
|
||||||
|
{
|
||||||
|
return Error.NotFound;
|
||||||
|
}
|
||||||
|
|
||||||
|
var temp = recordA;
|
||||||
|
recordA = recordB;
|
||||||
|
recordB = temp;
|
||||||
|
|
||||||
|
return Error.None;
|
||||||
|
}
|
||||||
|
|
||||||
public void BeginFrame(uint currentFrameFenceValue)
|
public void BeginFrame(uint currentFrameFenceValue)
|
||||||
{
|
{
|
||||||
ObjectDisposedException.ThrowIf(_disposed, this);
|
ObjectDisposedException.ThrowIf(_disposed, this);
|
||||||
|
|||||||
@@ -127,4 +127,12 @@ public interface IResourceDatabase : IDisposable
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id">The identifier of the sampler to release. Must reference a valid, existing sampler.</param>
|
/// <param name="id">The identifier of the sampler to release. Must reference a valid, existing sampler.</param>
|
||||||
void ReleaseSampler(Identifier<Sampler> id);
|
void ReleaseSampler(Identifier<Sampler> id);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Swaps the resources associated with the two specified handles, effectively exchanging their identities and all associated data.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="handleA">The first handle whose associated resource is to be swapped.</param>
|
||||||
|
/// <param name="handleB">The second handle whose associated resource is to be swapped.</param>
|
||||||
|
/// <returns>An Error indicating the success or failure of the swap operation.</returns>
|
||||||
|
Error Swap(Handle<GPUResource> handleA, Handle<GPUResource> handleB);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,10 +8,9 @@ namespace Ghost.Graphics.Core;
|
|||||||
public record struct RenderRecord
|
public record struct RenderRecord
|
||||||
{
|
{
|
||||||
public float4x4 localToWorld;
|
public float4x4 localToWorld;
|
||||||
public Handle<Material> material;
|
|
||||||
public Handle<Mesh> mesh;
|
public Handle<Mesh> mesh;
|
||||||
|
public Handle<Material> materialOffset;
|
||||||
public RenderingLayerMask renderingLayerMask;
|
public RenderingLayerMask renderingLayerMask;
|
||||||
public byte subMeshIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct RenderList : IDisposable
|
public struct RenderList : IDisposable
|
||||||
|
|||||||
@@ -20,7 +20,10 @@ internal sealed class SwapChainRecord
|
|||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
int current = Volatile.Read(ref _refCount);
|
int current = Volatile.Read(ref _refCount);
|
||||||
if (current == 0) return false; // It's dead, let it go.
|
if (current == 0)
|
||||||
|
{
|
||||||
|
return false; // It's dead, let it go.
|
||||||
|
}
|
||||||
|
|
||||||
if (Interlocked.CompareExchange(ref _refCount, current + 1, current) == current)
|
if (Interlocked.CompareExchange(ref _refCount, current + 1, current) == current)
|
||||||
{
|
{
|
||||||
@@ -66,7 +69,10 @@ internal class SwapChainManager
|
|||||||
|
|
||||||
if (record != null)
|
if (record != null)
|
||||||
{
|
{
|
||||||
if (record.TryAddRef()) return record.SwapChain;
|
if (record.TryAddRef())
|
||||||
|
{
|
||||||
|
return record.SwapChain;
|
||||||
|
}
|
||||||
|
|
||||||
Thread.Yield();
|
Thread.Yield();
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Ghost.Nvtt – Usage Guide
|
# Ghost.Nvtt - Usage Guide
|
||||||
|
|
||||||
`Ghost.Nvtt` is a managed C# wrapper over the NVIDIA Texture Tools 3 (nvtt) native library.
|
`Ghost.Nvtt` is a managed C# wrapper over the NVIDIA Texture Tools 3 (nvtt) native library.
|
||||||
All wrapper classes are in the `Ghost.Nvtt` namespace. Add a single `using Ghost.Nvtt;` and you have access to every wrapper class and every enum.
|
All wrapper classes are in the `Ghost.Nvtt` namespace. Add a single `using Ghost.Nvtt;` and you have access to every wrapper class and every enum.
|
||||||
@@ -99,7 +99,7 @@ set.LoadDDS("texture_array.dds");
|
|||||||
Console.WriteLine($"{set.FaceCount} faces, {set.MipmapCount} mips, " +
|
Console.WriteLine($"{set.FaceCount} faces, {set.MipmapCount} mips, " +
|
||||||
$"{set.Width}x{set.Height}");
|
$"{set.Width}x{set.Height}");
|
||||||
|
|
||||||
// Access the raw pointer for face 0, mip 0 (borrowed – do not dispose)
|
// Access the raw pointer for face 0, mip 0 (borrowed - do not dispose)
|
||||||
var surfacePtr = set.GetSurfacePtr(faceId: 0, mipId: 0);
|
var surfacePtr = set.GetSurfacePtr(faceId: 0, mipId: 0);
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -203,10 +203,10 @@ diff.Save("diff.png");
|
|||||||
|
|
||||||
| Returns | Ownership |
|
| Returns | Ownership |
|
||||||
|---------|-----------|
|
|---------|-----------|
|
||||||
| `new NvttSurface(...)` constructor overload accepting a raw pointer | **Takes** ownership – dispose when done |
|
| `new NvttSurface(...)` constructor overload accepting a raw pointer | **Takes** ownership - dispose when done |
|
||||||
| `NvttSurface.Clone()` | Caller owns result |
|
| `NvttSurface.Clone()` | Caller owns result |
|
||||||
| `NvttSurface.CreateSubImage()`, `CreateToksvigMap()` | Caller owns result |
|
| `NvttSurface.CreateSubImage()`, `CreateToksvigMap()` | Caller owns result |
|
||||||
| `NvttCubeSurface.Unfold()`, `IrradianceFilter()`, `CosinePowerFilter()`, `FastResample()` | Caller owns result |
|
| `NvttCubeSurface.Unfold()`, `IrradianceFilter()`, `CosinePowerFilter()`, `FastResample()` | Caller owns result |
|
||||||
| `NvttGlobal.Diff()`, `Histogram()`, `HistogramRange()` | Caller owns result |
|
| `NvttGlobal.Diff()`, `Histogram()`, `HistogramRange()` | Caller owns result |
|
||||||
| `NvttCubeSurface.FacePtr()`, `NvttSurfaceSet.GetSurfacePtr()` | **Borrowed** – do NOT dispose |
|
| `NvttCubeSurface.FacePtr()`, `NvttSurfaceSet.GetSurfacePtr()` | **Borrowed** - do NOT dispose |
|
||||||
| `NvttContext.GetTimingContextPtr()` | **Borrowed** – do NOT dispose |
|
| `NvttContext.GetTimingContextPtr()` | **Borrowed** - do NOT dispose |
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ public sealed unsafe class NvttBatchListHandle : IDisposable
|
|||||||
{
|
{
|
||||||
private NvttBatchList* _ptr;
|
private NvttBatchList* _ptr;
|
||||||
|
|
||||||
/// <summary>Raw pointer – use only when calling the native API directly.</summary>
|
/// <summary>Raw pointer - use only when calling the native API directly.</summary>
|
||||||
public NvttBatchList* Ptr => _ptr;
|
public NvttBatchList* Ptr => _ptr;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
@@ -62,7 +62,7 @@ public sealed unsafe class NvttBatchListHandle : IDisposable
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the raw pointers for item <paramref name="index"/>.
|
/// Returns the raw pointers for item <paramref name="index"/>.
|
||||||
/// The pointers are borrowed – do NOT dispose them.
|
/// The pointers are borrowed - do NOT dispose them.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void GetItem(uint index,
|
public void GetItem(uint index,
|
||||||
out NvttSurface* surface, out int face, out int mipmap,
|
out NvttSurface* surface, out int face, out int mipmap,
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
namespace Ghost.Nvtt;
|
namespace Ghost.Nvtt;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Controls how a surface is compressed – format, quality, pixel layout and
|
/// Controls how a surface is compressed - format, quality, pixel layout and
|
||||||
/// optional quantization settings.
|
/// optional quantization settings.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed unsafe class NvttCompressionOptionsHandle : IDisposable
|
public sealed unsafe class NvttCompressionOptionsHandle : IDisposable
|
||||||
{
|
{
|
||||||
private NvttCompressionOptions* _ptr;
|
private NvttCompressionOptions* _ptr;
|
||||||
|
|
||||||
/// <summary>Raw pointer – use only when calling the native API directly.</summary>
|
/// <summary>Raw pointer - use only when calling the native API directly.</summary>
|
||||||
public NvttCompressionOptions* Ptr => _ptr;
|
public NvttCompressionOptions* Ptr => _ptr;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ public sealed unsafe class NvttContextHandle : IDisposable
|
|||||||
{
|
{
|
||||||
private NvttContext* _ptr;
|
private NvttContext* _ptr;
|
||||||
|
|
||||||
/// <summary>Raw pointer – use only when calling the native API directly.</summary>
|
/// <summary>Raw pointer - use only when calling the native API directly.</summary>
|
||||||
public NvttContext* Ptr => _ptr;
|
public NvttContext* Ptr => _ptr;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
@@ -63,7 +63,7 @@ public sealed unsafe class NvttContextHandle : IDisposable
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the timing context owned by this nvtt context.
|
/// Returns the timing context owned by this nvtt context.
|
||||||
/// The pointer is borrowed – do NOT dispose it separately.
|
/// The pointer is borrowed - do NOT dispose it separately.
|
||||||
/// Returns <c>null</c> if timing was never enabled.
|
/// Returns <c>null</c> if timing was never enabled.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NvttTimingContext* GetTimingContextPtr()
|
public NvttTimingContext* GetTimingContextPtr()
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public sealed unsafe class NvttCubeSurfaceHandle : IDisposable
|
|||||||
{
|
{
|
||||||
private NvttCubeSurface* _ptr;
|
private NvttCubeSurface* _ptr;
|
||||||
|
|
||||||
/// <summary>Raw pointer – use only when calling the native API directly.</summary>
|
/// <summary>Raw pointer - use only when calling the native API directly.</summary>
|
||||||
public NvttCubeSurface* Ptr => _ptr;
|
public NvttCubeSurface* Ptr => _ptr;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
@@ -102,7 +102,7 @@ public sealed unsafe class NvttCubeSurfaceHandle : IDisposable
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the raw <see cref="NvttSurface"/> pointer for the given face
|
/// Returns the raw <see cref="NvttSurface"/> pointer for the given face
|
||||||
/// (0–5). The pointer is owned by this cube surface – do NOT dispose it.
|
/// (0–5). The pointer is owned by this cube surface - do NOT dispose it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NvttSurface* FacePtr(int face)
|
public NvttSurface* FacePtr(int face)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ public sealed unsafe class NvttOutputOptionsHandle : IDisposable
|
|||||||
{
|
{
|
||||||
private NvttOutputOptions* _ptr;
|
private NvttOutputOptions* _ptr;
|
||||||
|
|
||||||
/// <summary>Raw pointer – use only when calling the native API directly.</summary>
|
/// <summary>Raw pointer - use only when calling the native API directly.</summary>
|
||||||
public NvttOutputOptions* Ptr => _ptr;
|
public NvttOutputOptions* Ptr => _ptr;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
@@ -31,7 +31,7 @@ public sealed unsafe class NvttOutputOptionsHandle : IDisposable
|
|||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
private delegate void ErrorDelegate(Ghost.Nvtt.Native.NvttError error);
|
private delegate void ErrorDelegate(Ghost.Nvtt.Native.NvttError error);
|
||||||
|
|
||||||
// Pinned delegate instances – must stay alive as long as native code may call them.
|
// Pinned delegate instances - must stay alive as long as native code may call them.
|
||||||
private BeginImageDelegate? _beginImageDelegate;
|
private BeginImageDelegate? _beginImageDelegate;
|
||||||
private OutputDataDelegate? _outputDataDelegate;
|
private OutputDataDelegate? _outputDataDelegate;
|
||||||
private ErrorDelegate? _errorDelegate;
|
private ErrorDelegate? _errorDelegate;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ public sealed unsafe class NvttSurfaceHandle : IDisposable
|
|||||||
{
|
{
|
||||||
private NvttSurface* _ptr;
|
private NvttSurface* _ptr;
|
||||||
|
|
||||||
/// <summary>Raw pointer – use only when calling the native API directly.</summary>
|
/// <summary>Raw pointer - use only when calling the native API directly.</summary>
|
||||||
public NvttSurface* Ptr => _ptr;
|
public NvttSurface* Ptr => _ptr;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ public sealed unsafe class NvttSurfaceSetHandle : IDisposable
|
|||||||
{
|
{
|
||||||
private NvttSurfaceSet* _ptr;
|
private NvttSurfaceSet* _ptr;
|
||||||
|
|
||||||
/// <summary>Raw pointer – use only when calling the native API directly.</summary>
|
/// <summary>Raw pointer - use only when calling the native API directly.</summary>
|
||||||
public NvttSurfaceSet* Ptr => _ptr;
|
public NvttSurfaceSet* Ptr => _ptr;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
@@ -72,7 +72,7 @@ public sealed unsafe class NvttSurfaceSetHandle : IDisposable
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the raw <see cref="NvttSurface"/> pointer for the given face
|
/// Returns the raw <see cref="NvttSurface"/> pointer for the given face
|
||||||
/// and mip level. The pointer is owned by this surface set – do NOT dispose
|
/// and mip level. The pointer is owned by this surface set - do NOT dispose
|
||||||
/// it.
|
/// it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NvttSurface* GetSurfacePtr(int faceId, int mipId, bool expectSigned = false)
|
public NvttSurface* GetSurfacePtr(int faceId, int mipId, bool expectSigned = false)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public sealed unsafe class NvttTimingContextHandle : IDisposable
|
|||||||
{
|
{
|
||||||
private NvttTimingContext* _ptr;
|
private NvttTimingContext* _ptr;
|
||||||
|
|
||||||
/// <summary>Raw pointer – use only when calling the native API directly.</summary>
|
/// <summary>Raw pointer - use only when calling the native API directly.</summary>
|
||||||
public NvttTimingContext* Ptr => _ptr;
|
public NvttTimingContext* Ptr => _ptr;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user