Skip to content

Commit

Permalink
Merge pull request #7997 from Unity-Technologies/internal/master
Browse files Browse the repository at this point in the history
Internal/master
  • Loading branch information
UnityAljosha authored Nov 21, 2023
2 parents 9511b1d + 4180048 commit dde8846
Show file tree
Hide file tree
Showing 721 changed files with 74,637 additions and 10,649 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This document describes the main principles of a render graph and an overview of

## Main principles

Before you can write render passes with the [RenderGraph](../api/UnityEngine.Experimental.Rendering.RenderGraphModule.RenderGraph.html) API, you need to know the following foundational principles:
Before you can write render passes with the [RenderGraph](../api/UnityEngine.Rendering.RenderGraphModule.RenderGraph.html) API, you need to know the following foundational principles:

- You no longer handle resources directly and instead use render graph system-specific handles. All RenderGraph APIs use these handles to manipulate resources. The resource types a render graph manages are [RTHandles](rthandle-system.md), [ComputeBuffers](https://docs.unity3d.com/ScriptReference/ComputeBuffer.html), and [RendererLists](../api/UnityEngine.Experimental.Rendering.RendererList.html).
- Actual resource references are only accessible within the execution code of a render pass.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@

The render graph system sits on top of Unity's Scriptable Render Pipeline (SRP). It allows you to author a custom SRP in a maintainable and modular way. Unity's High Definition Render Pipeline (HDRP) uses the render graph system.

You use the [RenderGraph](../api/UnityEngine.Experimental.Rendering.RenderGraphModule.RenderGraph.html) API to create a render graph. A render graph is a high-level representation of the custom SRP's render passes, which explicitly states how the render passes use resources.
You use the [RenderGraph](../api/UnityEngine.Rendering.RenderGraphModule.RenderGraph.html) API to create a render graph. A render graph is a high-level representation of the custom SRP's render passes, which explicitly states how the render passes use resources.

Describing render passes in this way has two benefits: it simplifies render pipeline configuration, and it allows the render graph system to efficiently manage parts of the render pipeline, which can result in improved runtime performance. For more information on the benefits of the render graph system, see [benefits of the render graph system](render-graph-benefits.md).

To use the render graph system, you need to write your code in a different way to a regular custom SRP. For more information on how to write code for the render graph system, see [writing a render pipeline](render-graph-writing-a-render-pipeline.md).

For information on the technical principles behind the render graph system, see [render graph fundamentals](render-graph-fundamentals.md).

**Note**: Render graph is currently experimental which means Unity might change its API during future development.

This section contains the following pages:

- [Render graph benefits](render-graph-benefits.md)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ This page covers the process of how to use the RenderGraph API to write a render

### Initialization and cleanup of Render Graph

To begin, your render pipeline needs to maintain at least one instance of [RenderGraph](../api/UnityEngine.Experimental.Rendering.RenderGraphModule.RenderGraph.html). This is the main entry point for the API. You can use more than one instance of a render graph, but be aware that Unity does not share resources across `RenderGraph` instances so for optimal memory usage, only use one instance.
To begin, your render pipeline needs to maintain at least one instance of [RenderGraph](../api/UnityEngine.Rendering.RenderGraphModule.RenderGraph.html). This is the main entry point for the API. You can use more than one instance of a render graph, but be aware that Unity does not share resources across `RenderGraph` instances so for optimal memory usage, only use one instance.

```c#
using UnityEngine.Experimental.Rendering.RenderGraphModule;
using UnityEngine.Rendering.RenderGraphModule;

public class MyRenderPipeline : RenderPipeline
{
Expand All @@ -30,22 +30,21 @@ To initialize a `RenderGraph` instance, call the constructor with an optional na

### Starting a render graph

Before you add any render passes to the render graph, you first need to initialize the render graph. To do this, call the `RecordAndExecute` method. This method will return a disposable struct of type `RenderGraphExecution` that you can use with a scope. When the `RenderGraphExecution` struct exits the scope or its Dispose function is called, the render graph is executed.
This pattern ensures that the render graph is always executed correctly even in the case of an exception during the recording of the graph.
For details about this method's parameters, see the [API documentation](../api/UnityEngine.Experimental.Rendering.RenderGraphModule.RenderGraph.html)
Before you add any render passes to the render graph, you first need to initialize the render graph by calling the `BeginRecording` method. Once all the render passes have been added to the render graph, you can execute it by calling the `EndRecordingAndExecute` method.

For details about the `BeginRecording` method's parameters, see the [API documentation](../api/UnityEngine.Rendering.RenderGraphModule.RenderGraph.html)

```c#
var renderGraphParams = new RenderGraphExecuteParams()
var renderGraphParams = new RenderGraphParameters()
{
scriptableRenderContext = renderContext,
commandBuffer = cmd,
currentFrameIndex = frameIndex
};

using (m_RenderGraph.RecordAndExecute(renderGraphParams))
{
// Add your passes here
}
m_RenderGraph.BeginRecording(renderGraphParams);
// Add your passes here
m_RenderGraph.EndRecordingAndExecute();
```

### Creating resources for the render graph
Expand All @@ -69,7 +68,7 @@ public TextureHandle RenderGraph.ImportBackbuffer(RenderTargetIdentifier rt);
public BufferHandle RenderGraph.ImportBuffer(ComputeBuffer computeBuffer);
```

The main ways to create resources are described above, but there are variations of these functions. For the complete list, see the [API documentation](../api/UnityEngine.Experimental.Rendering.RenderGraphModule.RenderGraph.html). Note that the specific function to use to import the camera back buffer is `RenderTargetIdentifier`.
The main ways to create resources are described above, but there are variations of these functions. For the complete list, see the [API documentation](../api/UnityEngine.Rendering.RenderGraphModule.RenderGraph.html). Note that the specific function to use to import the camera back buffer is `RenderTargetIdentifier`.

To create resources, each API requires a descriptor structure as a parameter. The properties in these structures are similar to the properties in the resources they represent (respectively [RTHandle](rthandle-system.md), [ComputeBuffer](https://docs.unity3d.com/ScriptReference/ComputeBuffer.html), and [RendererLists](../api/UnityEngine.Experimental.Rendering.RendererList.html)). However, some properties are specific to render graph textures.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,38 @@

namespace UnityEditor.Rendering
{
class CoreBuildData : IDisposable
/// <summary>
/// Contains a set of needed data for building.
/// This might also being called when building Asset Bundles
/// </summary>
public class CoreBuildData : IDisposable
{
static CoreBuildData m_Instance = null;

/// <summary>
/// Instance to the current <see cref="CoreBuildData"/>.
/// </summary>
public static CoreBuildData instance => m_Instance ??= CreateInstance();

/// <summary>
/// If the target build has an SRP configured
/// </summary>
public bool buildingPlayerForRenderPipeline { get; private set; } = false;

/// <summary>
/// A valid type of <see cref="RenderPipelineAsset"/>, that the build is targeting,
/// </summary>
public Type currentRenderPipelineAssetType { get; private set; } = null;

/// <summary>
/// A list of <see cref="RenderPipelineAsset"/>, all of them of the same type.
/// </summary>
public List<RenderPipelineAsset> renderPipelineAssets { get; private set; } = new();
public Dictionary<int, ComputeShader> computeShaderCache { get; private set; } = new();

public bool pipelineSupportGPUResidentDrawer { get; private set; } = false;
public bool playerNeedGPUResidentDrawer { get; private set; } = false;
internal Dictionary<int, ComputeShader> computeShaderCache { get; private set; } = new();

internal bool pipelineSupportGPUResidentDrawer { get; private set; } = false;
internal bool playerNeedGPUResidentDrawer { get; private set; } = false;

private CoreBuildData(BuildTarget buildTarget)
{
Expand All @@ -27,16 +48,20 @@ private CoreBuildData(BuildTarget buildTarget)

buildingPlayerForRenderPipeline = true;

CheckGPUResidentDrawerUsage();
//We can check only the first as we don't support multiple pipeline type in player
var asset = renderPipelineAssets[0];
currentRenderPipelineAssetType = asset.GetType();

CheckGPUResidentDrawerUsage(asset);
}

public static CoreBuildData CreateInstance()
private static CoreBuildData CreateInstance()
=> new(EditorUserBuildSettings.activeBuildTarget);

private void CheckGPUResidentDrawerUsage()
private void CheckGPUResidentDrawerUsage(RenderPipelineAsset asset)
{
//We can check only the first as we don't support multiple pipeline type in player
pipelineSupportGPUResidentDrawer = renderPipelineAssets[0] is IGPUResidentRenderPipeline gpuResidentRenderPipeline && gpuResidentRenderPipeline.IsGPUResidentDrawerSupportedBySRP();
pipelineSupportGPUResidentDrawer = asset is IGPUResidentRenderPipeline gpuResidentRenderPipeline && gpuResidentRenderPipeline.IsGPUResidentDrawerSupportedBySRP();
if (!pipelineSupportGPUResidentDrawer)
return;

Expand All @@ -54,11 +79,14 @@ private void CheckGPUResidentDrawerUsage()
.ForEachFieldOfType<ComputeShader>(computeShader => computeShaderCache.Add(computeShader.GetInstanceID(), computeShader));
}

/// <summary>
/// Dispose all the gathered data for building
/// </summary>
public void Dispose()
{
renderPipelineAssets?.Clear();
computeShaderCache?.Clear();
m_Instance = null;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class CorePreprocessBuild : IPreprocessBuildWithReport, IPostprocessBuildWithRep
void IPreprocessBuildWithReport.OnPreprocessBuild(BuildReport report)
{
m_BuildData?.Dispose();
m_BuildData = CoreBuildData.CreateInstance();
m_BuildData = CoreBuildData.instance;
}

void IPostprocessBuildWithReport.OnPostprocessBuild(BuildReport report)
Expand Down
Loading

0 comments on commit dde8846

Please sign in to comment.