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