aboutsummaryrefslogtreecommitdiff
path: root/crates/fparkan-runtime/tests
diff options
context:
space:
mode:
Diffstat (limited to 'crates/fparkan-runtime/tests')
-rw-r--r--crates/fparkan-runtime/tests/behavior_distributor_tick_native_oracle.cs85
1 files changed, 83 insertions, 2 deletions
diff --git a/crates/fparkan-runtime/tests/behavior_distributor_tick_native_oracle.cs b/crates/fparkan-runtime/tests/behavior_distributor_tick_native_oracle.cs
index 500cc0d..457a6d6 100644
--- a/crates/fparkan-runtime/tests/behavior_distributor_tick_native_oracle.cs
+++ b/crates/fparkan-runtime/tests/behavior_distributor_tick_native_oracle.cs
@@ -1791,6 +1791,7 @@ internal static class BehaviorDistributorTickOracle {
}
private static void RunNativeControlResourceBudgetTag15Case(IntPtr module) {
+ RunNativeControlResourceBudgetEmptyCases(module);
NativeControlOwnerConstructor constructOwner = (NativeControlOwnerConstructor)Marshal.GetDelegateForFunctionPointer(
IntPtr.Add(module, ControlOwnerConstructorRva), typeof(NativeControlOwnerConstructor));
NativeControlProviderRowConstructor constructProviderRow = (NativeControlProviderRowConstructor)
@@ -1889,6 +1890,7 @@ internal static class BehaviorDistributorTickOracle {
Marshal.WriteInt32(generator, 0x1c, 0);
Marshal.WriteInt32(providerRow, 8, FloatBits(40.0f));
Marshal.WriteInt32(providerRow, 0x0c, FloatBits(40.0f));
+ Marshal.WriteInt32(providerRow, 0x10, 0);
Marshal.WriteInt32(providerRow, 0x14, FloatBits(0.4f));
Marshal.WriteInt32(owner, 0x590, FloatBits(40.0f));
const float dt = 0.5f;
@@ -1941,6 +1943,7 @@ internal static class BehaviorDistributorTickOracle {
Marshal.WriteInt32(nativeGenerator, 0x4c, FloatBits(1.0f));
Marshal.WriteInt32(providerRow, 8, FloatBits(40.0f));
Marshal.WriteInt32(providerRow, 0x0c, FloatBits(40.0f));
+ Marshal.WriteInt32(providerRow, 0x10, 0);
Marshal.WriteInt32(providerRow, 0x14, FloatBits(0.4f));
Marshal.WriteInt32(owner, 0x590, FloatBits(40.0f));
NativeControlResourceDeviceRate generatorRate = (NativeControlResourceDeviceRate)
@@ -1951,17 +1954,74 @@ internal static class BehaviorDistributorTickOracle {
update(owner, 0.5f);
uint amount = unchecked((uint)Marshal.ReadInt32(providerRow, 8));
uint fraction = unchecked((uint)Marshal.ReadInt32(providerRow, 0x14));
+ uint accumulated = unchecked((uint)Marshal.ReadInt32(providerRow, 0x10));
uint remaining = unchecked((uint)Marshal.ReadInt32(nativeGenerator, 0x4c));
Console.WriteLine("native-control-real-generator-budget: ctor=0x22980 rate=0x229a0 update=0x22a60" +
" cap=" + capped + " produced=" + Float(produced) + " amount=" + Hex(amount) +
- " ratio=" + Hex(fraction) + " remaining=" + Hex(remaining));
+ " accumulated=" + Hex(accumulated) + " ratio=" + Hex(fraction) + " remaining=" + Hex(remaining));
Expect(amount == (capped == 0 ? 0x42206666u : 0x42203333u) &&
fraction == (capped == 0 ? 0x3ecd4fdfu : 0x3ecd0e56u) &&
+ accumulated == (capped == 0 ? 0x3dcccc00u : 0x3d4ccc00u) &&
remaining == unchecked((uint)FloatBits(capped == 0 ? 0.75f : 0.0f)),
- "real generator and consumer update exact provider and reserve values in one budget pass");
+ "real generator and consumer update exact provider amount, delta, ratio, and reserve in one budget pass");
GC.KeepAlive(generatorRate);
}
+
+ Marshal.WriteInt32(typedRecord, 0x20, FloatBits(0.125f));
+ Marshal.WriteInt32(typedRecord, 0x2c, FloatBits(0.75f));
+ Marshal.WriteInt32(typedRecord, 0x30, FloatBits(1.25f));
+ Marshal.WriteInt32(nativeGeneratorRecord, 0x20, FloatBits(1.0f));
+ Marshal.WriteInt32(nativeGeneratorRecord, 0x2c, FloatBits(0.25f));
+ Expect(applyInto(owner, 1, typedRecord) == IntPtr.Add(typedRecord, 0xb4) &&
+ applyInto(owner, 0, nativeGeneratorRecord) == IntPtr.Add(nativeGeneratorRecord, 0xb4),
+ "native non-degenerate tag-19/tag-15 descriptor initializers");
+ Marshal.WriteInt32(device, 0x4c, FloatBits(0.8f));
+ Marshal.WriteInt32(nativeGenerator, 0x4c, FloatBits(1.0f));
+ Marshal.WriteInt32(providerRow, 8, FloatBits(40.0f));
+ Marshal.WriteInt32(providerRow, 0x0c, FloatBits(40.0f));
+ Marshal.WriteInt32(providerRow, 0x10, 0);
+ Marshal.WriteInt32(providerRow, 0x14, FloatBits(0.4f));
+ Marshal.WriteInt32(owner, 0x590, FloatBits(40.0f));
+ NativeControlResourceDeviceRate nativeGeneratorRate = (NativeControlResourceDeviceRate)
+ Marshal.GetDelegateForFunctionPointer(IntPtr.Add(module, 0x229a0), typeof(NativeControlResourceDeviceRate));
+ float nonDegenerateProduced = nativeGeneratorRate(nativeGenerator, 0.375f);
+ float nonDegenerateDemand = rate(device, 0.375f);
+ update(owner, 0.375f);
+ uint nonDegenerateAmount = unchecked((uint)Marshal.ReadInt32(providerRow, 8));
+ uint nonDegenerateProcessed = unchecked((uint)Marshal.ReadInt32(providerRow, 0x0c));
+ uint nonDegenerateAccumulated = unchecked((uint)Marshal.ReadInt32(providerRow, 0x10));
+ uint nonDegenerateRatio = unchecked((uint)Marshal.ReadInt32(providerRow, 0x14));
+ uint nonDegenerateConsumerMultiplier = unchecked((uint)Marshal.ReadInt32(device, 0x4c));
+ uint nonDegenerateGeneratorMultiplier = unchecked((uint)Marshal.ReadInt32(nativeGenerator, 0x4c));
+ uint nonDegenerateRate5dc = unchecked((uint)Marshal.ReadInt32(owner, 0x5dc));
+ uint nonDegenerateRate5e0 = unchecked((uint)Marshal.ReadInt32(owner, 0x5e0));
+ Expect(FloatBits(nonDegenerateProduced) == 0x3dcccccd && FloatBits(nonDegenerateDemand) == unchecked((int)0xbe400000) &&
+ nonDegenerateAmount == 0x42202b85 && nonDegenerateProcessed == 0x42202b85 &&
+ nonDegenerateAccumulated == 0x3d2e1400 && nonDegenerateRatio == 0x3ecd0481 &&
+ nonDegenerateConsumerMultiplier == 0x3f088889 && nonDegenerateGeneratorMultiplier == 0 &&
+ nonDegenerateRate5dc == 0x3e88888a && nonDegenerateRate5e0 == 0x3e88888a,
+ "native non-degenerate tag-19/tag-15 budget vector matches amount, delta, rates, and multipliers");
+ Console.WriteLine("native-control-real-complex-budget: dt=0.375 produced=" + Hex(unchecked((uint)FloatBits(nonDegenerateProduced))) +
+ " demand=" + Hex(unchecked((uint)FloatBits(nonDegenerateDemand))) +
+ " amount=" + Hex(nonDegenerateAmount) + " processed=" + Hex(nonDegenerateProcessed) +
+ " accumulated=" + Hex(nonDegenerateAccumulated) + " ratio=" + Hex(nonDegenerateRatio) +
+ " multipliers=" + Hex(nonDegenerateConsumerMultiplier) + "," + Hex(nonDegenerateGeneratorMultiplier) +
+ " rates=" + Hex(nonDegenerateRate5dc) + "," + Hex(nonDegenerateRate5e0));
+ GC.KeepAlive(nativeGeneratorRate);
+
+ // Restore the fixture that the subsequent native clock test uses.
+ Marshal.WriteInt32(typedRecord, 0x20, FloatBits(0.0f));
+ Marshal.WriteInt32(typedRecord, 0x2c, FloatBits(1.0f));
+ Marshal.WriteInt32(typedRecord, 0x30, FloatBits(1.0f));
+ Expect(applyInto(owner, 1, typedRecord) == IntPtr.Add(typedRecord, 0xb4),
+ "restore native tag-15 clock-test descriptor");
+ Marshal.WriteInt32(device, 0x4c, FloatBits(1.0f));
Marshal.WriteIntPtr(devices, 0, generator);
+ Marshal.WriteInt32(providerRow, 8, FloatBits(40.0f));
+ Marshal.WriteInt32(providerRow, 0x0c, FloatBits(40.0f));
+ Marshal.WriteInt32(providerRow, 0x10, 0);
+ Marshal.WriteInt32(providerRow, 0x14, FloatBits(0.4f));
+ Marshal.WriteInt32(owner, 0x590, FloatBits(40.0f));
GC.KeepAlive(constructGenerator);
// Bounded active class-10 host: no motion object, no deferred packets.
@@ -2081,6 +2141,27 @@ internal static class BehaviorDistributorTickOracle {
}
}
+ private static void RunNativeControlResourceBudgetEmptyCases(IntPtr module) {
+ NativeControlOwnerConstructor constructOwner = (NativeControlOwnerConstructor)
+ Marshal.GetDelegateForFunctionPointer(IntPtr.Add(module, ControlOwnerConstructorRva),
+ typeof(NativeControlOwnerConstructor));
+ NativeControlResourceBudgetUpdate update = (NativeControlResourceBudgetUpdate)
+ Marshal.GetDelegateForFunctionPointer(IntPtr.Add(module, ControlResourceBudgetUpdateRva),
+ typeof(NativeControlResourceBudgetUpdate));
+ using (Fixture fixture = NewFixture()) {
+ IntPtr owner = fixture.Allocate(0x664);
+ Expect(constructOwner(owner, IntPtr.Zero, 4) == owner, "native empty-budget owner constructor");
+ foreach (float dt in new[] { 0.0f, 0.5f }) {
+ update(owner, dt);
+ Expect(Marshal.ReadInt32(owner, 0x5dc) == unchecked((int)0x80000000) &&
+ Marshal.ReadInt32(owner, 0x5e0) == unchecked((int)0x80000000),
+ "native empty budget writes negative-zero output rates at dt=" + Float(dt));
+ }
+ Console.WriteLine("native-control-empty-budget: dt=0/0.5 rates=0x80000000,0x80000000");
+ }
+ GC.KeepAlive(update);
+ }
+
private static void RunNativeControlActivationCase(IntPtr module) {
NativeControlOwnerConstructor construct = (NativeControlOwnerConstructor)Marshal.GetDelegateForFunctionPointer(
IntPtr.Add(module, 0x31490), typeof(NativeControlOwnerConstructor));