-
Notifications
You must be signed in to change notification settings - Fork 870
Expand file tree
/
Copy pathBaseCommandBufer.cs
More file actions
144 lines (129 loc) · 8.52 KB
/
Copy pathBaseCommandBufer.cs
File metadata and controls
144 lines (129 loc) · 8.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System;
using System.Diagnostics;
using UnityEngine.Rendering.RenderGraphModule;
namespace UnityEngine.Rendering
{
/// <summary>
/// Render graph command buffer types inherit from this base class.
/// It provides some shared functionality for all command buffer types.
/// </summary>
public class BaseCommandBuffer
{
/// <summary>
/// The instance of Unity's CommandBuffer that this class encapsulates, providing access to lower-level rendering commands.
/// </summary>
protected internal CommandBuffer m_WrappedCommandBuffer;
internal RenderGraphPass m_ExecutingPass;
// Users cannot directly create command buffers. The rendergraph creates them and passes them to callbacks.
internal BaseCommandBuffer(CommandBuffer wrapped, RenderGraphPass executingPass, bool isAsync)
{
m_WrappedCommandBuffer = wrapped;
m_ExecutingPass = executingPass;
if (isAsync) m_WrappedCommandBuffer.SetExecutionFlags(CommandBufferExecutionFlags.AsyncCompute);
}
///<summary>See (https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer-name.html)</summary>
public string name => m_WrappedCommandBuffer.name;
///<summary>See (https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer-sizeInBytes.html)</summary>
public int sizeInBytes => m_WrappedCommandBuffer.sizeInBytes;
/// <summary>
/// Checks if modifying the global state is permitted by the currently executing render graph pass.
/// If such modifications are not allowed, an InvalidOperationException is thrown.
/// </summary>
/// <exception cref="InvalidOperationException">
/// Thrown if the current render graph pass does not permit modifications to global state.
/// </exception>
[Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")]
protected internal void ThrowIfGlobalStateNotAllowed()
{
if (m_ExecutingPass != null && !m_ExecutingPass.allowGlobalState) throw new InvalidOperationException($"{m_ExecutingPass.name}: Modifying global state from this command buffer is not allowed. Please ensure your render graph pass allows modifying global state.");
}
/// <summary>
/// Checks if the Raster Command Buffer has set a valid render target.
/// </summary>
/// <exception cref="InvalidOperationException">Thrown if the there are no active render targets.</exception>
[Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")]
protected internal void ThrowIfRasterNotAllowed()
{
if (m_ExecutingPass != null && !m_ExecutingPass.HasRenderAttachments()) throw new InvalidOperationException($"{m_ExecutingPass.name}: Using raster commands from a pass with no active render target is not allowed as it will use an undefined render target state. Please set up pass render targets using SetRenderAttachments.");
}
/// <summary>
/// Ensures that the texture handle being used is valid for the currently executing render graph pass.
/// This includes checks to ensure that the texture handle is registered for read or write access
/// and is not being used incorrectly as a render target attachment.
/// </summary>
/// <param name="h">The TextureHandle to validate for the current pass.</param>
/// <exception cref="Exception">
/// Throws an exception if the texture handle is not properly registered for the pass or being used incorrectly.
/// </exception>
[Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")]
protected internal void ValidateTextureHandle(TextureHandle h)
{
if(RenderGraph.enableValidityChecks)
{
if (m_ExecutingPass == null) return;
if (h.IsBuiltin()) return;
if (!m_ExecutingPass.IsRead(h.handle) && !m_ExecutingPass.IsWritten(h.handle) && !m_ExecutingPass.IsTransient(h.handle))
{
throw new Exception($"Pass '{m_ExecutingPass.name}' is trying to bind a texture on the command buffer that is not registered by its builder. Please indicate to the pass builder how the texture is used (UseTexture/CreateTransientTexture).");
}
if (m_ExecutingPass.IsAttachment(h))
{
throw new Exception($"Pass '{m_ExecutingPass.name}' is trying to bind a texture on the command buffer that is already set as a fragment attachment (SetRenderAttachment/SetRenderAttachmentDepth). A texture cannot be used as both in one pass, please fix its usage in the pass builder.");
}
}
}
/// <summary>
/// Validates that the specified texture handle is registered for read access within the context of the current executing render graph pass.
/// Throws an exception if the texture is not registered for reading or is used incorrectly as a render target attachment.
/// </summary>
/// <param name="h">The TextureHandle to validate for read access.</param>
/// <exception cref="Exception">
/// Throws an exception if the texture handle is either not registered as a readable resource or misused as both an attachment and a regular texture.
/// </exception>
[Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")]
protected internal void ValidateTextureHandleRead(TextureHandle h)
{
if (RenderGraph.enableValidityChecks)
{
if (m_ExecutingPass == null) return;
if (!m_ExecutingPass.IsRead(h.handle) && !m_ExecutingPass.IsTransient(h.handle))
{
throw new Exception($"Pass '{m_ExecutingPass.name}' is trying to read a texture on the command buffer that is not registered by its builder. Please indicate to the pass builder that the texture is read (UseTexture/CreateTransientTexture).");
}
if (m_ExecutingPass.IsAttachment(h))
{
throw new Exception($"Pass '{m_ExecutingPass.name}' is trying to bind a texture on the command buffer that is already set as a fragment attachment (SetRenderAttachment/SetRenderAttachmentDepth). A texture cannot be used as both in one pass, please fix its usage in the pass builder.");
}
}
}
/// <summary>
/// Validates that the specified texture handle is registered for write access within the context of the current executing render graph pass.
/// Additionally, it checks that built-in textures are not being written to, and that the texture is not incorrectly used as a render target attachment.
/// An exception is thrown if any of these checks fail.
/// </summary>
/// <param name="h">The TextureHandle to validate for write access.</param>
/// <exception cref="Exception">
/// Throws an exception if the texture handle is not registered for writing, attempts to write to a built-in texture, or is misused as both a writeable resource and a render target attachment.
/// </exception>
[Conditional("DEVELOPMENT_BUILD"), Conditional("UNITY_EDITOR")]
protected internal void ValidateTextureHandleWrite(TextureHandle h)
{
if(RenderGraph.enableValidityChecks)
{
if (m_ExecutingPass == null) return;
if (h.IsBuiltin())
{
throw new Exception("Pass '" + m_ExecutingPass.name + "' is trying to write to a built-in texture. This is not allowed built-in textures are small default resources like `white` or `black` that cannot be written to.");
}
if (!m_ExecutingPass.IsWritten(h.handle) && !m_ExecutingPass.IsTransient(h.handle))
{
throw new Exception($"Pass '{m_ExecutingPass.name}' is trying to write a texture on the command buffer that is not registered by its builder. Please indicate to the pass builder that the texture is written (UseTexture/CreateTransientTexture).");
}
if (m_ExecutingPass.IsAttachment(h))
{
throw new Exception($"Pass '{m_ExecutingPass.name}' is trying to bind a texture on the command buffer that is already set as a fragment attachment (SetRenderAttachment/SetRenderAttachmentDepth). A texture cannot be used as both in one pass, please fix its usage in the pass builder.");
}
}
}
}
}