Add Editor configs, refactor test core, DXC test
Added Debug_Editor/Release_Editor configs to all projects and solution. Refactored test utilities into Ghost.TestCore and updated references. Introduced DXCBindingTest for shader compilation. Updated conditional compilation to use GHOST_EDITOR. Improved platform mappings and performed minor code cleanup.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using Ghost.Test.Core;
|
||||
using Ghost.TestCore;
|
||||
using Misaki.HighPerformance.Jobs;
|
||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||
using Misaki.HighPerformance.Mathematics;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<Configurations>Debug;Release;Debug_Editor;Release_Editor</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -15,7 +16,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Runtime\Ghost.Entities\Ghost.Entities.csproj" />
|
||||
<ProjectReference Include="..\..\Test\Ghost.Test.Core\Ghost.Test.Core.csproj" />
|
||||
<ProjectReference Include="..\..\Test\Ghost.TestCore\Ghost.TestCore.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ghost.Test.Core;
|
||||
using Ghost.TestCore;
|
||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||
using Misaki.HighPerformance.Mathematics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ghost.Test.Core;
|
||||
using Ghost.TestCore;
|
||||
|
||||
namespace Ghost.Entities.Test;
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<EnableMsixTooling>true</EnableMsixTooling>
|
||||
<Nullable>enable</Nullable>
|
||||
<Configurations>Debug;Release;Debug_Editor;Release_Editor</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -50,7 +51,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Runtime\Ghost.Engine\Ghost.Engine.csproj" />
|
||||
<ProjectReference Include="..\..\Test\Ghost.Test.Core\Ghost.Test.Core.csproj" />
|
||||
<ProjectReference Include="..\..\Test\Ghost.TestCore\Ghost.TestCore.csproj" />
|
||||
<ProjectReference Include="..\..\Runtime\Ghost.Graphics\Ghost.Graphics.csproj" />
|
||||
<ProjectReference Include="..\..\Editor\Ghost.DSL\Ghost.DSL.csproj" />
|
||||
<ProjectReference Include="..\..\ThridParty\Ghost.Ufbx\Ghost.Ufbx.csproj" />
|
||||
@@ -68,6 +69,7 @@
|
||||
<!-- Publish Properties -->
|
||||
<PropertyGroup>
|
||||
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
|
||||
<PublishReadyToRun Condition="'$(Configuration)'=='Debug_Editor'">False</PublishReadyToRun>
|
||||
<PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun>
|
||||
<SupportedOSPlatformVersion>10.0.20348.0</SupportedOSPlatformVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
@@ -76,10 +78,19 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Editor|x86'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Editor|x64'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_Editor|ARM64'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
171
src/Test/Ghost.MicroTest/DXCBindingTest.cs
Normal file
171
src/Test/Ghost.MicroTest/DXCBindingTest.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
using Ghost.DXC;
|
||||
using Ghost.TestCore;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using static Ghost.DXC.UUID;
|
||||
|
||||
namespace Ghost.MicroTest;
|
||||
|
||||
internal unsafe class DXCBindingTest : ITest
|
||||
{
|
||||
private static ReadOnlySpan<byte> ShaderCode => @"
|
||||
struct VSInput
|
||||
{
|
||||
float3 position : POSITION;
|
||||
float3 normal : NORMAL;
|
||||
};
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 position : SV_POSITION;
|
||||
float3 normal : NORMAL;
|
||||
};
|
||||
|
||||
PSInput main(VSInput input)
|
||||
{
|
||||
PSInput output;
|
||||
output.position = float4(input.position, 1.0);
|
||||
output.normal = input.normal;
|
||||
return output;
|
||||
}"u8;
|
||||
|
||||
private IDxcCompiler3* _compiler;
|
||||
private IDxcUtils* _utils;
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
IDxcCompiler3* pCompiler = default;
|
||||
IDxcUtils* pUtils = default;
|
||||
var hr = Api.DxcCreateInstance((Guid*)Unsafe.AsPointer(in Api.CLSID_DxcCompiler), __uuidof(pCompiler), (void**)&pCompiler);
|
||||
if (hr < 0)
|
||||
{
|
||||
throw new InvalidOperationException($"Failed to create DXC compiler instance. HRESULT: 0x{hr:X8}");
|
||||
}
|
||||
|
||||
hr = Api.DxcCreateInstance((Guid*)Unsafe.AsPointer(in Api.CLSID_DxcUtils), __uuidof(pUtils), (void**)&pUtils);
|
||||
if (hr < 0)
|
||||
{
|
||||
pCompiler->Release();
|
||||
throw new InvalidOperationException($"Failed to create DXC utils instance. HRESULT: 0x{hr:X8}");
|
||||
}
|
||||
|
||||
_compiler = pCompiler;
|
||||
_utils = pUtils;
|
||||
}
|
||||
|
||||
private static List<string> GetCompilerArguments()
|
||||
{
|
||||
return new List<string>
|
||||
{
|
||||
"-T", "vs_6_6", // Target profile (vs_6_6 for vertex shader)
|
||||
"-E", "main", // Entry point
|
||||
"-HV", "2021", // HLSL version 2021
|
||||
"-enable-16bit-types" // Enable 16-bit types
|
||||
};
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
IDxcIncludeHandler* includeHandler = default;
|
||||
IDxcBlobEncoding* sourceBlob = default;
|
||||
try
|
||||
{
|
||||
var hr = _utils->CreateDefaultIncludeHandler(&includeHandler);
|
||||
Assert.AreEqual(0, hr, $"Failed to create default include handler. HRESULT: 0x{hr:X8}");
|
||||
|
||||
fixed (byte* pCode = ShaderCode)
|
||||
{
|
||||
hr = _utils->CreateBlobFromPinned(pCode, (uint)ShaderCode.Length, Api.DXC_CP_UTF8, &sourceBlob);
|
||||
Assert.AreEqual(0, hr, $"Failed to create blob from shader code. HRESULT: 0x{hr:X8}");
|
||||
}
|
||||
|
||||
var argsArray = GetCompilerArguments();
|
||||
var argPtrs = stackalloc char*[argsArray.Count];
|
||||
for (var i = 0; i < argsArray.Count; i++)
|
||||
{
|
||||
argPtrs[i] = (char*)Marshal.StringToHGlobalUni(argsArray[i]);
|
||||
}
|
||||
|
||||
IDxcResult* result = default;
|
||||
IDxcBlob* bytecodeBlob = default;
|
||||
|
||||
try
|
||||
{
|
||||
// Compile shader
|
||||
var buffer = new DxcBuffer
|
||||
{
|
||||
Ptr = sourceBlob->GetBufferPointer(),
|
||||
Size = sourceBlob->GetBufferSize(),
|
||||
Encoding = Api.DXC_CP_UTF8
|
||||
};
|
||||
|
||||
hr = _compiler->Compile(&buffer, argPtrs, (uint)argsArray.Count, includeHandler, __uuidof(result), (void**)&result);
|
||||
Assert.AreEqual(0, hr, $"Failed to compile shader. HRESULT: 0x{hr:X8}");
|
||||
|
||||
// Check compilation result
|
||||
int hrStatus;
|
||||
result->GetStatus(&hrStatus);
|
||||
if (hrStatus < 0)
|
||||
{
|
||||
// Get error messages
|
||||
IDxcBlobEncoding* pErrorBlob = default;
|
||||
result->GetErrorBuffer(&pErrorBlob);
|
||||
|
||||
if (pErrorBlob != null)
|
||||
{
|
||||
var errorMessage = Marshal.PtrToStringUTF8((IntPtr)pErrorBlob->GetBufferPointer());
|
||||
pErrorBlob->Release();
|
||||
|
||||
throw new InvalidOperationException($"DXC shader compilation failed:\n{errorMessage}");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("DXC shader compilation failed with unknown error.");
|
||||
}
|
||||
}
|
||||
|
||||
// Get compiled bytecode
|
||||
hr = result->GetResult(&bytecodeBlob);
|
||||
Assert.AreEqual(0, hr, $"Failed to get compiled shader bytecode. HRESULT: 0x{hr:X8}");
|
||||
|
||||
var bytecodeSize = bytecodeBlob->GetBufferSize();
|
||||
Assert.IsTrue(bytecodeSize > 0, "Compiled shader bytecode is empty.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (result != null)
|
||||
{
|
||||
result->Release();
|
||||
}
|
||||
|
||||
if (bytecodeBlob != null)
|
||||
{
|
||||
bytecodeBlob->Release();
|
||||
}
|
||||
|
||||
for (var i = 0; i < argsArray.Count; i++)
|
||||
{
|
||||
Marshal.FreeHGlobal((nint)argPtrs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (includeHandler != null)
|
||||
{
|
||||
includeHandler->Release();
|
||||
}
|
||||
|
||||
if (sourceBlob != null)
|
||||
{
|
||||
sourceBlob->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Cleanup()
|
||||
{
|
||||
_compiler->Release();
|
||||
_utils->Release();
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<PublishAot>True</PublishAot>
|
||||
<Configurations>Debug;Release;Debug_Editor;Release_Editor</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -15,7 +16,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Runtime\Ghost.Core\Ghost.Core.csproj" />
|
||||
<ProjectReference Include="..\..\Test\Ghost.Test.Core\Ghost.Test.Core.csproj" />
|
||||
<ProjectReference Include="..\Ghost.TestCore\Ghost.TestCore.csproj" />
|
||||
<ProjectReference Include="..\..\ThridParty\Ghost.DXC\Ghost.DXC.csproj" />
|
||||
<ProjectReference Include="..\..\ThridParty\Ghost.Nvtt\Ghost.Nvtt.csproj" />
|
||||
<ProjectReference Include="..\..\ThridParty\Ghost.StbI\Ghost.StbI.csproj" />
|
||||
<ProjectReference Include="..\..\ThridParty\Ghost.Ufbx\Ghost.Ufbx.csproj" />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using Ghost.Nvtt;
|
||||
using Ghost.Test.Core;
|
||||
using Ghost.TestCore;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ghost.MicroTest;
|
||||
using Ghost.Test.Core;
|
||||
using Ghost.TestCore;
|
||||
|
||||
TestRunner.Run<UfbxBindingTest>();
|
||||
TestRunner.Run<DXCBindingTest>();
|
||||
@@ -1,5 +1,5 @@
|
||||
using Ghost.StbI;
|
||||
using Ghost.Test.Core;
|
||||
using Ghost.TestCore;
|
||||
|
||||
namespace Ghost.MicroTest;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Ghost.Test.Core;
|
||||
using Ghost.TestCore;
|
||||
using Ghost.Ufbx;
|
||||
|
||||
namespace Ghost.MicroTest;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<PublishAot>True</PublishAot>
|
||||
<Configurations>Debug;Release;Debug_Editor;Release_Editor</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
namespace Ghost.Test.Core;
|
||||
|
||||
public class TestRunner
|
||||
{
|
||||
public static void Run<T>()
|
||||
where T : ITest, new()
|
||||
{
|
||||
var test = new T();
|
||||
test.Setup();
|
||||
test.Run();
|
||||
test.Cleanup();
|
||||
}
|
||||
|
||||
public static void Run<T>(int iteration)
|
||||
where T : ITest, new()
|
||||
{
|
||||
var test = new T();
|
||||
test.Setup();
|
||||
|
||||
iteration = iteration < 1 ? 1 : iteration;
|
||||
for (var i = 0; i < iteration; i++)
|
||||
{
|
||||
test.Run();
|
||||
}
|
||||
|
||||
test.Cleanup();
|
||||
}
|
||||
}
|
||||
33
src/Test/Ghost.TestCore/Assert.cs
Normal file
33
src/Test/Ghost.TestCore/Assert.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
namespace Ghost.TestCore;
|
||||
|
||||
public static class Assert
|
||||
{
|
||||
public static void AreEqual<T>(T expected, T actual, string message = "")
|
||||
{
|
||||
if (!EqualityComparer<T>.Default.Equals(expected, actual))
|
||||
{
|
||||
throw new AssertFailedException($"Assert.AreEqual failed. Expected: {expected}, Actual: {actual}. {message}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void IsTrue(bool condition, string message = "")
|
||||
{
|
||||
if (!condition)
|
||||
{
|
||||
throw new AssertFailedException($"Assert.IsTrue failed. {message}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void IsFalse(bool condition, string message = "")
|
||||
{
|
||||
if (condition)
|
||||
{
|
||||
throw new AssertFailedException($"Assert.IsFalse failed. {message}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Fail(string message = "")
|
||||
{
|
||||
throw new AssertFailedException($"Assert.Fail: {message}");
|
||||
}
|
||||
}
|
||||
17
src/Test/Ghost.TestCore/AssertFailedException.cs
Normal file
17
src/Test/Ghost.TestCore/AssertFailedException.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
namespace Ghost.TestCore;
|
||||
|
||||
[Serializable]
|
||||
internal class AssertFailedException : Exception
|
||||
{
|
||||
public AssertFailedException()
|
||||
{
|
||||
}
|
||||
|
||||
public AssertFailedException(string? message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public AssertFailedException(string? message, Exception? innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Configurations>Debug;Release;Debug_Editor;Release_Editor</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace Ghost.Test.Core;
|
||||
namespace Ghost.TestCore;
|
||||
|
||||
public interface ITest
|
||||
{
|
||||
49
src/Test/Ghost.TestCore/TestRunner.cs
Normal file
49
src/Test/Ghost.TestCore/TestRunner.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
namespace Ghost.TestCore;
|
||||
|
||||
public class TestRunner
|
||||
{
|
||||
public static void Run<T>()
|
||||
where T : ITest, new()
|
||||
{
|
||||
var test = new T();
|
||||
|
||||
try
|
||||
{
|
||||
test.Setup();
|
||||
test.Run();
|
||||
test.Cleanup();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Test failed with exception: {ex.Message}");
|
||||
}
|
||||
|
||||
Console.WriteLine("Test completed.");
|
||||
}
|
||||
|
||||
public static void Run<T>(int iteration)
|
||||
where T : ITest, new()
|
||||
{
|
||||
var test = new T();
|
||||
var i = 0;
|
||||
|
||||
try
|
||||
{
|
||||
test.Setup();
|
||||
|
||||
iteration = iteration < 1 ? 1 : iteration;
|
||||
for (i = 0; i < iteration; i++)
|
||||
{
|
||||
test.Run();
|
||||
}
|
||||
|
||||
test.Cleanup();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Test failed at iteration {i} with exception: {ex.Message}");
|
||||
}
|
||||
|
||||
Console.WriteLine($"Test completed after {iteration} iterations.");
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ public class ImportCoordinatorTests
|
||||
[TestMethod]
|
||||
public async Task TestImportCoordinator_BasicImport()
|
||||
{
|
||||
using var catalog = new AssetCatalog(_dbPath);
|
||||
var catalog = new AssetCatalog(_dbPath);
|
||||
using var coordinator = new ImportCoordinator(catalog);
|
||||
|
||||
var assetGuid = Guid.NewGuid();
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<Platforms>x64;x86;ARM64</Platforms>
|
||||
<RuntimeIdentifiers>win-x86;win-x64;win-arm64</RuntimeIdentifiers>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<Configurations>Debug;Release;Debug_Editor;Release_Editor</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user