forked from Misaki/GhostEngine
Add Ghost.Nvtt C# wrapper and integrate nvtt texture pipeline
- Introduce full managed C# wrapper for NVIDIA Texture Tools (nvtt) with safe handle classes, idiomatic APIs, and managed callback support. - Integrate Ghost.Nvtt into Ghost.Editor.Core and Ghost.MicroTest; update TextureAssetHandler to use the new nvtt wrapper for texture compression. - Add comprehensive end-to-end binding test (NvttBindingTest). - Refactor D3D12 resource management: add deferred/immediate release APIs, update allocator/database usage, and ensure proper resource cleanup. - Update project files for new native DLL layout and dependency versions. - Minor API cleanups: EditorApplication properties, D3D12 input layout, and removal of obsolete code. - Update shaders, tests, and documentation for new APIs and usage patterns.
This commit is contained in:
67
src/ThridParty/Ghost.Nvtt/NvttInterop.cs
Normal file
67
src/ThridParty/Ghost.Nvtt/NvttInterop.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Ghost.Nvtt;
|
||||
|
||||
/// <summary>
|
||||
/// Internal helpers for converting between managed and unmanaged types.
|
||||
/// </summary>
|
||||
internal static unsafe class NvttInterop
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static NvttBoolean ToNvtt(bool value)
|
||||
=> value ? NvttBoolean.NVTT_True : NvttBoolean.NVTT_False;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static bool ToBool(NvttBoolean value)
|
||||
=> value != NvttBoolean.NVTT_False;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// String to UTF-8 sbyte*
|
||||
//
|
||||
// Usage pattern:
|
||||
// fixed (byte* ptr = NvttInterop.ToUtf8(str, stackalloc byte[MaxStack]))
|
||||
// Api.nvttSomething((sbyte*)ptr);
|
||||
//
|
||||
// For paths longer than MaxStack bytes the helper falls back to a heap
|
||||
// allocation via Encoding.UTF8.GetBytes. The Span<byte> overload lets the
|
||||
// caller decide the stackalloc size.
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
internal const int _MAX_STACK_PATH = 512;
|
||||
|
||||
/// <summary>
|
||||
/// Encode <paramref name="value"/> as null-terminated UTF-8 into
|
||||
/// <paramref name="buffer"/>. Returns the used portion (including the
|
||||
/// null terminator). If the buffer is too small a new heap array is
|
||||
/// returned instead.
|
||||
/// </summary>
|
||||
internal static Span<byte> ToUtf8(string value, Span<byte> buffer)
|
||||
{
|
||||
var needed = Encoding.UTF8.GetByteCount(value) + 1; // +1 for null term
|
||||
if (needed > buffer.Length)
|
||||
{
|
||||
buffer = new byte[needed];
|
||||
}
|
||||
|
||||
var written = Encoding.UTF8.GetBytes(value, buffer);
|
||||
buffer[written] = 0; // null terminator
|
||||
return buffer[..(written + 1)];
|
||||
}
|
||||
|
||||
internal static string? FromUtf8(sbyte* ptr)
|
||||
{
|
||||
if (ptr == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var len = 0;
|
||||
while (ptr[len] != 0)
|
||||
{
|
||||
len++;
|
||||
}
|
||||
|
||||
return Encoding.UTF8.GetString((byte*)ptr, len);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user