Skip to content
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b4b6edf
initial store and load action SRP support
manuele-bonanno Apr 7, 2021
5c53798
removed depth prepass related temporary changes
manuele-bonanno Apr 8, 2021
6233c18
removing commented out code
manuele-bonanno Apr 8, 2021
1a77378
removing unused variables
manuele-bonanno Apr 8, 2021
03504e3
Added Store Actions settings
manuele-bonanno Apr 12, 2021
a6f59ed
moved the code that checks for injected passes
manuele-bonanno Apr 13, 2021
af2ecba
cleanup and addressing reviewer's feedback
manuele-bonanno Apr 13, 2021
1a9ce7f
Merge branch 'master' into urp/msaa_store_actions_optimization
manuele-bonanno Apr 13, 2021
1ee51a6
moved the "Store Actions" setting in the Advanced options section
manuele-bonanno Apr 13, 2021
8e95a89
further depth store action optimization for when MSAA is disabled
manuele-bonanno Apr 13, 2021
f2e7ec3
Added changelog entry
manuele-bonanno Apr 13, 2021
cc6422b
Added documentation
manuele-bonanno Apr 13, 2021
0b2d3a1
handling the opaque pass depth store actions separately for a more op…
manuele-bonanno Apr 14, 2021
701f703
Merge branch 'master' into urp/msaa_store_actions_optimization
manuele-bonanno Apr 15, 2021
f07f748
if "Store Actions"=Store, make sure to preserve and StoreAndResolve a…
manuele-bonanno Apr 15, 2021
de91e70
addressed reviewers feedback
manuele-bonanno Apr 16, 2021
060261b
added new API docs as requested by reviewers
manuele-bonanno Apr 16, 2021
cd25137
Added storeActionsOptimization property setter after reviewer's feedback
manuele-bonanno Apr 16, 2021
1bd8a24
the opaqueColorStoreAction should be StoreAndResolve only if copy col…
manuele-bonanno Apr 16, 2021
4e300f6
renamed parameter of CoreUtils.SetRenderTarget after reviewer's feedback
manuele-bonanno Apr 19, 2021
9761545
updated the tooltip after reviewer's feedback
manuele-bonanno Apr 19, 2021
887eb25
Merge branch 'master' into urp/msaa_store_actions_optimization
manuele-bonanno Apr 20, 2021
6b1315f
removed using System.ComponentModel.Design.Serialization; line added …
manuele-bonanno Apr 21, 2021
facbf42
removing files accidentally added by a previous merge
manuele-bonanno Apr 21, 2021
507291d
Edited the __Store Actions__ description.
oleks-k Apr 26, 2021
71e9011
Edited the StoreActionsOptimization API descriptions.
oleks-k Apr 26, 2021
b46f66a
Merge branch 'master' into urp/msaa_store_actions_optimization
manuele-bonanno Apr 26, 2021
23694e6
Merge branch 'master' into urp/msaa_store_actions_optimization
manuele-bonanno Apr 27, 2021
39b1394
editor test fix
manuele-bonanno Apr 27, 2021
497777f
Merge branch 'master' into urp/msaa_store_actions_optimization
phi-lira Apr 28, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions com.unity.render-pipelines.core/Runtime/Utilities/CoreUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,24 @@ public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier col
ClearRenderTarget(cmd, clearFlag, clearColor);
}

/// <summary>
/// Set the current render texture.
/// </summary>
/// <param name="cmd">CommandBuffer used for rendering commands.</param>
/// <param name="buffer">RenderTargetIdentifier of the render texture.</param>
/// <param name="colorLoadAction">Color buffer load action.</param>
/// <param name="colorStoreAction">Color buffer store action.</param>
/// <param name="depthLoadAction">Depth buffer load action.</param>
/// <param name="depthStoreAction">Depth buffer store action.</param>
/// <param name="clearFlag">If not set to ClearFlag.None, specifies how to clear the render target after setup.</param>
/// <param name="clearColor">If applicable, color with which to clear the render texture after setup.</param>
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier buffer, RenderBufferLoadAction colorLoadAction, RenderBufferStoreAction colorStoreAction,
RenderBufferLoadAction depthLoadAction, RenderBufferStoreAction depthStoreAction, ClearFlag clearFlag, Color clearColor)
{
cmd.SetRenderTarget(buffer, colorLoadAction, colorStoreAction, depthLoadAction, depthStoreAction);
ClearRenderTarget(cmd, clearFlag, clearColor);
}

/// <summary>
/// Set the current render texture.
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions com.unity.render-pipelines.universal/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Added _SURFACE_TYPE_TRANSPARENT keyword to URP shaders.
- Added Depth and DepthNormals passes to particles shaders.
- Added support for SSAO in Particle and Unlit shaders.
- Added 'Store Actions' option that enables bandwidth optimizations on mobile GPU architectures.

### Changed
- Moved fog evaluation from vertex shader to pixel shader. This improves rendering of fog for big triangles and fog quality. This can change the look of the fog slightly.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ This section allows you to fine-tune less commonly changed settings, which impac
| __Mixed Lighting__ | Enable [Mixed Lighting](https://docs.unity3d.com/Manual/LightMode-Mixed.html), to tell the pipeline to include mixed lighting shader variants in the build. |
| __Debug Level__ | Set the level of debug information that the render pipeline generates. The values are:<br />**Disabled**: Debugging is disabled. This is the default.<br />**Profiling**: Makes the render pipeline provide detailed information tags, which you can see in the FrameDebugger. |
| __Shader Variant Log Level__ | Set the level of information about Shader Stripping and Shader Variants you want to display when Unity finishes a build. Values are:<br /> **Disabled**: Unity doesn’t log anything.<br />**Only Universal**: Unity logs information for all of the [URP Shaders](shaders-in-universalrp.md).<br />**All**: Unity logs information for all Shaders in your build.<br /> You can see the information in Console panel when your build has finished. |

| __Store Actions__ | Defines the policy used when setting store actions for the DrawObjects passes. It has a great impact on bandwidth on mobile and tile based GPUs. <br/>__Auto__: Behaves like the Discard option. If any injected passes are detected will then fall back to Store. <br/>__Discard__: Targets of passes which are not re-used later in the frame will be discarded (optimal). <br/>__Store__: Store all the targets of each pass (non optimal). |


### Adaptive Performance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ internal class Styles
public static GUIContent mixedLightingSupportLabel = EditorGUIUtility.TrTextContent("Mixed Lighting", "Makes the render pipeline include mixed-lighting Shader Variants in the build.");
public static GUIContent debugLevel = EditorGUIUtility.TrTextContent("Debug Level", "Controls the level of debug information generated by the render pipeline. When Profiling is selected, the pipeline provides detailed profiling tags.");
public static GUIContent shaderVariantLogLevel = EditorGUIUtility.TrTextContent("Shader Variant Log Level", "Controls the level logging in of shader variants information is outputted when a build is performed. Information will appear in the Unity console when the build finishes.");
public static GUIContent storeActionsOptimizationText = EditorGUIUtility.TrTextContent("Store Actions", "Sets the store actions policy on tile based GPUs. Affects render targets memory usage and will impact performance.");

// Adaptive performance settings
public static GUIContent useAdaptivePerformance = EditorGUIUtility.TrTextContent("Use adaptive performance", "Allows Adaptive Performance to adjust rendering quality during runtime");
Expand Down Expand Up @@ -113,6 +114,7 @@ internal class Styles
SerializedProperty m_RequireOpaqueTextureProp;
SerializedProperty m_OpaqueDownsamplingProp;
SerializedProperty m_SupportsTerrainHolesProp;
SerializedProperty m_StoreActionsOptimizationProperty;

SerializedProperty m_HDR;
SerializedProperty m_MSAA;
Expand Down Expand Up @@ -229,6 +231,8 @@ void OnEnable()

m_ShaderVariantLogLevel = serializedObject.FindProperty("m_ShaderVariantLogLevel");

m_StoreActionsOptimizationProperty = serializedObject.FindProperty("m_StoreActionsOptimization");

m_ColorGradingMode = serializedObject.FindProperty("m_ColorGradingMode");
m_ColorGradingLutSize = serializedObject.FindProperty("m_ColorGradingLutSize");

Expand Down Expand Up @@ -610,6 +614,7 @@ void DrawAdvancedSettings()
EditorGUILayout.PropertyField(m_MixedLightingSupportedProp, Styles.mixedLightingSupportLabel);
EditorGUILayout.PropertyField(m_DebugLevelProp, Styles.debugLevel);
EditorGUILayout.PropertyField(m_ShaderVariantLogLevel, Styles.shaderVariantLogLevel);
EditorGUILayout.PropertyField(m_StoreActionsOptimizationProperty, Styles.storeActionsOptimizationText);
EditorGUI.indentLevel--;
EditorGUILayout.Space();
EditorGUILayout.Space();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,19 @@ public enum ColorGradingMode
HighDynamicRange
}

/// <summary>
/// Defines the policy used when setting store actions for the DrawObjects passes. It has a great impact on bandwidth on tile based GPUs.
/// </summary>
public enum StoreActionsOptimization
{
/// <summary> Behaves like the Discard option. If any injected passes are detected will then fall back to Store. </summary>
Auto,
/// <summary> Targets of passes which are not re-used later in the frame will be discarded (optimal). </summary>
Discard,
/// <summary> Store all the targets of each pass (non optimal). </summary>
Store
}

[ExcludeFromPreset]
public partial class UniversalRenderPipelineAsset : RenderPipelineAsset, ISerializationCallbackReceiver
{
Expand All @@ -111,6 +124,7 @@ public partial class UniversalRenderPipelineAsset : RenderPipelineAsset, ISerial
[SerializeField] bool m_RequireOpaqueTexture = false;
[SerializeField] Downsampling m_OpaqueDownsampling = Downsampling._2xBilinear;
[SerializeField] bool m_SupportsTerrainHoles = true;
[SerializeField] StoreActionsOptimization m_StoreActionsOptimization = StoreActionsOptimization.Auto;

// Quality settings
[SerializeField] bool m_SupportsHDR = true;
Expand Down Expand Up @@ -513,6 +527,16 @@ public bool supportsTerrainHoles
get { return m_SupportsTerrainHoles; }
}

/// <summary>
/// Returns the active store action optimization value.
/// </summary>
/// <returns>Returns the active store action optimization value.</returns>
public StoreActionsOptimization storeActionsOptimization
{
get { return m_StoreActionsOptimization; }
set { m_StoreActionsOptimization = value; }
}

public bool supportsHDR
{
get { return m_SupportsHDR; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,16 @@ public RenderTargetIdentifier depthAttachment
get => m_DepthAttachment;
}

public RenderBufferStoreAction[] colorStoreActions
{
get => m_ColorStoreActions;
}

public RenderBufferStoreAction depthStoreAction
{
get => m_DepthStoreAction;
}

/// <summary>
/// The input requirements for the <c>ScriptableRenderPass</c>, which has been set using <c>ConfigureInput</c>
/// </summary>
Expand All @@ -169,6 +179,9 @@ public Color clearColor
get => m_ClearColor;
}

RenderBufferStoreAction[] m_ColorStoreActions = new RenderBufferStoreAction[] { RenderBufferStoreAction.Store };
RenderBufferStoreAction m_DepthStoreAction = RenderBufferStoreAction.Store;
Comment on lines +183 to +184
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why not backing the entire attachemnt setup with something like https://docs.unity3d.com/ScriptReference/Rendering.RenderTargetBinding.html

I also find it weird that we provide StoreActions but don't expose LoadAction. If we don't think in terms of API completeness I feel like very soon someone might ask for Load actions as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in engine load actions are inferred based on the store actions setup, and this change or every API implementation. The only proper way right now to set load/store actions without having to fight built-in logic is to use the RenderPass API.

So while exposing the load actions here is easy, I am not sure they will have much effect in terms of determining the final store action used by the device. So there would be a lot of work needed to allow that. If it is important can be done as a future task, but from my experience the engine does a good job in figuring out the load actions and the main problems were introduced by wrong stores, so not sure the effort to have an explicit Load action API is worth it (also considering RenderPasses will do that)

I agree having only stores exposed in the API makes it feel limited, but if we want load actions too then it might involve lot of extra work. Future PRs could address it if really needed. WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. sounds good to me and fair justification.


/// <summary>
/// A ProfilingSampler for the entire render pass. Used as a profiling name by <c>ScriptableRenderer</c> when executing the pass.
/// Default is <c>Unnamed_ScriptableRenderPass</c>.
Expand Down Expand Up @@ -201,6 +214,8 @@ public ScriptableRenderPass()
renderPassEvent = RenderPassEvent.AfterRenderingOpaques;
m_ColorAttachments = new RenderTargetIdentifier[] {BuiltinRenderTextureType.CameraTarget, 0, 0, 0, 0, 0, 0, 0};
m_DepthAttachment = BuiltinRenderTextureType.CameraTarget;
m_ColorStoreActions = new RenderBufferStoreAction[] { RenderBufferStoreAction.Store, 0, 0, 0, 0, 0, 0, 0 };
m_DepthStoreAction = RenderBufferStoreAction.Store;
m_ClearFlag = ClearFlag.None;
m_ClearColor = Color.black;
overrideCameraTarget = false;
Expand Down Expand Up @@ -229,6 +244,25 @@ public void ConfigureInput(ScriptableRenderPassInput passInput)
m_Input = passInput;
}

public void ConfigureColorStoreAction(RenderBufferStoreAction storeAction, uint attachmentIndex = 0)
{
m_ColorStoreActions[attachmentIndex] = storeAction;
}

public void ConfigureColorStoreActions(RenderBufferStoreAction[] storeActions)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing public API

{
int count = Math.Min(storeActions.Length, m_ColorStoreActions.Length);
for (uint i = 0; i < count; ++i)
{
m_ColorStoreActions[i] = storeActions[i];
}
}

public void ConfigureDepthStoreAction(RenderBufferStoreAction storeAction)
{
m_DepthStoreAction = storeAction;
}

/// <summary>
/// Configures render targets for this render pass. Call this instead of CommandBuffer.SetRenderTarget.
/// This method should be called inside Configure.
Expand Down
63 changes: 60 additions & 3 deletions com.unity.render-pipelines.universal/Runtime/ScriptableRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,9 @@ static class RenderPassBlock
public static readonly int AfterRendering = 3;
}

private StoreActionsOptimization m_StoreActionsOptimizationSetting = StoreActionsOptimization.Auto;
private static bool m_UseOptimizedStoreActions = false;

const int k_RenderPassBlockCount = 4;

List<ScriptableRenderPass> m_ActiveRenderPassQueue = new List<ScriptableRenderPass>(32);
Expand All @@ -423,6 +426,14 @@ static class RenderPassBlock
static RenderTargetIdentifier[] m_ActiveColorAttachments = new RenderTargetIdentifier[] {0, 0, 0, 0, 0, 0, 0, 0 };
static RenderTargetIdentifier m_ActiveDepthAttachment;

private static RenderBufferStoreAction[] m_ActiveColorStoreActions = new RenderBufferStoreAction[]
{
RenderBufferStoreAction.Store, RenderBufferStoreAction.Store, RenderBufferStoreAction.Store, RenderBufferStoreAction.Store,
RenderBufferStoreAction.Store, RenderBufferStoreAction.Store, RenderBufferStoreAction.Store, RenderBufferStoreAction.Store
};

private static RenderBufferStoreAction m_ActiveDepthStoreAction = RenderBufferStoreAction.Store;

static AttachmentDescriptor[] m_ActiveColorAttachmentDescriptors = new AttachmentDescriptor[]
{
RenderingUtils.emptyAttachment, RenderingUtils.emptyAttachment, RenderingUtils.emptyAttachment,
Expand Down Expand Up @@ -477,6 +488,9 @@ public ScriptableRenderer(ScriptableRendererData data)
useRenderPassEnabled = data.useNativeRenderPass;
Clear(CameraRenderType.Base);
m_ActiveRenderPassQueue.Clear();

m_StoreActionsOptimizationSetting = UniversalRenderPipeline.asset.storeActionsOptimization;
m_UseOptimizedStoreActions = m_StoreActionsOptimizationSetting != StoreActionsOptimization.Store;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StoreActionsOptimization.Store should also remove store optimization from other passes like post-processing imo.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure I understand what you mean?
Currently StoreActionsOptimization.Store will remove optimization from all the passes going through the new SetRenderTarget API that explicitely sets the store actions. So any passes using that new interface will be affected. Right now that is only the DrawOpaque and DrawTransparent passes, but it is extensible to other passes in the future including post processing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PostProcessingPass.cs has some optimizations to load and store with SetRenderTarget. F.ex, I think we never store depth after post but some users asked for it. I was asking if these settings should affect those optimizations we already have there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes that sounds like a good idea. This PR is focusing on the opaque/transparent passes on top of introducing the new API. But extending the optimization options to other passes in future PRs sounds trivial (should be a matter of making sure that the new explicit actions API is called by the postproc pass)

}

public void Dispose()
Expand Down Expand Up @@ -802,6 +816,10 @@ protected void AddRenderPasses(ref RenderingData renderingData)
if (activeRenderPassQueue[i] == null)
activeRenderPassQueue.RemoveAt(i);
}

// if any pass was injected, the "automatic" store optimization policy will disable the optimized load actions
if (count > 0 && m_StoreActionsOptimizationSetting == StoreActionsOptimization.Auto)
m_UseOptimizedStoreActions = false;
}

void ClearRenderingState(CommandBuffer cmd)
Expand Down Expand Up @@ -1193,9 +1211,10 @@ void SetRenderPassAttachments(CommandBuffer cmd, ScriptableRenderPass renderPass
else
{
// Only setup render target if current render pass attachments are different from the active ones
if (passColorAttachment != m_ActiveColorAttachments[0] || passDepthAttachment != m_ActiveDepthAttachment || finalClearFlag != ClearFlag.None)
if (passColorAttachment != m_ActiveColorAttachments[0] || passDepthAttachment != m_ActiveDepthAttachment || finalClearFlag != ClearFlag.None ||
renderPass.colorStoreActions[0] != m_ActiveColorStoreActions[0] || renderPass.depthStoreAction != m_ActiveDepthStoreAction)
{
SetRenderTarget(cmd, passColorAttachment, passDepthAttachment, finalClearFlag, finalClearColor);
SetRenderTarget(cmd, passColorAttachment, passDepthAttachment, finalClearFlag, finalClearColor, renderPass.colorStoreActions[0], renderPass.depthStoreAction);

#if ENABLE_VR && ENABLE_XR_MODULE
if (cameraData.xr.enabled)
Expand Down Expand Up @@ -1243,6 +1262,11 @@ internal static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier c
for (int i = 1; i < m_ActiveColorAttachments.Length; ++i)
m_ActiveColorAttachments[i] = 0;

m_ActiveColorStoreActions[0] = RenderBufferStoreAction.Store;
m_ActiveDepthStoreAction = RenderBufferStoreAction.Store;
for (int i = 1; i < m_ActiveColorStoreActions.Length; ++i)
m_ActiveColorStoreActions[i] = RenderBufferStoreAction.Store;

m_ActiveDepthAttachment = depthAttachment;

RenderBufferLoadAction colorLoadAction = ((uint)clearFlag & (uint)ClearFlag.Color) != 0 ?
Expand All @@ -1255,6 +1279,39 @@ internal static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier c
depthAttachment, depthLoadAction, RenderBufferStoreAction.Store, clearFlag, clearColor);
}

internal static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorAttachment, RenderTargetIdentifier depthAttachment, ClearFlag clearFlag, Color clearColor, RenderBufferStoreAction colorStoreAction, RenderBufferStoreAction depthStoreAction)
{
m_ActiveColorAttachments[0] = colorAttachment;
for (int i = 1; i < m_ActiveColorAttachments.Length; ++i)
m_ActiveColorAttachments[i] = 0;

m_ActiveColorStoreActions[0] = colorStoreAction;
m_ActiveDepthStoreAction = depthStoreAction;
for (int i = 1; i < m_ActiveColorStoreActions.Length; ++i)
m_ActiveColorStoreActions[i] = RenderBufferStoreAction.Store;
Comment on lines +1317 to +1324
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hooking up on the previous idea, if we used RenderTargetBinding we could configure it here once.


m_ActiveDepthAttachment = depthAttachment;

RenderBufferLoadAction colorLoadAction = ((uint)clearFlag & (uint)ClearFlag.Color) != 0 ?
RenderBufferLoadAction.DontCare : RenderBufferLoadAction.Load;

RenderBufferLoadAction depthLoadAction = ((uint)clearFlag & (uint)ClearFlag.Depth) != 0 ?
RenderBufferLoadAction.DontCare : RenderBufferLoadAction.Load;

// if we shouldn't use optimized store actions then fall back to the conservative safe (un-optimal!) route and just store everything
if (!m_UseOptimizedStoreActions)
{
if (colorStoreAction != RenderBufferStoreAction.StoreAndResolve)
colorStoreAction = RenderBufferStoreAction.Store;
if (depthStoreAction != RenderBufferStoreAction.StoreAndResolve)
depthStoreAction = RenderBufferStoreAction.Store;
}


SetRenderTarget(cmd, colorAttachment, colorLoadAction, colorStoreAction,
depthAttachment, depthLoadAction, depthStoreAction, clearFlag, clearColor);
}

static void SetRenderTarget(
CommandBuffer cmd,
RenderTargetIdentifier colorAttachment,
Expand All @@ -1280,7 +1337,7 @@ static void SetRenderTarget(
// XRTODO: Revisit the logic. Why treat CameraTarget depth specially?
if (depthAttachment == BuiltinRenderTextureType.CameraTarget)
{
SetRenderTarget(cmd, colorAttachment, colorLoadAction, colorStoreAction, clearFlags, clearColor);
CoreUtils.SetRenderTarget(cmd, colorAttachment, colorLoadAction, colorStoreAction, depthLoadAction, depthStoreAction, clearFlags, clearColor);
}
else
{
Expand Down
Loading