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:
2026-05-08 13:59:36 +09:00
parent b42398bbce
commit 80e820a858
42 changed files with 392 additions and 101 deletions

View 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();
}
}

View File

@@ -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" />

View File

@@ -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;

View File

@@ -1,4 +1,4 @@
using Ghost.MicroTest;
using Ghost.Test.Core;
using Ghost.TestCore;
TestRunner.Run<UfbxBindingTest>();
TestRunner.Run<DXCBindingTest>();

View File

@@ -1,5 +1,5 @@
using Ghost.StbI;
using Ghost.Test.Core;
using Ghost.TestCore;
namespace Ghost.MicroTest;

View File

@@ -1,4 +1,4 @@
using Ghost.Test.Core;
using Ghost.TestCore;
using Ghost.Ufbx;
namespace Ghost.MicroTest;