using NUnit.Framework;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering.RenderGraphModule.Util;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.Rendering;
#endif
namespace UnityEngine.Rendering.Tests
{
partial class RenderGraphTests
{
class TestBlitResources
{
public TextureHandle[] textures = new TextureHandle[2];
public Material material;
public RenderGraphUtils.BlitMaterialParameters blitParameters;
};
TestBlitResources CreateBlitResources(RenderGraph g)
{
TestBlitResources result = new TestBlitResources();
result.material = new Material(Shader.Find("Hidden/BlitCopy"));
for (int i = 0; i < result.textures.Length; i++)
{
result.textures[i] = g.CreateTexture(new TextureDesc(Vector2.one) { colorFormat = GraphicsFormat.R8G8B8A8_UNorm });
}
result.blitParameters = new(result.textures[0], result.textures[1], result.material, 0);
return result;
}
[Test]
public void RenderPassAddBlitReturnBuilder()
{
var resources = CreateBlitResources(m_RenderGraph);
var builderNull = m_RenderGraph.AddBlitPass(resources.blitParameters, "Test Pass", false);
Assert.IsNull(builderNull);
var builder = m_RenderGraph.AddBlitPass(resources.blitParameters, "Test Pass", true);
Assert.IsNotNull(builder);
builder.Dispose();
builderNull = m_RenderGraph.AddBlitPass(resources.textures[0], resources.textures[1], Vector2.one, Vector2.zero, passName: "Test Pass", returnBuilder: false);
Assert.IsNull(builderNull);
builder = m_RenderGraph.AddBlitPass(resources.textures[0], resources.textures[1], Vector2.one, Vector2.zero, passName: "Test Pass", returnBuilder: true);
Assert.IsNotNull(builder);
builder.Dispose();
}
[Test]
public void RenderPassAddBlitSetGlobal()
{
int texture0ID = 0;
int texture1ID = 1;
var resources = CreateBlitResources(m_RenderGraph);
using (var builder = m_RenderGraph.AddBlitPass(resources.blitParameters, "Test Pass", true))
{
builder.SetGlobalTextureAfterPass(resources.textures[0], texture0ID);
}
Assert.IsTrue(m_RenderGraph.IsGlobal(texture0ID));
using (var builder = m_RenderGraph.AddBlitPass(resources.textures[0], resources.textures[1], Vector2.one, Vector2.zero, passName: "Test Pass", returnBuilder: true))
{
builder.SetGlobalTextureAfterPass(resources.textures[1], texture1ID);
}
Assert.IsTrue(m_RenderGraph.IsGlobal(texture1ID));
}
[Test]
public void RenderPassAddBlitUseTexture()
{
var resources = CreateBlitResources(m_RenderGraph);
var canUseCopyPass = RenderGraphUtils.CanAddCopyPass(m_RenderGraph, resources.blitParameters.source, resources.blitParameters.destination);
// Writing to the texture blitting is the same as writing the same texture twice, is not allowed.
using (var builder = m_RenderGraph.AddBlitPass(resources.blitParameters, "BlitPass", true))
{
Assert.Throws<System.InvalidOperationException>(() =>
{
builder.UseTexture(resources.textures[1], AccessFlags.Write);
});
}
// Writing to the texture blitting is the same as writing the same texture twice, is not allowed.
using (var builder = m_RenderGraph.AddBlitPass(resources.textures[0], resources.textures[1], Vector2.one, Vector2.zero, passName: "Test Pass", returnBuilder: true))
{
// The CopyPass should throw the following exception:
// "<System.ArgumentException: Trying to UseTexture on a texture that is already used through SetRenderAttachment. Consider updating your code. (pass BlitPass resource)."
if (canUseCopyPass)
{
Assert.Throws<System.ArgumentException>(() =>
{
builder.UseTexture(resources.textures[1], AccessFlags.Write);
});
}
// The BlitPass should throw the following exception:
// "<System.InvalidOperationException: Trying to write a resource twice in a pass. You can only write the same resource once within a pass (pass BlitPass resource)."
else
{
Assert.Throws<System.InvalidOperationException>(() =>
{
builder.UseTexture(resources.textures[1], AccessFlags.Write);
});
}
}
// Reading the same texture twice is allowed
using (var builder = m_RenderGraph.AddBlitPass(resources.blitParameters, "BlitPass", true))
{
builder.UseTexture(resources.textures[0], AccessFlags.Read);
}
// Reading the same texture twice is allowed
using (var builder = m_RenderGraph.AddBlitPass(resources.textures[0], resources.textures[1], Vector2.one, Vector2.zero, passName: "Test Pass", returnBuilder: true))
{
builder.UseTexture(resources.textures[0], AccessFlags.Read);
}
}
[Test]
public void RenderPassAddBlitNullSourceSupport()
{
var resources = CreateBlitResources(m_RenderGraph);
resources.blitParameters.source = TextureHandle.nullHandle;
// Using a Null Source support using a custom shader is allowed
Assert.DoesNotThrow(delegate { m_RenderGraph.AddBlitPass(resources.blitParameters, "BlitPassNullSource"); });
// Using a Null Source support using a internal blit shader is not allowed and throws an exception
Assert.Throws<System.ArgumentException>(() =>
{
m_RenderGraph.AddBlitPass(resources.blitParameters.source, resources.blitParameters.destination, Vector2.one, Vector2.zero, passName: "BlitPass2");
});
}
[Test]
public void RenderPassAddBlitBackbufferTarget()
{
var resources = CreateBlitResources(m_RenderGraph);
resources.blitParameters.destination = m_RenderGraph.ImportBackbuffer(0);
// Using a backbuffer as destination is allowed
Assert.DoesNotThrow(delegate { m_RenderGraph.AddBlitPass(resources.blitParameters, "BlitPassBackbufferTarget0"); });
Assert.DoesNotThrow(delegate { m_RenderGraph.AddBlitPass(resources.blitParameters.source, resources.blitParameters.destination, Vector2.one, Vector2.zero, passName: "BlitPassBackbufferTarget1"); });
resources.blitParameters.destination = resources.textures[1];
resources.blitParameters.source = m_RenderGraph.ImportBackbuffer(0);
// Using a backbuffer as source is not allowed and throws an exception
Assert.Throws<System.ArgumentException>(() =>
{
m_RenderGraph.AddBlitPass(resources.blitParameters, "BlitPassBackbufferSource0");
});
Assert.Throws<System.ArgumentException>(() =>
{
m_RenderGraph.AddBlitPass(resources.blitParameters.source, resources.blitParameters.destination, Vector2.one, Vector2.zero, passName: "BlitPassBackbufferSource1");
});
}
}
}