Skip to content

Commit 0951718

Browse files
svc-reach-platform-supportEvergreen
authored andcommitted
[Port] [6000.0] Graphics/bugfix/copypass texture array
1 parent b02dd4c commit 0951718

3 files changed

Lines changed: 66 additions & 8 deletions

File tree

Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraphUtilsBlit.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ public static bool CanAddCopyPassMSAA()
2020
return Blitter.CanCopyMSAA();
2121
}
2222

23+
/// <summary>
24+
/// Checks if the shader features required by the MSAA version of the copy pass is supported on current platform.
25+
/// </summary>
26+
/// <param name="sourceDesc">The texture description of the that will be copied from.</param>
27+
/// <returns>Returns true if the shader features required by the copy pass is supported for MSAA, otherwise will it return false.</returns>
28+
public static bool CanAddCopyPassMSAA(in TextureDesc sourceDesc)
29+
{
30+
return Blitter.CanCopyMSAA(sourceDesc);
31+
}
32+
2333
class CopyPassData
2434
{
2535
public bool isMSAA;
@@ -80,7 +90,7 @@ public static void AddCopyPass(
8090
// It would have 1 if the MSAA pass is not able to be used for target and 2 otherwise.
8191
// https://docs.unity3d.com/2017.4/Documentation/Manual/SL-ShaderCompileTargets.html
8292
// https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-to-get-sample-position
83-
if (isMSAA && !Blitter.CanCopyMSAA())
93+
if (isMSAA && !Blitter.CanCopyMSAA(sourceDesc))
8494
throw new ArgumentException("Target does not support MSAA for AddCopyPass. Please use the blit alternative or use non MSAA textures.");
8595

8696
using (var builder = graph.AddRasterRenderPass<CopyPassData>(passName, out var passData, file, line))

Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blitter.cs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Text.RegularExpressions;
66
using UnityEngine.Rendering.RenderGraphModule.Util;
77
using UnityEngine.Rendering.RenderGraphModule;
8+
89
#if UNITY_EDITOR
910
using UnityEditor;
1011
#endif
@@ -285,10 +286,9 @@ static internal void DrawQuad(CommandBuffer cmd, Material material, int shaderPa
285286

286287
internal static bool CanCopyMSAA()
287288
{
288-
//Temporary disable most msaa copies as we fix UUM-67324 which is a bit more involved due to the internal work required
289-
GraphicsDeviceType deviceType = SystemInfo.graphicsDeviceType;
290-
if (deviceType != GraphicsDeviceType.Metal || deviceType != GraphicsDeviceType.Vulkan)
289+
if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.PlayStation4)
291290
{
291+
// Will be done later, see: UUM-97281
292292
return false;
293293
}
294294

@@ -298,10 +298,34 @@ internal static bool CanCopyMSAA()
298298
return s_Copy.passCount == 2;
299299
}
300300

301+
internal static bool CanCopyMSAA(in TextureDesc sourceDesc)
302+
{
303+
304+
// Real native renderpass platforms
305+
// TODO: Expose this through systeminfo
306+
bool hasRenderPass =
307+
SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal
308+
|| SystemInfo.graphicsDeviceType == GraphicsDeviceType.Vulkan
309+
|| SystemInfo.graphicsDeviceType == GraphicsDeviceType.Direct3D12;
310+
311+
if (SystemInfo.supportsMultisampleAutoResolve &&
312+
!hasRenderPass && sourceDesc.bindTextureMS == false)
313+
{
314+
// If we have autoresolve it means msaa rendertextures render as MSAA but magically resolve in the driver when accessed as a texture, the MSAA surface is fully hidden inside the GFX device
315+
// this is contrary to most platforms where the resolve magic on reading happens in the engine layer (and thus allocates proper multi sampled and resolve surfaces the engine can access)
316+
// So in the cases of auto resolving, and a renderpass framebuffer fetch emulation layer we can't correctly access the individual unresolved msaa samples and thus don't allow this case here
317+
// Note: In practice the above check mostly triggers on GLES.
318+
return false;
319+
}
320+
321+
return CanCopyMSAA();
322+
}
323+
301324
/// <summary>
302325
/// Copy a texture to another texture using framebuffer fetch.
303326
/// </summary>
304327
/// <param name="cmd">Command Buffer used for rendering.</param>
328+
/// <param name="isMSAA">Use the MSAA variant of the copy shader (otherwise single sample is used).</param>
305329
/// <param name="force2DForXR">Disable the special handling when XR is active where the source and destination are considered array
306330
/// textures with a slice for each eye. Setting this to true will consider source and destination as regular 2D textures. When XR is
307331
/// disabled, textures are always 2D so forcing them to 2D has no impact.</param>

Tests/SRPTests/Projects/UniversalGraphicsTest_Foundation/Assets/Scenes/315_CoreCopyAndBlit/CoreCopyBlitTestFeature.cs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@ class CustomRenderPass : ScriptableRenderPass
1313
{
1414
Material m_Material;
1515
Material m_materialTint;
16+
Material m_materialDummyTint;
1617

1718
int m_Pass;
18-
public void init(Material material, Material materialTint, int pass)
19+
public void init(Material material, Material materialTint, Material materialDummyTint, int pass)
1920
{
2021
m_Material = material;
2122
m_materialTint = materialTint;
23+
m_materialDummyTint = materialDummyTint;
24+
2225
m_Pass = pass;
2326
}
2427

@@ -33,7 +36,7 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer
3336

3437
var mip = 0;
3538

36-
if (textureDesc.msaaSamples != MSAASamples.None && RenderGraphUtils.CanAddCopyPassMSAA())
39+
if (textureDesc.msaaSamples != MSAASamples.None && RenderGraphUtils.CanAddCopyPassMSAA(textureDesc))
3740
{
3841
textureDesc.name = "Temp FBFetchMSAA";
3942
TextureHandle fbFetchDestinationMSAA = renderGraph.CreateTexture(textureDesc);
@@ -44,13 +47,29 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer
4447
// Tint the temp texture, this works through alpha blending on the blit material and thus ensures we're not just sampling
4548
// an auto-resolved surface or something but that the copied pixels are good for "framebuffer operations"
4649
BlitMaterialParameters param = new BlitMaterialParameters(TextureHandle.nullHandle, fbFetchDestinationMSAA, m_materialTint, 0);
47-
renderGraph.AddBlitPass(param);
50+
renderGraph.AddBlitPass(param, passName: "Tint Temp Texture Blit");
4851

4952
// Copy the whole thing back to the main color texture
5053
renderGraph.AddCopyPass(fbFetchDestinationMSAA, resourceData.activeColorTexture, 0, 0, mip, mip, "Copy MSAA 2");
54+
55+
// This blit does nothing, it tints the color buffer by 1,1,1 it just ensures the blit pass below renders correctly
56+
// I "assume" it ensures vulkan thinks the color buffer has changed and it will correctly pick up the values in the inverse blit pass below.
57+
// Without this dummy pass it actually picks up the untinted values (i.e. the results of the copy pass above are not visible)
58+
// My suspicion is that this is because the copy pass goes through the renderpass api and the blit goes through setRT
59+
// we've seen similar issues before in other code where mixing renderpasses/setRT confused things.
60+
// When looking at this in renderdoc without this dummy pass you will see:
61+
// Pass "DrawOpaqueObjects": Resolves to 2d color attachment #x
62+
// Pass "Copy MSAA 2": Resolves to 2d color attachment #y
63+
// Pass "Blit inverse using Material": Reads from color attachment #x < so it incorrectly picks an old version X istead of Y (note: this is the resolve target specifically the MSAA samples target seems to be correct?)
64+
if (SystemInfo.graphicsDeviceType == GraphicsDeviceType.Vulkan)
65+
{
66+
BlitMaterialParameters paramDummy = new BlitMaterialParameters(TextureHandle.nullHandle, resourceData.activeColorTexture, m_materialDummyTint, 0);
67+
renderGraph.AddBlitPass(paramDummy, passName: "Dummy Blit");
68+
}
5169
}
5270
else
5371
{
72+
// If we can't do MSAA copies that part of the test doesn't apply. But we just tint the buffer here so the ref images are still the same for all cases
5473
BlitMaterialParameters param = new BlitMaterialParameters(TextureHandle.nullHandle, resourceData.activeColorTexture, m_materialTint, 0);
5574
renderGraph.AddBlitPass(param);
5675
}
@@ -84,11 +103,16 @@ public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer
84103
CustomRenderPass m_ScriptablePass;
85104
public Material material = null;
86105
public Material materialTint = null;
106+
private Material materialDummy = null;
107+
87108
public int pass = 0;
88109
/// <inheritdoc/>
89110
public override void Create()
90111
{
91112
m_ScriptablePass = new CustomRenderPass();
113+
materialDummy = new Material(materialTint);
114+
materialDummy.SetColor("_Color", Color.white);
115+
materialDummy.SetColor("_EyeOneColor", Color.white);
92116

93117
// Configures where the render pass should be injected.
94118
m_ScriptablePass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques;
@@ -99,7 +123,7 @@ public override void Create()
99123
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
100124
{
101125
if (material == null || materialTint == null) return;
102-
m_ScriptablePass.init(material, materialTint, pass);
126+
m_ScriptablePass.init(material, materialTint, materialDummy, pass);
103127
m_ScriptablePass.requiresIntermediateTexture = true;
104128
renderer.EnqueuePass(m_ScriptablePass);
105129
}

0 commit comments

Comments
 (0)