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.
212 lines
14 KiB
212 lines
14 KiB
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using UnityEngine.Experimental.Rendering;
|
|
using UnityEngine.Rendering.RenderGraphModule.NativeRenderPassCompiler;
|
|
|
|
namespace UnityEngine.Rendering.RenderGraphModule
|
|
{
|
|
public partial class RenderGraph
|
|
{
|
|
internal static class RenderGraphExceptionMessages
|
|
{
|
|
internal static bool enableCaller = true;
|
|
|
|
internal const string k_RenderGraphExecutionError = "Render Graph Execution error";
|
|
|
|
static readonly Dictionary<RenderGraphState, string> m_RenderGraphStateMessages = new()
|
|
{
|
|
{
|
|
RenderGraphState.RecordingPass,
|
|
"This API cannot be called when Render Graph records a pass. Call the API within SetRenderFunc() or outside of AddUnsafePass()/AddComputePass()/AddRasterRenderPass()."
|
|
},
|
|
{
|
|
RenderGraphState.RecordingGraph,
|
|
"This API cannot be called during the Render Graph high-level recording step. Call the API within AddUnsafePass()/AddComputePass()/AddRasterRenderPass() or outside of RecordRenderGraph()."
|
|
},
|
|
{
|
|
RenderGraphState.RecordingPass | RenderGraphState.Executing,
|
|
"This API cannot be called when Render Graph records a pass or executes it. Call the API outside of AddUnsafePass()/AddComputePass()/AddRasterRenderPass()."
|
|
},
|
|
{
|
|
RenderGraphState.Executing,
|
|
"This API cannot be called during the Render Graph execution. Call the API outside of SetRenderFunc()."
|
|
},
|
|
{
|
|
RenderGraphState.Active,
|
|
"This API cannot be called when Render Graph is active. Call the API outside of RecordRenderGraph()."
|
|
}
|
|
};
|
|
|
|
// General Errors
|
|
const string k_ErrorDefaultMessage = "Invalid render graph state, impossible to log the exception.";
|
|
|
|
internal const string k_NonTextureAsAttachmentError = "Only textures can be used as a fragment attachment.";
|
|
|
|
// Compiler Context Data
|
|
internal const string k_OneResourceTwoVersionsError =
|
|
"A pass is using SetAttachment or UseTexture on two versions of the same resource. Make sure you only access the latest version.";
|
|
|
|
internal const string k_UseTextureRandWriteTwoVersionsError =
|
|
"A pass is using UseTextureRandomWrite on two versions of the same resource. Make sure you only access the latest version.";
|
|
|
|
// Passes Data
|
|
internal const string k_InvalidGetRenderTargetInfoResultsError =
|
|
"GetRenderTargetInfo returned invalid results. Check that the width, height, and number of MSAA samples is not 0.";
|
|
|
|
internal const string k_CannotDetermineSubPassFlagNoDepth =
|
|
"SubPassFlag for merging cannot be determined if native pass doesn't have a depth attachment. Make sure your pass has a depth attachment.";
|
|
|
|
internal const string k_AddingOlderAttachmentVersion = "The pass adds an older version while a higher version is already registered with the pass. Make sure you only access the latest version.";
|
|
|
|
// Users shouldn't be seeing these, they are a sort of catch for internal RG mistakes.
|
|
internal const string k_NonIncrementalCreationCall =
|
|
"Something went wrong when compiling the graph. The Creation lists must be set-up incrementally for all passes, but AddFirstUse is called in an arbitrary non-incremental way.";
|
|
|
|
internal const string k_NonIncrementalDestructionCall =
|
|
"Something went wrong when compiling the graph. The Destruction lists must be set-up incrementally for all passes, AddLastUse is called in an arbitrary non-incremental way.";
|
|
|
|
internal static string MismatchInDimensions(string name, int fragWidth, int fragHeight, int fragVolumeDepth,
|
|
ResourceUnversionedData resInfo)
|
|
=>
|
|
$"Mismatch in fragment dimensions when using resource '{name}'. Expected {fragWidth} x {fragHeight} x {fragVolumeDepth} " +
|
|
$"but got {resInfo.width} x {resInfo.height} x {resInfo.volumeDepth} instead.";
|
|
|
|
internal static string MismatchInMSAASamlpes(string name, int expectedSamples, int actualSamples)
|
|
{
|
|
var expectedSamplesString = expectedSamples == 1 ? "None" : expectedSamples.ToString();
|
|
var actualSamplesString = actualSamples == 1 ? "None" : actualSamples.ToString();
|
|
return $"Mismatch in number of MSAA samples when using resource '{name}'. Expected {expectedSamplesString} but got {actualSamplesString} instead.";
|
|
}
|
|
|
|
// RenderGraphBuilders
|
|
internal const string k_UndisposedBuilderPreviousPass =
|
|
"Finish building the previous pass first by disposing of the pass builder object before adding a new pass. You can manually dispose of the builder with 'builder.Dispose()'.";
|
|
|
|
internal const string k_WriteToVersionedResource =
|
|
"The pass writes to a versioned resource handle. You can only write to unversioned resource handles to avoid branches in the resource history.";
|
|
|
|
internal const string k_WriteToResourceTwice = "The pass writes to a resource twice. You can only write the same resource once within a pass.";
|
|
|
|
internal const string k_TextureAlreadyBeingUsedThroughSetAttachment =
|
|
"UseTexture is called on a texture that is already used through SetRenderAttachment. Check your code and make sure the texture is only used once.";
|
|
|
|
internal const string k_SetRenderAttachmentTextureAlreadyUsed =
|
|
"SetRenderAttachment is called on a texture that is already used through UseTexture/SetRenderAttachment. Check your code and make sure the texture is only used once.";
|
|
|
|
internal const string k_SetRenderAttachmentOnDepthTexture =
|
|
"SetRenderAttachment is called on a texture that has a depth format. Use a texture with a color format instead, or call SetRenderDepthAttachment.";
|
|
|
|
internal const string k_SetRenderAttachmentOnGlobalTexture =
|
|
"SetRenderAttachment is called on a texture that is currently bound to a global texture slot. Shaders might be using the texture using samplers. Make sure textures are not set as globals when using them as fragment attachments.";
|
|
|
|
internal const string k_InvalidResource = "Using an invalid resource. Invalid resources can be resources leftover from a previous execution.";
|
|
|
|
internal const string k_ReadWriteTransient =
|
|
"This pass is reading or writing a transient resource. Transient resources are always assumed to be both read and written using 'AccessFlags.ReadWrite'.";
|
|
|
|
internal static string NoGlobalTextureAtPropertyID(int propertyId) =>
|
|
$"This pass is trying to read the global texture property {propertyId} but no previous pass in the graph bound a value to this global.";
|
|
|
|
internal static string UseDepthWithColorFormat(GraphicsFormat colorFormat) =>
|
|
$"SetRenderAttachmentDepth is called on a texture that has a color format {colorFormat}. Use a texture with a depth format instead, or call SetRenderAttachment.";
|
|
|
|
internal static string UseTransientTextureInWrongPass(int transientIndex) =>
|
|
$"This pass is using a transient resource from a different pass (pass index {transientIndex}). A transient resource should only be used in a single pass.";
|
|
|
|
internal static string IncompatibleTextureUVOrigin(TextureUVOriginSelection origin, string attachmentType, string attachmentName, RenderGraphResourceType attachmentResourceType, int attachmentResourceIndex, TextureUVOriginSelection attachmentOrigin) =>
|
|
$"TextureUVOrigin `{origin}` is not compatible with existing {attachmentType} attachment `{attachmentType}` of type `{attachmentResourceType}` at index `{attachmentResourceIndex}` with TextureUVOrigin `{attachmentOrigin}`";
|
|
|
|
internal static string IncompatibleTextureUVOriginUseTexture(TextureUVOriginSelection origin) =>
|
|
$"UseTexture() of a resource with `{origin}` is not compatible with Unity's standard UV origin for texture reading {TextureUVOrigin.BottomLeft}. Are you trying to UseTexture() on a backbuffer?";
|
|
|
|
// RenderGraphPass
|
|
internal const string k_MoreThanOneResourceForMRTIndex =
|
|
"You can only bind a single texture to a single index in a multiple render texture (MRT). Verify your indexes are correct.";
|
|
|
|
internal const string k_MoreThanOneTextureForFragInputIndex =
|
|
"You can only bind a single texture to a fragment input index. Verify your indexes are correct.";
|
|
|
|
internal const string k_MoreThanOneTextureRandomWriteInputIndex =
|
|
"You can only bind a single texture to a random write input index. Verify your indexes are correct.";
|
|
|
|
internal const string k_MultipleDepthTextures = "You can only set a single depth texture per pass.";
|
|
|
|
//NativePassCompiler
|
|
internal const string k_LoadingMemorylessResource = "This pass is loading a resource marked as memoryless.";
|
|
|
|
internal const string k_ResolvignMemorylessResource =
|
|
"This pass is storing or resolving a resource marked as memoryless";
|
|
|
|
internal const string k_RenderPassIsEmpty = "Empty render pass";
|
|
|
|
internal const string k_RenderPassHasInvalidProperties =
|
|
"Invalid render pass properties. One or more properties are zero.";
|
|
|
|
internal const string k_ShadingRateImageAttachmentDoesNotMatch =
|
|
"Low level rendergraph error: Shading rate image attachment in renderpass does not match.";
|
|
|
|
internal const string k_AttachmentsDoNotMatch =
|
|
"Low level rendergraph error: Attachments in renderpass do not match.";
|
|
|
|
internal const string k_MultisampledShaderResolveInvalidAttachmentSetup =
|
|
"Low level rendergraph error: last subpass with shader resolve must have one color attachment.";
|
|
|
|
internal const string k_MultisampledShaderResolveInputAttachmentNotMemoryless =
|
|
"Low level rendergraph error: last subpass with shader resolve must have all input attachments as memoryless attachments.";
|
|
|
|
internal const string k_InvalidMRTSetup = "Multiple render texture (MRT) setup is invalid. Some indices are not used.";
|
|
|
|
internal const string k_NoDepthBufferMRT = "Setting multiple render textures (MRTs) without a depth buffer is not supported.";
|
|
|
|
internal const string k_InvalidDepthAndColorTargets = "Neither depth nor color render targets are correctly set up.";
|
|
|
|
internal const string k_InvalidResourceType = "Invalid resource type, expected texture or buffer";
|
|
|
|
internal const string k_NoRenderFunction = "RenderPass was not provided with an execute function.";
|
|
|
|
internal const string k_BeginNoActivePass =
|
|
"Compiler error: Pass is marked as beginning a native sub pass but no pass is currently active.";
|
|
|
|
internal const string k_NoActivePassForSubpass =
|
|
"Compiler error: Generated a subpass pass but no pass is currently active.";
|
|
internal static string UsingLegacyRenderGraph(string passName) =>
|
|
"Pass '" + passName + "' is using the legacy rendergraph API." +
|
|
" You cannot use legacy passes with the Native Render Pass Compiler." +
|
|
" The APIs that are compatible with the Native Render Pass Compiler are AddUnsafePass, AddComputePass and AddRasterRenderPass.";
|
|
|
|
internal static string IncompatibleTextureUVOriginStore(string firstAttachmentName, TextureUVOriginSelection firstAttachmentOrigin, string secondAttachmentName, TextureUVOriginSelection secondAttachmentOrigin) =>
|
|
$"Texture attachment {firstAttachmentName} with uv origin {firstAttachmentOrigin} does not match with texture attachment {secondAttachmentName} with uv origin {secondAttachmentOrigin}. Storing both would result in contents being flipped.";
|
|
|
|
internal static string GetExceptionMessage(RenderGraphState state)
|
|
{
|
|
string caller = GetHigherCaller();
|
|
if (!m_RenderGraphStateMessages.TryGetValue(state, out var messageException))
|
|
{
|
|
return enableCaller ? $"[{caller}] {k_ErrorDefaultMessage}" : k_ErrorDefaultMessage;
|
|
}
|
|
|
|
return enableCaller ? $"[{caller}] {messageException}" : messageException;
|
|
}
|
|
|
|
static string GetHigherCaller()
|
|
{
|
|
// k_CurrentStackCaller is used here to skip three levels in the call stack:
|
|
// Level 0: GetHigherCaller() itself.
|
|
// Level 1: GetExceptionMessage() or any other wrapper method that calls GetHigherCaller().
|
|
// Level 2: The function that directly calls GetMessage() (e.g CheckNotUsedWhenExecute).
|
|
// Level 3: The actual function we are interested in, our public API.
|
|
const int k_CurrentStackCaller = 3;
|
|
|
|
var stackTrace = new StackTrace(k_CurrentStackCaller, false);
|
|
|
|
if (stackTrace.FrameCount > 0)
|
|
{
|
|
var frame = stackTrace.GetFrame(0);
|
|
return frame?.GetMethod()?.Name ?? "UnknownCaller";
|
|
}
|
|
|
|
return "UnknownCaller";
|
|
}
|
|
}
|
|
}
|
|
}
|