暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BaseCommandBufer.cs 8.1KB

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