234 lines
11 KiB
C#
234 lines
11 KiB
C#
using Aquarium.Engine.Render;
|
|
|
|
namespace Aquarium.Engine.Tests;
|
|
|
|
public sealed class FieldScriptCompilerTests
|
|
{
|
|
[Fact]
|
|
public void CompileTreatsSplineFieldAsIntentWithAutoLoweringByDefault()
|
|
{
|
|
var frame = AquariumFieldScriptCompiler.Compile(
|
|
"""
|
|
texture id=spectrum
|
|
surface id=amplitude op=texture.sample value=0,0,0,0
|
|
splinefield id=field texture=spectrum frequencyAxis=x columns=4
|
|
""",
|
|
new Dictionary<string, AquariumTextureFieldBinding>(StringComparer.Ordinal)
|
|
{
|
|
["spectrum"] = new("spectrum", 8, 4, 1, 0, AquariumRollingModuloMode.Rows, Enumerable.Repeat(0.5f, 32).ToArray()),
|
|
});
|
|
|
|
Assert.Equal(AquariumFieldLoweringMode.Auto, frame.LoweringPolicy.Mode);
|
|
Assert.True(frame.Reservoir.HasInput);
|
|
Assert.False(frame.UseReservoirLowering);
|
|
Assert.Single(frame.TextureSplineFields);
|
|
}
|
|
|
|
[Fact]
|
|
public void CompileParsesLoweringPolicyWithoutBackendCommands()
|
|
{
|
|
var frame = AquariumFieldScriptCompiler.Compile(
|
|
"""
|
|
texture id=spectrum
|
|
splinefield id=field texture=spectrum frequencyAxis=x columns=8
|
|
lowering mode=reservoirSplats maxSplines=2 maxControlPoints=16 maxSplats=4096 lodBias=0.5
|
|
""",
|
|
new Dictionary<string, AquariumTextureFieldBinding>(StringComparer.Ordinal)
|
|
{
|
|
["spectrum"] = new("spectrum", 8, 8, 1, 0, AquariumRollingModuloMode.Rows, Enumerable.Repeat(0.5f, 64).ToArray()),
|
|
});
|
|
|
|
Assert.Equal(AquariumFieldLoweringMode.ReservoirSplats, frame.LoweringPolicy.Mode);
|
|
Assert.Equal(2, frame.LoweringPolicy.MaxDirectSplines);
|
|
Assert.Equal(16, frame.LoweringPolicy.MaxDirectControlPoints);
|
|
Assert.Equal(4096, frame.LoweringPolicy.MaxReservoirSplats);
|
|
Assert.Equal(0.5f, frame.LoweringPolicy.LodBias);
|
|
Assert.True(frame.UseReservoirLowering);
|
|
}
|
|
|
|
[Fact]
|
|
public void CompileEvidenceParsesTubeSplineLoweringForRollingFloatBuffers()
|
|
{
|
|
var resource = new AquariumFieldResourceDeclaration(
|
|
"mimir:resource:log-mel",
|
|
AquariumFieldResourceKind.StructuredBuffer,
|
|
AquariumFieldResourceResidency.SharedGpu,
|
|
AquariumFieldShaderAccess.ShaderResource,
|
|
"Float32",
|
|
Width: 64,
|
|
Height: 32,
|
|
DepthOrCount: 2048,
|
|
StrideBytes: 4,
|
|
ValidFromNs: 0,
|
|
ValidUntilNs: 10_000,
|
|
Version: 7,
|
|
NativeHandle: IntPtr.Zero,
|
|
NativeHandleKind: "fensalir-buffer");
|
|
|
|
var frame = AquariumFieldScriptCompiler.CompileEvidence(
|
|
"""
|
|
resource id=mel key=mimir:resource:log-mel
|
|
tubespline id=mel-field resource=mel domain=mimir:log-mel width=64 height=32 stride=4 firstColumn=3 columns=8 columnStride=1 rollingModulo=32 rollingOffset=12 amplitudePower=2 normalizeMin=0 normalizeMax=1 radius=0.01 radiusScale=0.03 ramp=D:\WIP4\Projects\Aetheria\Assets\Resources\Ramps\blackbody.png emissionScale=10 subdivisions=4
|
|
""",
|
|
new Dictionary<string, AquariumFieldResourceDeclaration>(StringComparer.Ordinal)
|
|
{
|
|
[resource.ResourceKey] = resource,
|
|
});
|
|
|
|
var lowering = Assert.Single(frame.TubeSplineLowerings);
|
|
Assert.Equal("dsl:tube:mel-field", lowering.ClaimKey);
|
|
Assert.Equal(resource.ResourceKey, lowering.ResourceKey);
|
|
Assert.Equal(64, lowering.Width);
|
|
Assert.Equal(32, lowering.Height);
|
|
Assert.Equal(12, lowering.RollingOffset);
|
|
Assert.Equal(2.0f, lowering.AmplitudePower);
|
|
Assert.Equal(10.0f, lowering.EmissionScale);
|
|
Assert.Equal(@"D:\WIP4\Projects\Aetheria\Assets\Resources\Ramps\blackbody.png", lowering.RampTexturePath);
|
|
Assert.Equal("", lowering.RampResourceKey);
|
|
}
|
|
|
|
[Fact]
|
|
public void CompileEvidenceBindsLocalTexture2DResourcesAsTubeRamps()
|
|
{
|
|
var resource = new AquariumFieldResourceDeclaration(
|
|
"mimir:resource:log-mel",
|
|
AquariumFieldResourceKind.StructuredBuffer,
|
|
AquariumFieldResourceResidency.SharedGpu,
|
|
AquariumFieldShaderAccess.ShaderResource,
|
|
"Float32",
|
|
Width: 64,
|
|
Height: 32,
|
|
DepthOrCount: 2048,
|
|
StrideBytes: 4,
|
|
ValidFromNs: 0,
|
|
ValidUntilNs: 10_000,
|
|
Version: 7,
|
|
NativeHandle: IntPtr.Zero,
|
|
NativeHandleKind: "fensalir-buffer");
|
|
|
|
var frame = AquariumFieldScriptCompiler.CompileEvidence(
|
|
"""
|
|
resource id=mel key=mimir:resource:log-mel
|
|
texture2d id=blackbody key=aquarium:resource:ramp:blackbody path=D:\WIP4\Projects\Aetheria\Assets\Resources\Ramps\blackbody.png format=Rgba8Unorm version=11
|
|
tubespline id=mel-field resource=mel domain=mimir:log-mel width=64 height=32 stride=4 columns=8 ramp=blackbody
|
|
""",
|
|
new Dictionary<string, AquariumFieldResourceDeclaration>(StringComparer.Ordinal)
|
|
{
|
|
[resource.ResourceKey] = resource,
|
|
});
|
|
|
|
Assert.Equal(2, frame.Resources.Count);
|
|
var ramp = frame.Resources.Single(resource => resource.Kind == AquariumFieldResourceKind.Texture2D);
|
|
Assert.Equal("aquarium:resource:ramp:blackbody", ramp.ResourceKey);
|
|
Assert.Equal("local-asset", ramp.NativeHandleKind);
|
|
Assert.Equal(@"D:\WIP4\Projects\Aetheria\Assets\Resources\Ramps\blackbody.png", ramp.SourceUri);
|
|
|
|
var lowering = Assert.Single(frame.TubeSplineLowerings);
|
|
Assert.Equal(ramp.ResourceKey, lowering.RampResourceKey);
|
|
Assert.Equal(ramp.SourceUri, lowering.RampTexturePath);
|
|
}
|
|
|
|
[Fact]
|
|
public void CompileEvidenceDeclaresSurfacePagesAsGpuResources()
|
|
{
|
|
var frame = AquariumFieldScriptCompiler.CompileEvidence(
|
|
"""
|
|
surfacepage id=height key=aquarium:resource:surface-page:heightfield width=128 height=128 format=R16Float version=3
|
|
""",
|
|
new Dictionary<string, AquariumFieldResourceDeclaration>(StringComparer.Ordinal));
|
|
|
|
var resource = Assert.Single(frame.Resources);
|
|
Assert.Equal("aquarium:resource:surface-page:heightfield", resource.ResourceKey);
|
|
Assert.Equal(AquariumFieldResourceKind.SurfacePage, resource.Kind);
|
|
Assert.Equal(AquariumFieldResourceResidency.GpuResident, resource.Residency);
|
|
Assert.Equal(AquariumFieldShaderAccess.ShaderResource, resource.Access);
|
|
Assert.Equal(128, resource.Width);
|
|
Assert.Equal(128, resource.Height);
|
|
Assert.Equal("R16Float", resource.Format);
|
|
Assert.Equal("fensalir-surface-page", resource.NativeHandleKind);
|
|
}
|
|
|
|
[Fact]
|
|
public void CompileEvidenceDeclaresVolumeTexturesAsGpuResources()
|
|
{
|
|
var frame = AquariumFieldScriptCompiler.CompileEvidence(
|
|
"""
|
|
volumetexture id=density key=aquarium:resource:volume:density width=32 height=32 depth=16 format=R16Float version=5
|
|
""",
|
|
new Dictionary<string, AquariumFieldResourceDeclaration>(StringComparer.Ordinal));
|
|
|
|
var resource = Assert.Single(frame.Resources);
|
|
Assert.Equal("aquarium:resource:volume:density", resource.ResourceKey);
|
|
Assert.Equal(AquariumFieldResourceKind.VolumeTexture, resource.Kind);
|
|
Assert.Equal(AquariumFieldResourceResidency.GpuResident, resource.Residency);
|
|
Assert.Equal(AquariumFieldShaderAccess.ShaderResource, resource.Access);
|
|
Assert.Equal(32, resource.Width);
|
|
Assert.Equal(32, resource.Height);
|
|
Assert.Equal(16, resource.DepthOrCount);
|
|
Assert.Equal("R16Float", resource.Format);
|
|
Assert.Equal("fensalir-volume-texture", resource.NativeHandleKind);
|
|
}
|
|
|
|
[Fact]
|
|
public void CompileEvidenceDeclaresMeshPackagesAsGpuResources()
|
|
{
|
|
var frame = AquariumFieldScriptCompiler.CompileEvidence(
|
|
"""
|
|
mesh id=quad key=aquarium:resource:mesh:quad vertices=4 vertexStride=32 indices=6 indexFormat=UInt32 topology=TriangleList min=-1,-1,0 max=1,1,0 submeshes=1 version=9
|
|
""",
|
|
new Dictionary<string, AquariumFieldResourceDeclaration>(StringComparer.Ordinal));
|
|
|
|
var resource = Assert.Single(frame.Resources);
|
|
Assert.Equal("aquarium:resource:mesh:quad", resource.ResourceKey);
|
|
Assert.Equal(AquariumFieldResourceKind.Mesh, resource.Kind);
|
|
Assert.Equal(AquariumFieldResourceResidency.GpuResident, resource.Residency);
|
|
Assert.Equal(AquariumFieldShaderAccess.ShaderResource, resource.Access);
|
|
Assert.Equal("fensalir-mesh-package", resource.NativeHandleKind);
|
|
Assert.True(resource.Mesh.IsValid);
|
|
Assert.Equal(4, resource.Mesh.Vertices.Count);
|
|
Assert.Equal(32, resource.Mesh.Vertices.StrideBytes);
|
|
Assert.Equal(6, resource.Mesh.Indices.Count);
|
|
Assert.Equal(4, resource.Mesh.Indices.StrideBytes);
|
|
Assert.Equal(AquariumFieldMeshTopology.TriangleList, resource.Mesh.Topology);
|
|
Assert.Equal(AquariumFieldMeshIndexFormat.UInt32, resource.Mesh.IndexFormat);
|
|
}
|
|
|
|
[Fact]
|
|
public void CompileEvidencePlansGenericResourceClaims()
|
|
{
|
|
var frame = AquariumFieldScriptCompiler.CompileEvidence(
|
|
"""
|
|
mesh id=quad key=aquarium:resource:mesh:quad vertices=4 vertexStride=32 indices=6 indexFormat=UInt32 topology=TriangleList min=-1,-1,0 max=1,1,0 submeshes=1 version=9
|
|
surfacepage id=height key=aquarium:resource:surface-page:height width=64 height=64 format=R16Float
|
|
volumetexture id=fog key=aquarium:resource:volume-texture:fog width=16 height=16 depth=16 format=R16Float
|
|
claim id=quad resource=quad encoding=Mesh layer=Form radius=1
|
|
claim id=height resource=height encoding=Height layer=Form radius=1
|
|
claim id=fog resource=fog encoding=Density layer=Appearance radius=1
|
|
""",
|
|
new Dictionary<string, AquariumFieldResourceDeclaration>(StringComparer.Ordinal));
|
|
|
|
var plan = AquariumFieldLoweringPlanner.Plan(frame);
|
|
|
|
Assert.Empty(plan.DeferredRequests);
|
|
Assert.Collection(
|
|
plan.Packets,
|
|
packet =>
|
|
{
|
|
Assert.Equal(AquariumFieldEncoding.Mesh, packet.Encoding);
|
|
Assert.Equal(AquariumFieldBackendKind.Mesh, packet.Backend);
|
|
Assert.Equal("aquarium:resource:mesh:quad", packet.PayloadHandle);
|
|
},
|
|
packet =>
|
|
{
|
|
Assert.Equal(AquariumFieldEncoding.Height, packet.Encoding);
|
|
Assert.Equal(AquariumFieldBackendKind.SurfacePage, packet.Backend);
|
|
Assert.Equal("aquarium:resource:surface-page:height", packet.PayloadHandle);
|
|
},
|
|
packet =>
|
|
{
|
|
Assert.Equal(AquariumFieldEncoding.Density, packet.Encoding);
|
|
Assert.Equal(AquariumFieldBackendKind.VolumeSplat, packet.Backend);
|
|
Assert.Equal("aquarium:resource:volume-texture:fog", packet.PayloadHandle);
|
|
});
|
|
}
|
|
}
|