Skip to content

Commit 6bcd723

Browse files
[Universal] RenderPass merging (#4099)
* enabled MSAA when the RenderPass API is used. Resolving implicitly to the color target's resolve surface * Initial lazy merging prototype * Lazy merging prototype: all the needed attachments are now added to the RenderPass attachment list. Merging subpasses and attachments which are the same or compatible * initial work to add lazy merging to the deferred renderer (doesn't handle coorrectly edge cases) * MRT attachments merging improvements * fix for a crash because of incomplete Targets setup for merged render passes * change m_ShadowmapWidth/Height variables to use renderTargetWidth * m_ActiveRenderPassQueue[i] to var renderPass * changing hash ctor logic to merge width/height and include depth rtID * fix setlastpass flag loop * NativeArray memory leak fix * refactoring to remove duplicated code * fix non-renderpass passes getting hashes and etc. * more cleaning up, moving RenderPass code in separate functions for clarity * lists to arrays and other gc.alloc related stuff * merge leftovers * moving all the RenderPass API specific code in separate methods as a preparation step to move into different files (potentially) * remove Configure in SetLastPassFlag * refatoring (in progress): moving all the RenderPass API specific code to NativeRenderPassUtils * fixing depth-only offscreen camera and exposing usesNativeRenderPass * merge leftovers * more cleaning up and refactoring * splitting initial scene index setup from RenderPass data, and moved RenderPass data to the NativeRenderPass class * Revert "splitting initial scene index setup from RenderPass data, and moved RenderPass data to the NativeRenderPass class" This reverts commit ef3e215. * fix for RenderPass MRT attachments being setup when the RenderPass API is disabled * adding profiler samples to NativeRenderPass code * moving more RenderPass related code in NativeRenderPass.cs * removed any direct references to RenderPass frame data outside of NativeRenderPass * fixing targetTexture != null and depthOnly pass cornercase with wrong target being picked * NativeRenderPass from static to partial class conversion * add RenderPassDescriptor to contain dimensions and etc. * add GetDefaultGraphicsFormat for RenderPass attachment descriptors * remove isFirstMergeable and isLastMergeable and add comments * moving some stuff and removing some parameters for methods due to partial class impl * some more cleanup * more cleanup: making methods non static and reducing the input parameters * renamed attachmentIndices in m_InputAttachmentIndices * more cleanup: removing unnecessary statics * improved subpass merging * more renaming of methods * renaming more stuff for consistency with previous renamings * renderPass MRT clear logic fixed * useDepth always if depthOnly is true * fixing useDepth not picking up default depth attachment * adding SupportsNativeRenderPass to rendererFeatures and adding mechanism to enable/disable it properly * formatting check fix * more formatting check fixes... * include cleanup * add validation check and fallback * reviewer feedback changes * merge cleanup * minor changes to address reviewers feedback * minor refactoring addressing reviewer feedback Co-authored-by: Manuele Bonanno <[email protected]>
1 parent d983ccd commit 6bcd723

File tree

11 files changed

+605
-189
lines changed

11 files changed

+605
-189
lines changed

com.unity.render-pipelines.universal/Runtime/NativeRenderPass.cs

Lines changed: 531 additions & 0 deletions
Large diffs are not rendered by default.

com.unity.render-pipelines.universal/Runtime/NativeRenderPass.cs.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

com.unity.render-pipelines.universal/Runtime/Passes/AdditionalLightsShadowCasterPass.cs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@ public ShadowResolutionRequest(int _visibleLightIndex, int _perLightShadowSliceI
5656
private RenderTargetHandle m_AdditionalLightsShadowmap;
5757
internal RenderTexture m_AdditionalLightsShadowmapTexture;
5858

59-
int m_ShadowmapWidth;
60-
int m_ShadowmapHeight;
6159

6260
float m_MaxShadowDistanceSq;
6361
float m_CascadeBorder;
@@ -479,8 +477,8 @@ public bool Setup(ref RenderingData renderingData)
479477

480478
Clear();
481479

482-
m_ShadowmapWidth = renderingData.shadowData.additionalLightsShadowmapWidth;
483-
m_ShadowmapHeight = renderingData.shadowData.additionalLightsShadowmapHeight;
480+
renderTargetWidth = renderingData.shadowData.additionalLightsShadowmapWidth;
481+
renderTargetHeight = renderingData.shadowData.additionalLightsShadowmapHeight;
484482

485483
var visibleLights = renderingData.lightData.visibleLights;
486484
int additionalLightsCount = renderingData.lightData.additionalLightsCount;
@@ -747,11 +745,12 @@ public bool Setup(ref RenderingData renderingData)
747745
atlasMaxY = Mathf.Max(atlasMaxY, shadowResolutionRequest.offsetY + shadowResolutionRequest.allocatedResolution);
748746
}
749747
// ...but make sure we still use power-of-two dimensions (might perform better on some hardware)
750-
m_ShadowmapWidth = Mathf.NextPowerOfTwo(atlasMaxX);
751-
m_ShadowmapHeight = Mathf.NextPowerOfTwo(atlasMaxY);
752748

753-
float oneOverAtlasWidth = 1.0f / m_ShadowmapWidth;
754-
float oneOverAtlasHeight = 1.0f / m_ShadowmapHeight;
749+
renderTargetWidth = Mathf.NextPowerOfTwo(atlasMaxX);
750+
renderTargetHeight = Mathf.NextPowerOfTwo(atlasMaxY);
751+
752+
float oneOverAtlasWidth = 1.0f / renderTargetWidth;
753+
float oneOverAtlasHeight = 1.0f / renderTargetHeight;
755754

756755
Matrix4x4 sliceTransform;
757756
for (int globalShadowSliceIndex = 0; globalShadowSliceIndex < shadowCastingLightsBufferCount; ++globalShadowSliceIndex)
@@ -784,7 +783,7 @@ public bool Setup(ref RenderingData renderingData)
784783
m_AdditionalLightShadowSliceIndexTo_WorldShadowMatrix[globalShadowSliceIndex] = sliceTransform * m_AdditionalLightShadowSliceIndexTo_WorldShadowMatrix[globalShadowSliceIndex];
785784
}
786785

787-
m_AdditionalLightsShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(m_ShadowmapWidth, m_ShadowmapHeight, k_ShadowmapBufferBits);
786+
m_AdditionalLightsShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(renderTargetWidth, renderTargetHeight, k_ShadowmapBufferBits);
788787
m_MaxShadowDistanceSq = renderingData.cameraData.maxShadowDistance * renderingData.cameraData.maxShadowDistance;
789788
m_CascadeBorder = renderingData.shadowData.mainLightShadowCascadeBorder;
790789

@@ -793,7 +792,7 @@ public bool Setup(ref RenderingData renderingData)
793792

794793
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
795794
{
796-
ConfigureTarget(new RenderTargetIdentifier(m_AdditionalLightsShadowmapTexture), GraphicsFormat.ShadowAuto, m_ShadowmapWidth, m_ShadowmapHeight, 1, true);
795+
ConfigureTarget(new RenderTargetIdentifier(m_AdditionalLightsShadowmapTexture), GraphicsFormat.ShadowAuto, renderTargetWidth, renderTargetHeight, 1, true);
797796
ConfigureClear(ClearFlag.All, Color.black);
798797
}
799798

com.unity.render-pipelines.universal/Runtime/Passes/MainLightShadowCasterPass.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ private static class MainLightShadowConstantBuffer
2828
const int k_ShadowmapBufferBits = 16;
2929
float m_CascadeBorder;
3030
float m_MaxShadowDistanceSq;
31-
int m_ShadowmapWidth;
32-
int m_ShadowmapHeight;
3331
int m_ShadowCasterCascadesCount;
3432
bool m_SupportsBoxFilterForShadows;
3533

@@ -98,22 +96,22 @@ public bool Setup(ref RenderingData renderingData)
9896

9997
int shadowResolution = ShadowUtils.GetMaxTileResolutionInAtlas(renderingData.shadowData.mainLightShadowmapWidth,
10098
renderingData.shadowData.mainLightShadowmapHeight, m_ShadowCasterCascadesCount);
101-
m_ShadowmapWidth = renderingData.shadowData.mainLightShadowmapWidth;
102-
m_ShadowmapHeight = (m_ShadowCasterCascadesCount == 2) ?
99+
renderTargetWidth = renderingData.shadowData.mainLightShadowmapWidth;
100+
renderTargetHeight = (m_ShadowCasterCascadesCount == 2) ?
103101
renderingData.shadowData.mainLightShadowmapHeight >> 1 :
104102
renderingData.shadowData.mainLightShadowmapHeight;
105103

106104
for (int cascadeIndex = 0; cascadeIndex < m_ShadowCasterCascadesCount; ++cascadeIndex)
107105
{
108106
bool success = ShadowUtils.ExtractDirectionalLightMatrix(ref renderingData.cullResults, ref renderingData.shadowData,
109-
shadowLightIndex, cascadeIndex, m_ShadowmapWidth, m_ShadowmapHeight, shadowResolution, light.shadowNearPlane,
107+
shadowLightIndex, cascadeIndex, renderTargetWidth, renderTargetHeight, shadowResolution, light.shadowNearPlane,
110108
out m_CascadeSplitDistances[cascadeIndex], out m_CascadeSlices[cascadeIndex]);
111109

112110
if (!success)
113111
return false;
114112
}
115113

116-
m_MainLightShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(m_ShadowmapWidth, m_ShadowmapHeight, k_ShadowmapBufferBits);
114+
m_MainLightShadowmapTexture = ShadowUtils.GetTemporaryShadowTexture(renderTargetWidth, renderTargetHeight, k_ShadowmapBufferBits);
117115
m_MaxShadowDistanceSq = renderingData.cameraData.maxShadowDistance * renderingData.cameraData.maxShadowDistance;
118116
m_CascadeBorder = renderingData.shadowData.mainLightShadowCascadeBorder;
119117

@@ -122,7 +120,7 @@ public bool Setup(ref RenderingData renderingData)
122120

123121
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
124122
{
125-
ConfigureTarget(new RenderTargetIdentifier(m_MainLightShadowmapTexture), GraphicsFormat.ShadowAuto, m_ShadowmapWidth, m_ShadowmapHeight, 1, true);
123+
ConfigureTarget(new RenderTargetIdentifier(m_MainLightShadowmapTexture), GraphicsFormat.ShadowAuto, renderTargetWidth, renderTargetHeight, 1, true);
126124
ConfigureClear(ClearFlag.All, Color.black);
127125
}
128126

@@ -215,8 +213,8 @@ void SetupMainLightShadowReceiverConstants(CommandBuffer cmd, VisibleLight shado
215213
for (int i = cascadeCount; i <= k_MaxCascades; ++i)
216214
m_MainLightShadowMatrices[i] = noOpShadowMatrix;
217215

218-
float invShadowAtlasWidth = 1.0f / m_ShadowmapWidth;
219-
float invShadowAtlasHeight = 1.0f / m_ShadowmapHeight;
216+
float invShadowAtlasWidth = 1.0f / renderTargetWidth;
217+
float invShadowAtlasHeight = 1.0f / renderTargetHeight;
220218
float invHalfShadowAtlasWidth = 0.5f * invShadowAtlasWidth;
221219
float invHalfShadowAtlasHeight = 0.5f * invShadowAtlasHeight;
222220
float softShadowsProp = softShadows ? 1.0f : 0.0f;
@@ -267,7 +265,7 @@ void SetupMainLightShadowReceiverConstants(CommandBuffer cmd, VisibleLight shado
267265
// enough so custom shaders might use it.
268266
cmd.SetGlobalVector(MainLightShadowConstantBuffer._ShadowmapSize, new Vector4(invShadowAtlasWidth,
269267
invShadowAtlasHeight,
270-
m_ShadowmapWidth, m_ShadowmapHeight));
268+
renderTargetWidth, renderTargetHeight));
271269
}
272270
}
273271
};

com.unity.render-pipelines.universal/Runtime/Passes/ScriptableRenderPass.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections;
33
using System.Collections.Generic;
44
using System.ComponentModel;
5+
using Unity.Collections;
56
using UnityEngine.Scripting.APIUpdating;
67
using UnityEngine.Experimental.Rendering;
78

@@ -201,7 +202,10 @@ public Color clearColor
201202
internal bool depthOnly { get; set; }
202203
// this flag is updated each frame to keep track of which pass is the last for the current camera
203204
internal bool isLastPass { get; set; }
205+
// index to track the position in the current frame
206+
internal int renderPassQueueIndex { get; set; }
204207

208+
internal NativeArray<int> m_InputAttachmentIndices;
205209

206210
internal GraphicsFormat[] renderTargetFormat { get; set; }
207211
RenderTargetIdentifier[] m_ColorAttachments = new RenderTargetIdentifier[] {BuiltinRenderTextureType.CameraTarget};
@@ -228,6 +232,7 @@ public ScriptableRenderPass()
228232
renderTargetWidth = -1;
229233
renderTargetHeight = -1;
230234
renderTargetSampleCount = -1;
235+
renderPassQueueIndex = -1;
231236
renderTargetFormat = new GraphicsFormat[]
232237
{
233238
GraphicsFormat.None, GraphicsFormat.None, GraphicsFormat.None,

com.unity.render-pipelines.universal/Runtime/RendererFeatures/RenderObjects.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,10 @@ public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingD
9292
{
9393
renderer.EnqueuePass(renderObjectsPass);
9494
}
95+
96+
internal override bool SupportsNativeRenderPass()
97+
{
98+
return true;
99+
}
95100
}
96101
}

com.unity.render-pipelines.universal/Runtime/RenderingUtils.cs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -349,20 +349,6 @@ internal static uint GetValidColorBufferCount(RenderTargetIdentifier[] colorBuff
349349
return nonNullColorBuffers;
350350
}
351351

352-
internal static uint GetValidColorAttachmentCount(AttachmentDescriptor[] colorAttachments)
353-
{
354-
uint nonNullColorBuffers = 0;
355-
if (colorAttachments != null)
356-
{
357-
foreach (var attachment in colorAttachments)
358-
{
359-
if (attachment != RenderingUtils.emptyAttachment)
360-
++nonNullColorBuffers;
361-
}
362-
}
363-
return nonNullColorBuffers;
364-
}
365-
366352
/// <summary>
367353
/// Return true if colorBuffers is an actual MRT setup
368354
/// </summary>

0 commit comments

Comments
 (0)