testss
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"createSeparatePackage": false
|
||||
}
|
@@ -0,0 +1,160 @@
|
||||
using NUnit.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace UnityEngine.Rendering.Tests
|
||||
{
|
||||
class BitArrayTests
|
||||
{
|
||||
BitArray8[] ba8;
|
||||
BitArray16[] ba16;
|
||||
BitArray32[] ba32;
|
||||
BitArray64[] ba64;
|
||||
BitArray128[] ba128;
|
||||
BitArray256[] ba256;
|
||||
|
||||
static readonly uint[] aIndexes = new uint[] { 300, 200, 198, 100, 98, 60, 58, 30, 28, 10, 8, 4, 2, 0, 0 }; //double 0 entry to test double entry
|
||||
static readonly uint[] bIndexes = new uint[] { 300, 200, 199, 100, 99, 60, 59, 30, 29, 10, 9, 8, 5, 1, 0 };
|
||||
static readonly uint[] getSetTestedIndexes = new uint[] { 201, 200, 101, 100, 61, 60, 31, 30, 11, 10, 1, 0 }; // on a, odd value are false, even true
|
||||
const string aHumanized = "00000000.00000000.00000000.00000000.00000000.00000000.00000001.01000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00010100.00000000.00000000.00000000.00000000.00010100.00000000.00000000.00000000.01010000.00000000.00000101.00010101";
|
||||
const string bHumanized = "00000000.00000000.00000000.00000000.00000000.00000000.00000001.10000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00011000.00000000.00000000.00000000.00000000.00011000.00000000.00000000.00000000.01100000.00000000.00000111.00100011";
|
||||
const string aAndBHumanized = "00000000.00000000.00000000.00000000.00000000.00000000.00000001.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00010000.00000000.00000000.00000000.00000000.00010000.00000000.00000000.00000000.01000000.00000000.00000101.00000001";
|
||||
const string aOrBHumanized = "00000000.00000000.00000000.00000000.00000000.00000000.00000001.11000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00011100.00000000.00000000.00000000.00000000.00011100.00000000.00000000.00000000.01110000.00000000.00000111.00110111";
|
||||
const string notAHumanized = "11111111.11111111.11111111.11111111.11111111.11111111.11111110.10111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11101011.11111111.11111111.11111111.11111111.11101011.11111111.11111111.11111111.10101111.11111111.11111010.11101010";
|
||||
const string zeroHumanized = "00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000.00000000";
|
||||
const string maxHumanized = "11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111.11111111";
|
||||
|
||||
[SetUp]
|
||||
public void SetUpBitArray()
|
||||
{
|
||||
ba8 = new[] { new BitArray8(), new BitArray8(aIndexes), new BitArray8(bIndexes), new BitArray8(byte.MaxValue) };
|
||||
ba16 = new[] { new BitArray16(), new BitArray16(aIndexes), new BitArray16(bIndexes), new BitArray16(ushort.MaxValue) };
|
||||
ba32 = new[] { new BitArray32(), new BitArray32(aIndexes), new BitArray32(bIndexes), new BitArray32(uint.MaxValue) };
|
||||
ba64 = new[] { new BitArray64(), new BitArray64(aIndexes), new BitArray64(bIndexes), new BitArray64(ulong.MaxValue) };
|
||||
ba128 = new[] { new BitArray128(), new BitArray128(aIndexes), new BitArray128(bIndexes), new BitArray128(ulong.MaxValue, ulong.MaxValue) };
|
||||
ba256 = new[] { new BitArray256(), new BitArray256(aIndexes), new BitArray256(bIndexes), new BitArray256(ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue) };
|
||||
}
|
||||
|
||||
//[TearDown]
|
||||
//nothing to do as they are non static struct
|
||||
|
||||
string GetLastHumanizedBits(string a, uint bitNumber) => a.Substring(a.Length - ((int)bitNumber + ((int)bitNumber - 1) / 8)); //handle '.' separators
|
||||
|
||||
void TestBitArrayMethods<T>(T[] ba, uint capacity)
|
||||
where T : IBitArray
|
||||
{
|
||||
Assert.AreEqual(capacity, ba[0].capacity);
|
||||
Assert.AreEqual(true, ba[0].allFalse);
|
||||
Assert.AreEqual(false, ba[0].allTrue);
|
||||
var trimmedZeroHumanized = GetLastHumanizedBits(zeroHumanized, capacity);
|
||||
var humanized = ba[0].humanizedData;
|
||||
Assert.AreEqual(trimmedZeroHumanized, humanized);
|
||||
|
||||
Assert.AreEqual(capacity, ba[1].capacity);
|
||||
Assert.AreEqual(false, ba[1].allFalse);
|
||||
Assert.AreEqual(false, ba[1].allTrue);
|
||||
var trimmedAHumanized = GetLastHumanizedBits(aHumanized, capacity);
|
||||
humanized = ba[1].humanizedData;
|
||||
Assert.AreEqual(trimmedAHumanized, humanized);
|
||||
|
||||
Assert.AreEqual(capacity, ba[2].capacity);
|
||||
Assert.AreEqual(false, ba[2].allFalse);
|
||||
Assert.AreEqual(false, ba[2].allTrue);
|
||||
var trimmedBHumanized = GetLastHumanizedBits(bHumanized, capacity);
|
||||
humanized = ba[2].humanizedData;
|
||||
Assert.AreEqual(trimmedBHumanized, humanized);
|
||||
|
||||
Assert.AreEqual(capacity, ba[3].capacity);
|
||||
Assert.AreEqual(false, ba[3].allFalse);
|
||||
Assert.AreEqual(true, ba[3].allTrue);
|
||||
var trimmedMaxHumnized = GetLastHumanizedBits(maxHumanized, capacity);
|
||||
humanized = ba[3].humanizedData;
|
||||
Assert.AreEqual(trimmedMaxHumnized, humanized);
|
||||
}
|
||||
|
||||
void TestBitArrayOperator<T>(T[] ba)
|
||||
where T : IBitArray
|
||||
{
|
||||
//ensure we keep value type when refactoring
|
||||
var ba_4 = ba[1];
|
||||
Assert.AreEqual(ba_4, ba[1]);
|
||||
Assert.AreNotSame(ba_4, ba[1]);
|
||||
ba_4 = ba[2];
|
||||
Assert.AreNotEqual(ba_4, ba[1]);
|
||||
|
||||
//test and
|
||||
var bAndA = ba[2].BitAnd(ba[1]);
|
||||
var aAndB = ba[1].BitAnd(ba[2]);
|
||||
Assert.AreEqual(bAndA, aAndB);
|
||||
Assert.AreEqual(bAndA.humanizedData, GetLastHumanizedBits(aAndBHumanized, ba[0].capacity));
|
||||
|
||||
//test or
|
||||
var bOrA = ba[2].BitOr(ba[1]);
|
||||
var aOrB = ba[1].BitOr(ba[2]);
|
||||
Assert.AreEqual(bOrA, aOrB);
|
||||
Assert.AreEqual(bOrA.humanizedData, GetLastHumanizedBits(aOrBHumanized, ba[0].capacity));
|
||||
|
||||
//test not
|
||||
var notA = ba[1].BitNot();
|
||||
Assert.AreEqual(notA.humanizedData, GetLastHumanizedBits(notAHumanized, ba[0].capacity));
|
||||
|
||||
//test indexer
|
||||
foreach (uint index in getSetTestedIndexes.Where(i => i < ba[0].capacity))
|
||||
{
|
||||
//test get
|
||||
Assert.AreEqual(ba[1][index], (index & 1) == 0); //on a, odd value are false and even true
|
||||
|
||||
//test set
|
||||
var bai = ba[1];
|
||||
bai[index] = ba[1][index];
|
||||
Assert.AreEqual(ba[1], bai);
|
||||
bai[index] = !ba[1][index];
|
||||
Assert.AreNotEqual(ba[1], bai);
|
||||
Assert.AreEqual(bai[index], !ba[1][index]);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBitArray8()
|
||||
{
|
||||
TestBitArrayMethods(ba8, 8u);
|
||||
TestBitArrayOperator(ba8);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBitArray16()
|
||||
{
|
||||
TestBitArrayMethods(ba16, 16u);
|
||||
TestBitArrayOperator(ba16);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBitArray32()
|
||||
{
|
||||
TestBitArrayMethods(ba32, 32u);
|
||||
TestBitArrayOperator(ba32);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBitArray64()
|
||||
{
|
||||
TestBitArrayMethods(ba64, 64u);
|
||||
TestBitArrayOperator(ba64);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBitArray128()
|
||||
{
|
||||
TestBitArrayMethods(ba128, 128u);
|
||||
TestBitArrayOperator(ba128);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBitArray256()
|
||||
{
|
||||
TestBitArrayMethods(ba256, 256u);
|
||||
TestBitArrayOperator(ba256);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,139 @@
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace UnityEditor.Rendering.Tests
|
||||
{
|
||||
unsafe class CoreUnsafeUtilsTests
|
||||
{
|
||||
public struct TestData : IEquatable<TestData>
|
||||
{
|
||||
public int intValue;
|
||||
public float floatValue;
|
||||
|
||||
public bool Equals(TestData other)
|
||||
{
|
||||
return intValue == other.intValue && floatValue == other.floatValue;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is TestData))
|
||||
return false;
|
||||
return Equals((TestData)obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
fixed(float* fptr = &floatValue)
|
||||
return intValue ^ *(int*)fptr;
|
||||
}
|
||||
}
|
||||
|
||||
static object[][] s_CopyToList = new object[][]
|
||||
{
|
||||
new object[] { new List<TestData>
|
||||
{
|
||||
new TestData { floatValue = 2, intValue = 1 },
|
||||
new TestData { floatValue = 3, intValue = 2 },
|
||||
new TestData { floatValue = 4, intValue = 3 },
|
||||
new TestData { floatValue = 5, intValue = 4 },
|
||||
new TestData { floatValue = 6, intValue = 5 },
|
||||
} }
|
||||
};
|
||||
|
||||
[Test]
|
||||
[TestCaseSource("s_CopyToList")]
|
||||
public void CopyToList(List<TestData> datas)
|
||||
{
|
||||
var dest = stackalloc TestData[datas.Count];
|
||||
datas.CopyTo(dest, datas.Count);
|
||||
|
||||
for (int i = 0; i < datas.Count; ++i)
|
||||
Assert.AreEqual(datas[i], dest[i]);
|
||||
}
|
||||
|
||||
static object[][] s_CopyToArray = new object[][]
|
||||
{
|
||||
new object[] { new TestData[]
|
||||
{
|
||||
new TestData { floatValue = 2, intValue = 1 },
|
||||
new TestData { floatValue = 3, intValue = 2 },
|
||||
new TestData { floatValue = 4, intValue = 3 },
|
||||
new TestData { floatValue = 5, intValue = 4 },
|
||||
new TestData { floatValue = 6, intValue = 5 },
|
||||
} }
|
||||
};
|
||||
|
||||
[Test]
|
||||
[TestCaseSource("s_CopyToArray")]
|
||||
public void CopyToArray(TestData[] datas)
|
||||
{
|
||||
var dest = stackalloc TestData[datas.Length];
|
||||
datas.CopyTo(dest, datas.Length);
|
||||
|
||||
for (int i = 0; i < datas.Length; ++i)
|
||||
Assert.AreEqual(datas[i], dest[i]);
|
||||
}
|
||||
|
||||
static object[][] s_QuickSort = new object[][]
|
||||
{
|
||||
new object[] { new int[] { 0, 1 } },
|
||||
new object[] { new int[] { 1, 0 } },
|
||||
new object[] { new int[] { 0, 4, 2, 6, 3, 7, 1, 5 } }, // Test with unique set
|
||||
new object[] { new int[] { 0, 4, 2, 6, 4, 7, 1, 5 } }, // Test with non unique set
|
||||
};
|
||||
|
||||
[Test]
|
||||
[TestCaseSource("s_QuickSort")]
|
||||
public void QuickSort(int[] values)
|
||||
{
|
||||
// We must perform a copy to avoid messing the test data directly
|
||||
var ptrValues = stackalloc int[values.Length];
|
||||
values.CopyTo(ptrValues, values.Length);
|
||||
|
||||
CoreUnsafeUtils.QuickSort<int>(values.Length, ptrValues);
|
||||
|
||||
for (int i = 0; i < values.Length - 1; ++i)
|
||||
Assert.LessOrEqual(ptrValues[i], ptrValues[i + 1]);
|
||||
}
|
||||
|
||||
static object[][] s_QuickSortHash = new object[][]
|
||||
{
|
||||
new object[]
|
||||
{
|
||||
new Hash128[] { Hash128.Parse("78b27b84a9011b5403e836b9dfa51e33"), Hash128.Parse("c7417d322c083197631326bccf3f9ea0"), Hash128.Parse("dd27f0dc4ffe20b0f8ecc0e4fdf618fe") },
|
||||
new Hash128[] { Hash128.Parse("dd27f0dc4ffe20b0f8ecc0e4fdf618fe"), Hash128.Parse("c7417d322c083197631326bccf3f9ea0"), Hash128.Parse("78b27b84a9011b5403e836b9dfa51e33") },
|
||||
},
|
||||
};
|
||||
|
||||
[Test]
|
||||
[TestCaseSource("s_QuickSortHash")]
|
||||
public void QuickSortHash(Hash128[] l, Hash128[] r)
|
||||
{
|
||||
var lPtr = stackalloc Hash128[l.Length];
|
||||
var rPtr = stackalloc Hash128[r.Length];
|
||||
for (int i = 0; i < l.Length; ++i)
|
||||
{
|
||||
lPtr[i] = l[i];
|
||||
rPtr[i] = r[i];
|
||||
}
|
||||
|
||||
CoreUnsafeUtils.QuickSort<Hash128>(l.Length, lPtr);
|
||||
CoreUnsafeUtils.QuickSort<Hash128>(r.Length, rPtr);
|
||||
|
||||
for (int i = 0; i < l.Length - 1; ++i)
|
||||
{
|
||||
Assert.LessOrEqual(lPtr[i], lPtr[i + 1]);
|
||||
Assert.LessOrEqual(rPtr[i], rPtr[i + 1]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < l.Length; ++i)
|
||||
{
|
||||
Assert.AreEqual(lPtr[i], rPtr[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
|
||||
class EditorExampleTest
|
||||
{
|
||||
[Test]
|
||||
public void EditorSampleTestSimplePasses()
|
||||
{
|
||||
// Use the Assert class to test conditions.
|
||||
}
|
||||
|
||||
// A UnityTest behaves like a coroutine in PlayMode
|
||||
// and allows you to yield null to skip a frame in EditMode
|
||||
[UnityTest]
|
||||
public IEnumerator EditorSampleTestWithEnumeratorPasses()
|
||||
{
|
||||
// Use the Assert class to test conditions.
|
||||
// yield to skip a frame
|
||||
yield return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
|
||||
namespace UnityEngine.Rendering.Tests
|
||||
{
|
||||
unsafe class FixedBufferStringQueueTests
|
||||
{
|
||||
[Test]
|
||||
public void PushAndPopInBufferRange()
|
||||
{
|
||||
const int size = 512;
|
||||
var bufferStart = stackalloc byte[size];
|
||||
var buffer = new CoreUnsafeUtils.FixedBufferStringQueue(bufferStart, size);
|
||||
|
||||
Assert.True(buffer.TryPush("Lorem ipsum dolor sit"));
|
||||
Assert.True(buffer.TryPush("amet, consectetur adipiscing"));
|
||||
Assert.True(buffer.TryPush("elit, sed do eiusmod"));
|
||||
Assert.True(buffer.TryPush("tempor incididunt ut labore"));
|
||||
|
||||
Assert.AreEqual(4, buffer.Count);
|
||||
|
||||
Assert.True(buffer.TryPop(out string v) && v == "Lorem ipsum dolor sit");
|
||||
Assert.True(buffer.TryPop(out v) && v == "amet, consectetur adipiscing");
|
||||
Assert.True(buffer.TryPop(out v) && v == "elit, sed do eiusmod");
|
||||
Assert.True(buffer.TryPop(out v) && v == "tempor incididunt ut labore");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PushAndPopOutOfBufferRange()
|
||||
{
|
||||
const int size = 64;
|
||||
var bufferStart = stackalloc byte[size];
|
||||
var buffer = new CoreUnsafeUtils.FixedBufferStringQueue(bufferStart, size);
|
||||
|
||||
Assert.True(buffer.TryPush("Lorem ipsum dolor sit"));
|
||||
Assert.False(buffer.TryPush("amet, consectetur adipiscing"));
|
||||
|
||||
Assert.AreEqual(1, buffer.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PushAndPopAndClear()
|
||||
{
|
||||
const int size = 128;
|
||||
var bufferStart = stackalloc byte[size];
|
||||
var buffer = new CoreUnsafeUtils.FixedBufferStringQueue(bufferStart, size);
|
||||
|
||||
Assert.True(buffer.TryPush("Lorem ipsum dolor sit"));
|
||||
Assert.True(buffer.TryPush("amet, consectetur adipiscing"));
|
||||
Assert.False(buffer.TryPush("elit, sed do eiusmod"));
|
||||
|
||||
Assert.AreEqual(2, buffer.Count);
|
||||
buffer.Clear();
|
||||
Assert.AreEqual(0, buffer.Count);
|
||||
|
||||
Assert.True(buffer.TryPush("elit, sed do eiusmod"));
|
||||
Assert.True(buffer.TryPush("tempor incididunt ut labore"));
|
||||
Assert.True(buffer.TryPop(out string v) && v == "elit, sed do eiusmod");
|
||||
Assert.True(buffer.TryPop(out v) && v == "tempor incididunt ut labore");
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,79 @@
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace UnityEngine.Rendering.Tests
|
||||
{
|
||||
public static class ReflectionUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Calls a private method from a class
|
||||
/// </summary>
|
||||
/// <param name="methodName">The method name</param>
|
||||
/// <param name="args">The arguments to pass to the method</param>
|
||||
public static object Invoke(this object target, string methodName, params object[] args)
|
||||
{
|
||||
Assert.True(target != null, "The target could not be null");
|
||||
Assert.IsNotEmpty(methodName, "The field to set could not be null");
|
||||
|
||||
var mi = target.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
Assert.True(mi != null, $"Could not find method `{methodName}` on object `{target}`");
|
||||
return mi.Invoke(target, args);
|
||||
}
|
||||
|
||||
private static FieldInfo FindField(this Type type, string fieldName)
|
||||
{
|
||||
FieldInfo fi = null;
|
||||
|
||||
while (type != null)
|
||||
{
|
||||
fi = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
|
||||
if (fi != null) break;
|
||||
|
||||
type = type.BaseType;
|
||||
}
|
||||
|
||||
Assert.True(fi != null, $"Could not find method `{fieldName}` on object `{type}`");
|
||||
|
||||
return fi;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a private field from a class
|
||||
/// </summary>
|
||||
/// <param name="fieldName">The field to change</param>
|
||||
/// <param name="value">The new value</param>
|
||||
public static void SetField(this object target, string fieldName, object value)
|
||||
{
|
||||
Assert.True(target != null, "The target could not be null");
|
||||
Assert.IsNotEmpty(fieldName, "The field to set could not be null");
|
||||
target.GetType().FindField(fieldName).SetValue(target, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of a private field from a class
|
||||
/// </summary>
|
||||
/// <param name="fieldName">The field to get</param>
|
||||
public static object GetField(this object target, string fieldName)
|
||||
{
|
||||
Assert.True(target != null, "The target could not be null");
|
||||
Assert.IsNotEmpty(fieldName, "The field to set could not be null");
|
||||
return target.GetType().FindField(fieldName).GetValue(target);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all the fields from a class
|
||||
/// </summary>
|
||||
public static IEnumerable<FieldInfo> GetFields(this object target)
|
||||
{
|
||||
Assert.True(target != null, "The target could not be null");
|
||||
|
||||
return target.GetType()
|
||||
.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
|
||||
.OrderBy(t => t.MetadataToken);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,552 @@
|
||||
using NUnit.Framework;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
using UnityEngine.Experimental.Rendering.RenderGraphModule;
|
||||
|
||||
namespace UnityEngine.Rendering.Tests
|
||||
{
|
||||
class RenderGraphTests
|
||||
{
|
||||
RenderGraph m_RenderGraph = new RenderGraph();
|
||||
|
||||
[SetUp]
|
||||
public void SetupRenderGraph()
|
||||
{
|
||||
m_RenderGraph.ClearCompiledGraph();
|
||||
}
|
||||
|
||||
class RenderGraphTestPassData
|
||||
{
|
||||
public TextureHandle[] textures = new TextureHandle[8];
|
||||
public ComputeBufferHandle[] buffers = new ComputeBufferHandle[8];
|
||||
}
|
||||
|
||||
// Final output (back buffer) of render graph needs to be explicitly imported in order to know that the chain of dependency should not be culled.
|
||||
[Test]
|
||||
public void WriteToBackBufferNotCulled()
|
||||
{
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass0", out var passData))
|
||||
{
|
||||
builder.WriteTexture(m_RenderGraph.ImportBackbuffer(0));
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
Assert.AreEqual(1, compiledPasses.size);
|
||||
Assert.AreEqual(false, compiledPasses[0].culled);
|
||||
}
|
||||
|
||||
// If no back buffer is ever written to, everything should be culled.
|
||||
[Test]
|
||||
public void NoWriteToBackBufferCulled()
|
||||
{
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass0", out var passData))
|
||||
{
|
||||
builder.WriteTexture(m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }));
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
Assert.AreEqual(1, compiledPasses.size);
|
||||
Assert.AreEqual(true, compiledPasses[0].culled);
|
||||
}
|
||||
|
||||
// Writing to imported resource is considered as a side effect so passes should not be culled.
|
||||
[Test]
|
||||
public void WriteToImportedTextureNotCulled()
|
||||
{
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass0", out var passData))
|
||||
{
|
||||
builder.WriteTexture(m_RenderGraph.ImportTexture(null));
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
Assert.AreEqual(1, compiledPasses.size);
|
||||
Assert.AreEqual(false, compiledPasses[0].culled);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteToImportedComputeBufferNotCulled()
|
||||
{
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass0", out var passData))
|
||||
{
|
||||
builder.WriteComputeBuffer(m_RenderGraph.ImportComputeBuffer(null));
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
Assert.AreEqual(1, compiledPasses.size);
|
||||
Assert.AreEqual(false, compiledPasses[0].culled);
|
||||
}
|
||||
|
||||
// TODO RENDERGRAPH : Temporarily removed. See RenderGraph.cs pass culling
|
||||
//// A pass not writing to anything is useless and should be culled.
|
||||
//[Test]
|
||||
//public void CullPassWithNoProduct()
|
||||
//{
|
||||
// // This pass reads an input but does not produce anything (no writes) so it should be culled.
|
||||
// TextureHandle texture = m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm });
|
||||
// using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass0", out var passData))
|
||||
// {
|
||||
// builder.ReadTexture(texture);
|
||||
// builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => { });
|
||||
// }
|
||||
|
||||
// m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
// var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
// Assert.AreEqual(1, compiledPasses.size);
|
||||
// Assert.AreEqual(true, compiledPasses[0].culled);
|
||||
//}
|
||||
|
||||
//// A series of passes with no final product should be culled.
|
||||
//[Test]
|
||||
//public void CullPassWithTextureDependenciesAndNoProduct()
|
||||
//{
|
||||
// // First pass produces an output that is read by second pass.
|
||||
// // Second pass does not produce anything so it should be culled as well as all its unused dependencies.
|
||||
// TextureHandle texture;
|
||||
// using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass0", out var passData))
|
||||
// {
|
||||
// texture = builder.WriteTexture(m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }));
|
||||
// builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => { });
|
||||
// }
|
||||
|
||||
// using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass1", out var passData))
|
||||
// {
|
||||
// builder.ReadTexture(texture);
|
||||
// builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => { });
|
||||
// }
|
||||
|
||||
// m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
// var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
// Assert.AreEqual(2, compiledPasses.size);
|
||||
// Assert.AreEqual(true, compiledPasses[0].culled);
|
||||
// Assert.AreEqual(true, compiledPasses[1].culled);
|
||||
//}
|
||||
|
||||
//// A series of passes with no final product should be culled.
|
||||
//// Here first pass is not culled because Compute Buffer is imported.
|
||||
//// TODO: Add test where compute buffer is created instead of imported once the API exists.
|
||||
//[Test]
|
||||
//public void CullPassWithBufferDependenciesAndNoProduct()
|
||||
//{
|
||||
// // First pass produces an output that is read by second pass.
|
||||
// // Second pass does not produce anything so it should be culled as well as all its unused dependencies.
|
||||
// ComputeBufferHandle computeBuffer;
|
||||
// using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass0", out var passData))
|
||||
// {
|
||||
// computeBuffer = builder.WriteComputeBuffer(m_RenderGraph.ImportComputeBuffer(null));
|
||||
// builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => { });
|
||||
// }
|
||||
|
||||
// using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass1", out var passData))
|
||||
// {
|
||||
// builder.ReadComputeBuffer(computeBuffer);
|
||||
// builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => { });
|
||||
// }
|
||||
|
||||
// m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
// var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
// Assert.AreEqual(2, compiledPasses.size);
|
||||
// Assert.AreEqual(false, compiledPasses[0].culled); // Not culled because writing to an imported resource is a side effect.
|
||||
// Assert.AreEqual(true, compiledPasses[1].culled);
|
||||
//}
|
||||
|
||||
[Test]
|
||||
public void PassWriteResourcePartialNotReadAfterNotCulled()
|
||||
{
|
||||
// If a pass writes to a resource that is not unused globally by the graph but not read ever AFTER the pass then the pass should be culled unless it writes to another used resource.
|
||||
TextureHandle texture0;
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass0", out var passData))
|
||||
{
|
||||
texture0 = builder.WriteTexture(m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }));
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
TextureHandle texture1;
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass1", out var passData))
|
||||
{
|
||||
builder.ReadTexture(texture0);
|
||||
texture1 = builder.WriteTexture(m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }));
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
// This pass writes to texture0 which is used so will not be culled out.
|
||||
// Since texture0 is never read after this pass, we should decrement refCount for this pass and potentially cull it.
|
||||
// However, it also writes to texture1 which is used in the last pass so we mustn't cull it.
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass2", out var passData))
|
||||
{
|
||||
builder.WriteTexture(texture0);
|
||||
builder.WriteTexture(texture1);
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass3", out var passData))
|
||||
{
|
||||
builder.ReadTexture(texture1);
|
||||
builder.WriteTexture(m_RenderGraph.ImportBackbuffer(0)); // Needed for the passes to not be culled
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
Assert.AreEqual(4, compiledPasses.size);
|
||||
Assert.AreEqual(false, compiledPasses[0].culled);
|
||||
Assert.AreEqual(false, compiledPasses[1].culled);
|
||||
Assert.AreEqual(false, compiledPasses[2].culled);
|
||||
Assert.AreEqual(false, compiledPasses[3].culled);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void PassDisallowCullingNotCulled()
|
||||
{
|
||||
// This pass does nothing so should be culled but we explicitly disallow it.
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass0", out var passData))
|
||||
{
|
||||
builder.AllowPassCulling(false);
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
Assert.AreEqual(1, compiledPasses.size);
|
||||
Assert.AreEqual(false, compiledPasses[0].culled);
|
||||
}
|
||||
|
||||
// First pass produces two textures and second pass only read one of the two. Pass one should not be culled.
|
||||
[Test]
|
||||
public void PartialUnusedProductNotCulled()
|
||||
{
|
||||
TextureHandle texture;
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass0", out var passData))
|
||||
{
|
||||
texture = builder.WriteTexture(m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }));
|
||||
builder.WriteTexture(m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }));
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass1", out var passData))
|
||||
{
|
||||
builder.ReadTexture(texture);
|
||||
builder.WriteTexture(m_RenderGraph.ImportBackbuffer(0));
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
Assert.AreEqual(2, compiledPasses.size);
|
||||
Assert.AreEqual(false, compiledPasses[0].culled);
|
||||
Assert.AreEqual(false, compiledPasses[1].culled);
|
||||
}
|
||||
|
||||
// Simple cycle of create/release of a texture across multiple passes.
|
||||
[Test]
|
||||
public void SimpleCreateReleaseTexture()
|
||||
{
|
||||
TextureHandle texture;
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass0", out var passData))
|
||||
{
|
||||
texture = builder.WriteTexture(m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }));
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
// Add dummy passes
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass1", out var passData))
|
||||
{
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
}
|
||||
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass2", out var passData))
|
||||
{
|
||||
builder.ReadTexture(texture);
|
||||
builder.WriteTexture(m_RenderGraph.ImportBackbuffer(0)); // Needed for the passes to not be culled
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
Assert.AreEqual(4, compiledPasses.size);
|
||||
Assert.Contains(texture.handle.index, compiledPasses[0].resourceCreateList[(int)RenderGraphResourceType.Texture]);
|
||||
Assert.Contains(texture.handle.index, compiledPasses[3].resourceReleaseList[(int)RenderGraphResourceType.Texture]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UseTransientOutsidePassRaiseException()
|
||||
{
|
||||
Assert.Catch<System.ArgumentException>(() =>
|
||||
{
|
||||
TextureHandle texture;
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass0", out var passData))
|
||||
{
|
||||
texture = builder.CreateTransientTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm });
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass1", out var passData))
|
||||
{
|
||||
builder.ReadTexture(texture); // This is illegal (transient resource was created in previous pass)
|
||||
builder.WriteTexture(m_RenderGraph.ImportBackbuffer(0)); // Needed for the passes to not be culled
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
m_RenderGraph.CompileRenderGraph();
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TransientCreateReleaseInSamePass()
|
||||
{
|
||||
TextureHandle texture;
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass0", out var passData))
|
||||
{
|
||||
texture = builder.CreateTransientTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm });
|
||||
builder.WriteTexture(m_RenderGraph.ImportBackbuffer(0)); // Needed for the passes to not be culled
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
Assert.AreEqual(1, compiledPasses.size);
|
||||
Assert.Contains(texture.handle.index, compiledPasses[0].resourceCreateList[(int)RenderGraphResourceType.Texture]);
|
||||
Assert.Contains(texture.handle.index, compiledPasses[0].resourceReleaseList[(int)RenderGraphResourceType.Texture]);
|
||||
}
|
||||
|
||||
// Texture that should be released during an async pass should have their release delayed until the first pass that syncs with the compute pipe.
|
||||
// Otherwise they may be reused by the graphics pipe even if the async pipe is not done executing.
|
||||
[Test]
|
||||
public void AsyncPassReleaseTextureOnGraphicsPipe()
|
||||
{
|
||||
TextureHandle texture0;
|
||||
TextureHandle texture1;
|
||||
TextureHandle texture2;
|
||||
TextureHandle texture3;
|
||||
// First pass creates and writes two textures.
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("Async_TestPass0", out var passData))
|
||||
{
|
||||
texture0 = builder.WriteTexture(m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }));
|
||||
texture1 = builder.WriteTexture(m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }));
|
||||
builder.EnableAsyncCompute(true);
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
// Second pass creates a transient texture => Create/Release should happen in this pass but we want to delay the release until the first graphics pipe pass that sync with async queue.
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("Async_TestPass1", out var passData))
|
||||
{
|
||||
texture2 = builder.CreateTransientTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm });
|
||||
builder.WriteTexture(texture0);
|
||||
builder.EnableAsyncCompute(true);
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
// This pass is the last to read texture0 => Release should happen in this pass but we want to delay the release until the first graphics pipe pass that sync with async queue.
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("Async_TestPass2", out var passData))
|
||||
{
|
||||
texture0 = builder.ReadTexture(texture0);
|
||||
builder.WriteTexture(texture1);
|
||||
builder.EnableAsyncCompute(true);
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
// Just here to add "padding" to the number of passes to ensure resources are not released right at the first sync pass.
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass3", out var passData))
|
||||
{
|
||||
texture3 = builder.WriteTexture(m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }));
|
||||
builder.EnableAsyncCompute(false);
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
// Pass prior to synchronization should be where textures are released.
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass4", out var passData))
|
||||
{
|
||||
builder.WriteTexture(texture3);
|
||||
builder.EnableAsyncCompute(false);
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
// Graphics pass that reads texture1. This will request a sync with compute pipe. The previous pass should be the one releasing async textures.
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass5", out var passData))
|
||||
{
|
||||
builder.ReadTexture(texture1);
|
||||
builder.ReadTexture(texture3);
|
||||
builder.WriteTexture(m_RenderGraph.ImportBackbuffer(0)); // Needed for the passes to not be culled
|
||||
builder.EnableAsyncCompute(false);
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
Assert.AreEqual(6, compiledPasses.size);
|
||||
Assert.Contains(texture0.handle.index, compiledPasses[4].resourceReleaseList[(int)RenderGraphResourceType.Texture]);
|
||||
Assert.Contains(texture2.handle.index, compiledPasses[4].resourceReleaseList[(int)RenderGraphResourceType.Texture]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TransientResourceNotCulled()
|
||||
{
|
||||
TextureHandle texture0;
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass0", out var passData))
|
||||
{
|
||||
texture0 = builder.WriteTexture(m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }));
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass1", out var passData))
|
||||
{
|
||||
builder.CreateTransientTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm });
|
||||
builder.WriteTexture(texture0);
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
// Graphics pass that reads texture1. This will request a sync with compute pipe. The previous pass should be the one releasing async textures.
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass5", out var passData))
|
||||
{
|
||||
builder.ReadTexture(texture0);
|
||||
builder.WriteTexture(m_RenderGraph.ImportBackbuffer(0)); // Needed for the passes to not be culled
|
||||
builder.EnableAsyncCompute(false);
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
Assert.AreEqual(3, compiledPasses.size);
|
||||
Assert.AreEqual(false, compiledPasses[1].culled);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AsyncPassWriteWaitOnGraphcisPipe()
|
||||
{
|
||||
TextureHandle texture0;
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass0", out var passData))
|
||||
{
|
||||
texture0 = builder.WriteTexture(m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }));
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("Async_TestPass1", out var passData))
|
||||
{
|
||||
texture0 = builder.WriteTexture(texture0);
|
||||
builder.EnableAsyncCompute(true);
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass2", out var passData))
|
||||
{
|
||||
builder.ReadTexture(texture0);
|
||||
builder.WriteTexture(m_RenderGraph.ImportBackbuffer(0)); // Needed for the passes to not be culled
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
Assert.AreEqual(3, compiledPasses.size);
|
||||
Assert.AreEqual(0, compiledPasses[1].syncToPassIndex);
|
||||
Assert.AreEqual(1, compiledPasses[2].syncToPassIndex);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AsyncPassReadWaitOnGraphcisPipe()
|
||||
{
|
||||
TextureHandle texture0;
|
||||
TextureHandle texture1;
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass0", out var passData))
|
||||
{
|
||||
texture0 = builder.WriteTexture(m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }));
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("Async_TestPass1", out var passData))
|
||||
{
|
||||
builder.ReadTexture(texture0);
|
||||
texture1 = builder.WriteTexture(m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }));
|
||||
builder.EnableAsyncCompute(true);
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass2", out var passData))
|
||||
{
|
||||
builder.ReadTexture(texture1);
|
||||
builder.WriteTexture(m_RenderGraph.ImportBackbuffer(0)); // Needed for the passes to not be culled
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
Assert.AreEqual(3, compiledPasses.size);
|
||||
Assert.AreEqual(0, compiledPasses[1].syncToPassIndex);
|
||||
Assert.AreEqual(1, compiledPasses[2].syncToPassIndex);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GraphicsPassWriteWaitOnAsyncPipe()
|
||||
{
|
||||
TextureHandle texture0;
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("Async_TestPass0", out var passData))
|
||||
{
|
||||
texture0 = builder.WriteTexture(m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }));
|
||||
builder.EnableAsyncCompute(true);
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass1", out var passData))
|
||||
{
|
||||
builder.WriteTexture(texture0);
|
||||
builder.WriteTexture(m_RenderGraph.ImportBackbuffer(0)); // Needed for the passes to not be culled
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
Assert.AreEqual(2, compiledPasses.size);
|
||||
Assert.AreEqual(0, compiledPasses[1].syncToPassIndex);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GraphicsPassReadWaitOnAsyncPipe()
|
||||
{
|
||||
TextureHandle texture0;
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("Async_TestPass0", out var passData))
|
||||
{
|
||||
texture0 = builder.WriteTexture(m_RenderGraph.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm }));
|
||||
builder.EnableAsyncCompute(true);
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
using (var builder = m_RenderGraph.AddRenderPass<RenderGraphTestPassData>("TestPass1", out var passData))
|
||||
{
|
||||
builder.ReadTexture(texture0);
|
||||
builder.WriteTexture(m_RenderGraph.ImportBackbuffer(0)); // Needed for the passes to not be culled
|
||||
builder.SetRenderFunc((RenderGraphTestPassData data, RenderGraphContext context) => {});
|
||||
}
|
||||
|
||||
m_RenderGraph.CompileRenderGraph();
|
||||
|
||||
var compiledPasses = m_RenderGraph.GetCompiledPassInfos();
|
||||
Assert.AreEqual(2, compiledPasses.size);
|
||||
Assert.AreEqual(0, compiledPasses[1].syncToPassIndex);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "Unity.RenderPipelines.Core.Editor.Tests",
|
||||
"references": [
|
||||
"GUID:df380645f10b7bc4b97d4f5eb6303d95",
|
||||
"GUID:3eae0364be2026648bf74846acb8a731",
|
||||
"GUID:27619889b8ba8c24980f49ee34dbb44a",
|
||||
"GUID:0acc523941302664db1f4e527237feb3"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [
|
||||
"nunit.framework.dll"
|
||||
],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [
|
||||
"UNITY_INCLUDE_TESTS"
|
||||
],
|
||||
"versionDefines": []
|
||||
}
|
@@ -0,0 +1,159 @@
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEditor.Rendering;
|
||||
|
||||
namespace UnityEngine.Rendering.Tests
|
||||
{
|
||||
public class VolumeComponentEditorTests
|
||||
{
|
||||
class VolumeComponentNoAdditionalAttributes : VolumeComponent
|
||||
{
|
||||
public MinFloatParameter parameter = new MinFloatParameter(0f, 0f);
|
||||
}
|
||||
|
||||
class VolumeComponentAllAdditionalAttributes : VolumeComponent
|
||||
{
|
||||
[AdditionalProperty]
|
||||
public MinFloatParameter parameter1 = new MinFloatParameter(0f, 0f);
|
||||
|
||||
[AdditionalProperty]
|
||||
public FloatParameter parameter2 = new MinFloatParameter(0f, 0f);
|
||||
}
|
||||
|
||||
class VolumeComponentMixedAdditionalAttributes : VolumeComponent
|
||||
{
|
||||
public MinFloatParameter parameter1 = new MinFloatParameter(0f, 0f);
|
||||
|
||||
[AdditionalProperty]
|
||||
public FloatParameter parameter2 = new MinFloatParameter(0f, 0f);
|
||||
|
||||
public MinFloatParameter parameter3 = new MinFloatParameter(0f, 0f);
|
||||
|
||||
[AdditionalProperty]
|
||||
public FloatParameter parameter4 = new MinFloatParameter(0f, 0f);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestOverridesChanges()
|
||||
{
|
||||
var component = ScriptableObject.CreateInstance<VolumeComponentMixedAdditionalAttributes>();
|
||||
var editor = (VolumeComponentEditor)Activator.CreateInstance(typeof(VolumeComponentEditor));
|
||||
editor.Invoke("Init", component, null);
|
||||
|
||||
component.SetAllOverridesTo(false);
|
||||
bool allOverridesState = (bool)editor.Invoke("AreAllOverridesTo", false);
|
||||
Assert.True(allOverridesState);
|
||||
|
||||
component.SetAllOverridesTo(true);
|
||||
|
||||
// Was the change correct?
|
||||
allOverridesState = (bool)editor.Invoke("AreAllOverridesTo", true);
|
||||
Assert.True(allOverridesState);
|
||||
|
||||
// Enable the advance mode on the editor
|
||||
component.SetField("m_AdvancedMode", true);
|
||||
|
||||
// Everything is false
|
||||
component.SetAllOverridesTo(false);
|
||||
|
||||
// Disable the advance mode on the editor
|
||||
component.SetField("m_AdvancedMode", false);
|
||||
|
||||
// Now just set to true the overrides of non additional properties
|
||||
editor.Invoke("SetOverridesTo", true);
|
||||
|
||||
// Check that the non additional properties must be false
|
||||
allOverridesState = (bool)editor.Invoke("AreAllOverridesTo", true);
|
||||
Assert.False(allOverridesState);
|
||||
|
||||
ScriptableObject.DestroyImmediate(component);
|
||||
}
|
||||
|
||||
static TestCaseData[] s_AdditionalAttributesTestCaseDatas =
|
||||
{
|
||||
new TestCaseData(typeof(VolumeComponentNoAdditionalAttributes))
|
||||
.Returns(Array.Empty<string>())
|
||||
.SetName("VolumeComponentNoAdditionalAttributes"),
|
||||
new TestCaseData(typeof(VolumeComponentAllAdditionalAttributes))
|
||||
.Returns(new string[2] {"parameter1", "parameter2"})
|
||||
.SetName("VolumeComponentAllAdditionalAttributes"),
|
||||
new TestCaseData(typeof(VolumeComponentMixedAdditionalAttributes))
|
||||
.Returns(new string[2] {"parameter2", "parameter4"})
|
||||
.SetName("VolumeComponentMixedAdditionalAttributes"),
|
||||
};
|
||||
|
||||
[Test, TestCaseSource(nameof(s_AdditionalAttributesTestCaseDatas))]
|
||||
public string[] AdditionalProperties(Type volumeComponentType)
|
||||
{
|
||||
var component = (VolumeComponent)ScriptableObject.CreateInstance(volumeComponentType);
|
||||
var editor = (VolumeComponentEditor)Activator.CreateInstance(typeof(VolumeComponentEditor));
|
||||
editor.Invoke("Init", component, null);
|
||||
|
||||
var fields = component
|
||||
.GetFields()
|
||||
.Where(f => f.GetCustomAttribute<AdditionalPropertyAttribute>() != null)
|
||||
.Select(f => f.Name)
|
||||
.ToArray();
|
||||
|
||||
var notAdditionalParameters = editor.GetField("m_VolumeNotAdditionalParameters") as List<VolumeParameter>;
|
||||
Assert.True(fields.Count() + notAdditionalParameters.Count == component.parameters.Count);
|
||||
|
||||
ScriptableObject.DestroyImmediate(component);
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
#region Decorators Handling Test
|
||||
|
||||
class VolumeComponentDecorators : VolumeComponent
|
||||
{
|
||||
[Tooltip("Increase to make the noise texture appear bigger and less")]
|
||||
public FloatParameter _NoiseTileSize = new FloatParameter(25.0f);
|
||||
|
||||
[InspectorName("Color")]
|
||||
public ColorParameter _FogColor = new ColorParameter(Color.grey);
|
||||
|
||||
[InspectorName("Size and occurrence"), Tooltip("Increase to make patches SMALLER, and frequent")]
|
||||
public ClampedFloatParameter _HighNoiseSpaceFreq = new ClampedFloatParameter(0.1f, 0.1f, 1f);
|
||||
}
|
||||
|
||||
readonly (string displayName, string tooltip)[] k_ExpectedResults =
|
||||
{
|
||||
(string.Empty, "Increase to make the noise texture appear bigger and less"),
|
||||
("Color", string.Empty),
|
||||
("Size and occurrence", "Increase to make patches SMALLER, and frequent")
|
||||
};
|
||||
|
||||
[Test]
|
||||
public void TestHandleParameterDecorators()
|
||||
{
|
||||
var component = ScriptableObject.CreateInstance<VolumeComponentDecorators>();
|
||||
var editor = (VolumeComponentEditor)Activator.CreateInstance(typeof(VolumeComponentEditor));
|
||||
editor.Invoke("Init", component, null);
|
||||
|
||||
var parameters =
|
||||
editor.GetField("m_Parameters") as List<(GUIContent displayName, int displayOrder,
|
||||
SerializedDataParameter param)>;
|
||||
|
||||
Assert.True(parameters != null && parameters.Count() == k_ExpectedResults.Count());
|
||||
|
||||
for (int i = 0; i < k_ExpectedResults.Count(); ++i)
|
||||
{
|
||||
var property = parameters[i].param;
|
||||
var title = new GUIContent(parameters[i].displayName);
|
||||
|
||||
editor.Invoke("HandleDecorators", property, title);
|
||||
|
||||
Assert.True(k_ExpectedResults[i].displayName == title.text);
|
||||
Assert.True(k_ExpectedResults[i].tooltip == title.tooltip);
|
||||
}
|
||||
|
||||
ScriptableObject.DestroyImmediate(component);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.TestTools;
|
||||
using NUnit.Framework;
|
||||
using System.Collections;
|
||||
|
||||
class RuntimeExampleTest
|
||||
{
|
||||
[Test]
|
||||
public void PlayModeSampleTestSimplePasses()
|
||||
{
|
||||
// Use the Assert class to test conditions.
|
||||
}
|
||||
|
||||
// A UnityTest behaves like a coroutine in PlayMode
|
||||
// and allows you to yield null to skip a frame in EditMode
|
||||
[UnityTest]
|
||||
public IEnumerator PlayModeSampleTestWithEnumeratorPasses()
|
||||
{
|
||||
// Use the Assert class to test conditions.
|
||||
// yield to skip a frame
|
||||
yield return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "Unity.RenderPipelines.Core.Runtime.Tests",
|
||||
"references": [
|
||||
"GUID:df380645f10b7bc4b97d4f5eb6303d95",
|
||||
"GUID:27619889b8ba8c24980f49ee34dbb44a",
|
||||
"GUID:0acc523941302664db1f4e527237feb3"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [
|
||||
"nunit.framework.dll"
|
||||
],
|
||||
"autoReferenced": false,
|
||||
"defineConstraints": [
|
||||
"UNITY_INCLUDE_TESTS"
|
||||
],
|
||||
"versionDefines": []
|
||||
}
|
Reference in New Issue
Block a user