您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

409 行
15 KiB

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using System.IO;
using UnityEditor;
using NUnit.Framework;
using UnityEngine.TestTools;
namespace UnityEngine.Experimental.Rendering
{
public class TestFrameworkTools
{
public static readonly string s_RootPath = Directory.GetParent(Directory.GetFiles(Application.dataPath, "SRPMARKER", SearchOption.AllDirectories).First()).ToString();
// path where the tests live
public static string[] s_Path =
{
"Tests",
"GraphicsTests",
"RenderPipeline"
};
public static Dictionary<string, string> renderPipelineAssets = new Dictionary<string, string>()
{
{ "HDRP", "HDRenderPipeline/CommonAssets/RP_Assets/HDRP_Test_Def.asset" },
{ "LWRP", "LightweightPipeline/LightweightPipelineAsset.asset" }
};
// Renderpipeline assets used for the tests
public static Dictionary<string, string> renderPipelineScenesFolder = new Dictionary<string, string>()
{
{ "HDRP", "HDRenderPipeline/Scenes" },
{ "LWRP", "LightweightPipeline/Scenes" }
};
// info that gets generated for use
// in a dod way
public struct TestInfo
{
public string name;
public string comment;
public float threshold;
public string relativePath;
public string templatePath;
public int frameWait;
public int sceneListIndex;
public override string ToString()
{
if (string.IsNullOrEmpty(comment))
return name;
else
return string.Format("{0}: {1}", name, comment);
}
}
// Get additionalSceneInfo
public static Dictionary<string, AdditionalTestSceneInfos.AdditionalTestSceneInfo> GetAdditionalInfos ( string path)
{
Dictionary<string, AdditionalTestSceneInfos.AdditionalTestSceneInfo> o = new Dictionary<string, AdditionalTestSceneInfos.AdditionalTestSceneInfo>();
AdditionalTestSceneInfos additionalTestSceneInfos = AssetDatabase.LoadAssetAtPath<AdditionalTestSceneInfos>(path);
if (additionalTestSceneInfos != null)
{
for (int i=0 ; i<additionalTestSceneInfos.additionalInfos.Length ; ++i)
{
o[additionalTestSceneInfos.additionalInfos[i].name] = additionalTestSceneInfos.additionalInfos[i];
}
}
return o;
}
// collect the scenes that we can use
public static class CollectScenes
{
public static IEnumerable HDRP
{
get
{
return GetScenesForPipelineID("HDRP");
}
}
public static IEnumerable HDRP_Params
{
get
{
return GetScenesForPipelineID("HDRP", true);
}
}
public static IEnumerable LWRP
{
get
{
return GetScenesForPipelineID("LWRP");
}
}
public static IEnumerable GetScenesForPipelineID(string _pipelineID, bool fixtureParam = false)
{
return GetScenesForPipeline(renderPipelineScenesFolder[_pipelineID]);
}
public static IEnumerable GetScenesForPipeline(string _pipelinePath, bool fixtureParam = false)
{
var absoluteScenesPath = s_Path.Aggregate(s_RootPath, Path.Combine);
var filesPath = Path.Combine(absoluteScenesPath, _pipelinePath);
// find all the scenes
var allPaths = Directory.GetFiles(filesPath, "*.unity", SearchOption.AllDirectories);
// Convert to List for easy sorting in alphabetical order
List<string> allPaths_List = new List<string>(allPaths);
allPaths_List.Sort();
// Get the play mode scenes
List<string> playModeScenes = new List<string>();
foreach( TestInfo ti in CollectScenesPlayMode.GetScenesForPipeline( _pipelinePath ) )
{
playModeScenes.Add(ti.templatePath);
}
// Get the additional infos
var additionalInfos = GetAdditionalInfos( "Assets"+Path.Combine(filesPath.Replace(Application.dataPath, ""), "AdditionalTestSceneInfos.asset") );
// construct all the needed test infos
for (int i = 0; i < allPaths_List.Count; ++i)
{
var path = allPaths_List[i];
var p = new FileInfo(path);
var split = s_Path.Aggregate("", Path.Combine);
split = string.Format("{0}{1}", split, Path.DirectorySeparatorChar);
var splitPaths = p.FullName.Split(new[] { split }, StringSplitOptions.RemoveEmptyEntries);
// Filter out play mode tests from the list
if (playModeScenes.Contains(splitPaths.Last()))
continue;
string sceneNum = p.Name.Split("_"[0])[0];
TestInfo testInfo = new TestInfo()
{
name = p.Name,
comment = additionalInfos.ContainsKey(sceneNum)? additionalInfos[sceneNum].comment:null,
relativePath = splitPaths.Last(),
templatePath = splitPaths.Last(),
threshold = 0.02f,
frameWait = 5
};
if (fixtureParam)
yield return new TestFixtureData(testInfo);
else
yield return testInfo;
}
}
}
public static class CollectScenesPlayMode
{
public static IEnumerable HDRP
{
get
{
return GetScenesForPipelineID("HDRP");
}
}
public static IEnumerable HDRP_Param
{
get
{
return GetScenesForPipelineID("HDRP", true);
}
}
public static IEnumerable LWRP
{
get
{
return GetScenesForPipelineID("LWRP");
}
}
public static IEnumerable GetScenesForPipelineID(string _pipelineID, bool fixtureParam = false)
{
return GetScenesForPipeline(renderPipelineScenesFolder[_pipelineID]);
}
public static IEnumerable GetScenesForPipeline(string _pipelinePath, bool fixtureParam = false)
{
#if UNITY_EDITOR
string absoluteScenesPath = s_Path.Aggregate(s_RootPath, Path.Combine);
string assetScenesPath = absoluteScenesPath.Replace(Application.dataPath, "");
assetScenesPath = Path.Combine("Assets", assetScenesPath.Remove(0, 1));
string filesPath = Path.Combine(assetScenesPath, _pipelinePath);
string listFilePath = Path.Combine(filesPath, "EditorPlayModeTests.asset");
EditorPlayModeTests listFile = (EditorPlayModeTests) AssetDatabase.LoadMainAssetAtPath(listFilePath);
if ( listFile == null)
{
AssetDatabase.CreateAsset(ScriptableObject.CreateInstance<EditorPlayModeTests>(), listFilePath);
AssetDatabase.Refresh();
yield return null;
}
else
{
// Get the additional infos
var additionalInfos = GetAdditionalInfos( Path.Combine(filesPath, "AdditionalTestSceneInfos.asset") );
for ( int i=0 ; i<listFile.scenesPath.Length ; ++i)
{
string path = listFile.scenesPath[i];
var p = new FileInfo( Path.Combine(filesPath, path ) );
var split = s_Path.Aggregate("", Path.Combine);
split = string.Format("{0}{1}", split, Path.DirectorySeparatorChar);
var splitPaths = p.FullName.Split(new[] { split }, StringSplitOptions.RemoveEmptyEntries);
string sceneNum = p.Name.Split("_"[0])[0];
TestInfo testInfo = new TestInfo
{
name = p.Name,
comment = additionalInfos.ContainsKey(sceneNum)? additionalInfos[sceneNum].comment:null,
relativePath = p.ToString(),
templatePath = splitPaths.Last(),
threshold = 0.02f,
frameWait = 100,
sceneListIndex = i
};
if (fixtureParam)
yield return new TestFixtureData(testInfo);
else
yield return testInfo;
}
}
#else
yield return "null";
#endif
}
}
// compare textures, use RMS for this
public static bool CompareTextures(Texture2D fromDisk, Texture2D captured, float threshold)
{
if (fromDisk == null || captured == null)
return false;
if (fromDisk.width != captured.width
|| fromDisk.height != captured.height)
return false;
var pixels1 = fromDisk.GetPixels();
var pixels2 = captured.GetPixels();
if (pixels1.Length != pixels2.Length)
return false;
int numberOfPixels = pixels1.Length;
float sumOfSquaredColorDistances = 0;
for (int i = 0; i < numberOfPixels; i++)
{
Color p1 = pixels1[i];
Color p2 = pixels2[i];
Color diff = p1 - p2;
diff = diff * diff;
sumOfSquaredColorDistances += (diff.r + diff.g + diff.b) / 3.0f;
}
float rmse = Mathf.Sqrt(sumOfSquaredColorDistances / numberOfPixels);
return rmse < threshold;
}
public static Texture2D RenderSetupToTexture( SetupSceneForRenderPipelineTest _testSetup)
{
// Setup Render Target
Camera testCamera = _testSetup.cameraToUse;
var rtDesc = new RenderTextureDescriptor(
_testSetup.width,
_testSetup.height,
(_testSetup.hdr && testCamera.allowHDR) ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB32,
24);
#if UNITY_EDITOR
rtDesc.sRGB = PlayerSettings.colorSpace == ColorSpace.Linear;
#endif
rtDesc.msaaSamples = _testSetup.msaaSamples;
// render the scene
var tempTarget = RenderTexture.GetTemporary(rtDesc);
var oldTarget = _testSetup.cameraToUse.targetTexture;
_testSetup.cameraToUse.targetTexture = tempTarget;
_testSetup.cameraToUse.Render();
_testSetup.cameraToUse.targetTexture = oldTarget;
// Readback the rendered texture
var oldActive = RenderTexture.active;
RenderTexture.active = tempTarget;
var captured = new Texture2D(tempTarget.width, tempTarget.height, TextureFormat.RGB24, false);
captured.ReadPixels(new Rect(0, 0, _testSetup.width, _testSetup.height), 0, 0);
RenderTexture.active = oldActive;
return captured;
}
public static bool FindReferenceImage(TestInfo _testInfo, ref Texture2D _fromDisk, Texture2D _captured, ref string _dumpFileLocation)
{
var templatePath = Path.Combine(s_RootPath, "ImageTemplates");
// find the reference image
_dumpFileLocation = Path.Combine(templatePath, string.Format("{0}.{1}", _testInfo.templatePath, "png"));
//Debug.Log("Template file at: " + _dumpFileLocation);
if (!File.Exists(_dumpFileLocation))
{
// no reference exists, create it
var fileInfo = new FileInfo(_dumpFileLocation);
fileInfo.Directory.Create();
var generated = _captured.EncodeToPNG();
File.WriteAllBytes(_dumpFileLocation, generated);
return false;
}
var template = File.ReadAllBytes(_dumpFileLocation);
_fromDisk.LoadImage(template, false);
return true;
}
public static Texture2D GetTemplateImage(string _templatePath)
{
string templatePath = Path.Combine(s_RootPath, "ImageTemplates");
templatePath = Path.Combine(templatePath, string.Format("{0}.{1}", _templatePath, "png"));
if (File.Exists(templatePath))
{
byte[] template = File.ReadAllBytes(templatePath);
Texture2D o = new Texture2D(4, 4);
return o.LoadImage(template, false) ? o : null;
}
else
return null;
}
public static Texture2D GetTemplateImage(TestInfo _testInfo)
{
return GetTemplateImage(_testInfo.templatePath);
}
#if UNITY_EDITOR
public static Texture2D GetTemplateImage(UnityEngine.Object _sceneAsset, ref string path)
{
string _scenePath = AssetDatabase.GetAssetPath(_sceneAsset);
var p = new FileInfo(_scenePath);
var split = s_Path.Aggregate("", Path.Combine);
split = string.Format("{0}{1}", split, Path.DirectorySeparatorChar);
var splitPaths = p.FullName.Split(new[] { split }, StringSplitOptions.RemoveEmptyEntries);
path = splitPaths.Last();
TestInfo testInfo = new TestInfo
{
name = p.Name,
relativePath = p.ToString(),
templatePath = splitPaths.Last(),
threshold = 0.02f,
frameWait = 100,
};
return GetTemplateImage(testInfo);
}
#endif
public static class AssertFix
{
public static void TestWithMessages( bool? _comparison, string _fail = "Test failed", string _pass = null )
{
if (_comparison.HasValue)
{
if (_comparison.Value)
NUnit.Framework.Assert.IsTrue(true, _pass);
else
throw new System.Exception(_fail);
}
else
throw new System.Exception("Test comparison is null.");
}
}
}
}