Skip to content

Commit 9acf106

Browse files
robinb-u3dEvergreen
authored andcommitted
URP - Improve Y-Flip detection for intermediate render passes when using Shader Attachment Reads
1 parent a869cfb commit 9acf106

27 files changed

+1205
-353
lines changed

Packages/com.unity.render-pipelines.core/Editor/RenderGraph/RenderGraphTestsCore.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ internal class RenderGraphTestPipelineAsset : RenderPipelineAsset<RenderGraphTes
3737

3838
public RenderGraph renderGraph;
3939

40+
public RenderTextureUVOriginStrategy renderTextureUVOriginStrategy;
41+
42+
public bool invalidContextForTesting;
43+
4044
protected override RenderPipeline CreatePipeline()
4145
{
4246
return new RenderGraphTestPipelineInstance(this);
@@ -76,7 +80,8 @@ protected override void Render(ScriptableRenderContext renderContext, List<Camer
7680
commandBuffer = cmd,
7781
scriptableRenderContext = renderContext,
7882
currentFrameIndex = Time.frameCount,
79-
invalidContextForTesting = false
83+
invalidContextForTesting = asset.invalidContextForTesting,
84+
renderTextureUVOriginStrategy = asset.renderTextureUVOriginStrategy
8085
};
8186

8287
try
@@ -99,10 +104,14 @@ protected override void Render(ScriptableRenderContext renderContext, List<Camer
99104
return;
100105
}
101106

102-
renderContext.ExecuteCommandBuffer(cmd);
107+
if (rgParams.invalidContextForTesting == false)
108+
{
109+
renderContext.ExecuteCommandBuffer(cmd);
110+
}
103111

104112
CommandBufferPool.Release(cmd);
105113
}
114+
106115
renderContext.Submit();
107116
}
108117
}
@@ -175,6 +184,7 @@ public void Cleanup()
175184
[TearDown]
176185
public void CleanupRenderGraph()
177186
{
187+
m_RenderGraphTestPipeline.invalidContextForTesting = false;
178188
// Cleaning all Render Graph resources and data structures
179189
// Nothing remains, Render Graph in next test will start from scratch
180190
m_RenderGraph.ForceCleanup();

Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/CompilerContextData.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,19 @@ public void CullAllPasses(bool isCulled)
247247
}
248248
}
249249

250+
public TextureUVOrigin GetTextureUVOrigin(in TextureHandle targetHandle)
251+
{
252+
if (targetHandle.handle.IsValid())
253+
{
254+
ref readonly ResourceUnversionedData unversionedData = ref UnversionedResourceData(targetHandle.handle);
255+
return unversionedData.textureUVOrigin == TextureUVOriginSelection.TopLeft ? TextureUVOrigin.TopLeft : TextureUVOrigin.BottomLeft;
256+
}
257+
else
258+
{
259+
return TextureUVOrigin.BottomLeft;
260+
}
261+
}
262+
250263
// Helper to loop over native passes
251264
public ref struct NativePassIterator
252265
{

Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/NativePassCompiler.cs

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ internal struct RenderGraphInputInfo
1515
public string debugName;
1616
public bool disablePassCulling;
1717
public bool disablePassMerging;
18+
public RenderTextureUVOriginStrategy renderTextureUVOriginStrategy;
1819
}
1920

2021
internal RenderGraphInputInfo graph;
@@ -73,7 +74,7 @@ public void Cleanup()
7374
}
7475

7576
public bool Initialize(RenderGraphResourceRegistry resources, List<RenderGraphPass> renderPasses, RenderGraphDebugParams debugParams, string debugName, bool useCompilationCaching,
76-
int graphHash, int frameIndex)
77+
int graphHash, int frameIndex, RenderTextureUVOriginStrategy renderTextureUVOriginStrategy)
7778
{
7879
bool cached = false;
7980
if (!useCompilationCaching)
@@ -86,6 +87,7 @@ public bool Initialize(RenderGraphResourceRegistry resources, List<RenderGraphPa
8687
graph.disablePassCulling = debugParams.disablePassCulling;
8788
graph.disablePassMerging = debugParams.disablePassMerging;
8889
graph.debugName = debugName;
90+
graph.renderTextureUVOriginStrategy = renderTextureUVOriginStrategy;
8991

9092
Clear(clearContextData: !useCompilationCaching);
9193

@@ -145,6 +147,9 @@ public void Compile(RenderGraphResourceRegistry resources)
145147
DetectMemoryLessResources();
146148

147149
PrepareNativeRenderPasses();
150+
151+
if (graph.renderTextureUVOriginStrategy == RenderTextureUVOriginStrategy.PropagateAttachmentOrientation)
152+
PropagateTextureUVOrigin();
148153
}
149154

150155
public void Clear(bool clearContextData)
@@ -172,6 +177,7 @@ internal enum NativeCompilerProfileId
172177
NRPRGComp_TryMergeNativePasses,
173178
NRPRGComp_FindResourceUsageRanges,
174179
NRPRGComp_DetectMemorylessResources,
180+
NRPRGComp_PropagateTextureUVOrigin,
175181
NRPRGComp_ExecuteInitializeResources,
176182
NRPRGComp_ExecuteBeginRenderpassCommand,
177183
NRPRGComp_ExecuteDestroyResources,
@@ -181,7 +187,7 @@ internal enum NativeCompilerProfileId
181187
void ValidatePasses()
182188
{
183189
if (RenderGraph.enableValidityChecks)
184-
{
190+
{
185191
int tilePropertiesPassIndex = -1;
186192
for (int passId = 0; passId < graph.m_RenderPasses.Count; passId++)
187193
{
@@ -822,6 +828,62 @@ void PrepareNativeRenderPasses()
822828
}
823829
}
824830

831+
void PropagateTextureUVOrigin()
832+
{
833+
using (new ProfilingScope(ProfilingSampler.Get(NativeCompilerProfileId.NRPRGComp_PropagateTextureUVOrigin)))
834+
{
835+
// Work backwards through the native pass list and propagate the texture uv origin we store with to
836+
// any texture attachments that are not explicitly known (usually intermediate memoryless attachments).
837+
for (int passIdx = contextData.nativePassData.Length - 1; passIdx >= 0; --passIdx)
838+
{
839+
ref NativePassData nativePassData = ref contextData.nativePassData.ElementAt(passIdx);
840+
841+
// Find a texture attachment that is storing to find out the orientation for this pass.
842+
int attachmentsCount = nativePassData.attachments.size;
843+
int firstStoreAttachmentIndex = 0;
844+
TextureUVOriginSelection storeUVOrigin = TextureUVOriginSelection.Unknown;
845+
for (int attIdx = 0; attIdx < attachmentsCount; ++attIdx)
846+
{
847+
ref NativePassAttachment nativePassAttachment = ref nativePassData.attachments[attIdx];
848+
if (nativePassAttachment.storeAction != RenderBufferStoreAction.DontCare)
849+
{
850+
if (nativePassAttachment.handle.type == RenderGraphResourceType.Texture) // Only textures have orientation
851+
{
852+
ref ResourceUnversionedData resData = ref contextData.UnversionedResourceData(nativePassAttachment.handle);
853+
storeUVOrigin = resData.textureUVOrigin; // Inherit the orientation of the store if we are currently storing to an unknown orientation.
854+
firstStoreAttachmentIndex = attIdx;
855+
break;
856+
}
857+
}
858+
}
859+
860+
// Update any texture attachments with an unknown uv origin to the one we are going to use for storing and validate
861+
// we don't have a mixture of uv origins on the texture attachment list as this would mean something is going to be
862+
// read/written upside down.
863+
for (int attIdx = 0; attIdx < attachmentsCount; ++attIdx)
864+
{
865+
ref NativePassAttachment nativePassAttachment = ref nativePassData.attachments[attIdx];
866+
867+
if (nativePassAttachment.handle.type == RenderGraphResourceType.Texture)
868+
{
869+
ref ResourceUnversionedData resData = ref contextData.UnversionedResourceData(nativePassAttachment.handle);
870+
if (storeUVOrigin != TextureUVOriginSelection.Unknown && resData.textureUVOrigin != TextureUVOriginSelection.Unknown && resData.textureUVOrigin != storeUVOrigin)
871+
{
872+
ref NativePassAttachment firstStoreNativePassAttachment = ref nativePassData.attachments[firstStoreAttachmentIndex];
873+
var firstStoreAttachmentName = graph.m_ResourcesForDebugOnly.GetRenderGraphResourceName(firstStoreNativePassAttachment.handle);
874+
var name = graph.m_ResourcesForDebugOnly.GetRenderGraphResourceName(nativePassAttachment.handle);
875+
876+
throw new InvalidOperationException($"From pass '{contextData.passNames[nativePassData.firstGraphPass]}' to pass '{contextData.passNames[nativePassData.lastGraphPass]}' when trying to store resource '{name}' of type {nativePassAttachment.handle.type} at index {nativePassAttachment.handle.index} - "
877+
+ RenderGraph.RenderGraphExceptionMessages.IncompatibleTextureUVOriginStore(firstStoreAttachmentName, storeUVOrigin, name, resData.textureUVOrigin));
878+
}
879+
880+
resData.textureUVOrigin = storeUVOrigin;
881+
}
882+
}
883+
}
884+
}
885+
}
886+
825887
static bool IsGlobalTextureInPass(RenderGraphPass pass, ResourceHandle handle)
826888
{
827889
foreach (var g in pass.setGlobalsList)

Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/Compiler/ResourcesData.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@ internal struct ResourceUnversionedData
3636
public readonly bool discard; // graph.m_Resources.GetTextureResourceDesc(fragment.resource).discardBuffer;
3737
public readonly bool bindMS;
3838

39+
public TextureUVOriginSelection textureUVOrigin;
40+
3941
[MethodImpl(MethodImplOptions.AggressiveInlining)]
4042
public string GetName(CompilerContextData ctx, ResourceHandle h) => ctx.GetResourceName(h);
4143

42-
public ResourceUnversionedData(IRenderGraphResource rll, ref RenderTargetInfo info, ref TextureDesc desc, bool isResourceShared)
44+
public ResourceUnversionedData(TextureResource rll, ref RenderTargetInfo info, ref TextureDesc desc, bool isResourceShared)
4345
{
4446
isImported = rll.imported;
4547
isShared = isResourceShared;
@@ -59,6 +61,7 @@ public ResourceUnversionedData(IRenderGraphResource rll, ref RenderTargetInfo in
5961
clear = desc.clearBuffer;
6062
discard = desc.discardBuffer;
6163
bindMS = info.bindMS;
64+
textureUVOrigin = rll.textureUVOrigin;
6265
}
6366

6467
public ResourceUnversionedData(IRenderGraphResource rll, ref BufferDesc _, bool isResourceShared)
@@ -83,6 +86,7 @@ public ResourceUnversionedData(IRenderGraphResource rll, ref BufferDesc _, bool
8386
clear = false;
8487
discard = false;
8588
bindMS = false;
89+
textureUVOrigin = TextureUVOriginSelection.Unknown;
8690
}
8791

8892
public ResourceUnversionedData(IRenderGraphResource rll, ref RayTracingAccelerationStructureDesc _, bool isResourceShared)
@@ -107,13 +111,15 @@ public ResourceUnversionedData(IRenderGraphResource rll, ref RayTracingAccelerat
107111
clear = false;
108112
discard = false;
109113
bindMS = false;
114+
textureUVOrigin = TextureUVOriginSelection.Unknown;
110115
}
111116

112117
public void InitializeNullResource()
113118
{
114119
firstUsePassID = -1;
115120
lastUsePassID = -1;
116121
lastWritePassID = -1;
122+
textureUVOrigin = TextureUVOriginSelection.Unknown;
117123
}
118124
}
119125

@@ -276,11 +282,12 @@ public void Initialize(RenderGraphResourceRegistry resources)
276282
{
277283
case (int)RenderGraphResourceType.Texture:
278284
{
285+
var tex = rll as TextureResource;
279286
resources.GetRenderTargetInfo(h, out var info);
280-
ref var desc = ref (rll as TextureResource).desc;
287+
ref var desc = ref tex.desc;
281288
bool isResourceShared = resources.IsRenderGraphResourceShared(h);
282289

283-
unversionedData[t][r] = new ResourceUnversionedData(rll, ref info, ref desc, isResourceShared);
290+
unversionedData[t][r] = new ResourceUnversionedData(tex, ref info, ref desc, isResourceShared);
284291
break;
285292
}
286293
case (int)RenderGraphResourceType.Buffer:

Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.Compiler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ internal NativePassCompiler CompileNativeRenderGraph(int graphHash)
1515
if (nativeCompiler == null)
1616
nativeCompiler = new NativePassCompiler(m_CompilationCache);
1717

18-
bool compilationIsCached = nativeCompiler.Initialize(m_Resources, m_RenderPasses, m_DebugParameters, name, m_EnableCompilationCaching, graphHash, m_ExecutionCount);
18+
bool compilationIsCached = nativeCompiler.Initialize(m_Resources, m_RenderPasses, m_DebugParameters, name, m_EnableCompilationCaching, graphHash, m_ExecutionCount, m_renderTextureUVOriginStrategy);
1919
if (!compilationIsCached)
2020
nativeCompiler.Compile(m_Resources);
2121

Packages/com.unity.render-pipelines.core/Runtime/RenderGraph/RenderGraph.ExceptionMessages.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ internal static string UseDepthWithColorFormat(GraphicsFormat colorFormat) =>
113113
internal static string UseTransientTextureInWrongPass(int transientIndex) =>
114114
$"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.";
115115

116+
internal static string IncompatibleTextureUVOrigin(TextureUVOriginSelection origin, string attachmentType, string attachmentName, RenderGraphResourceType attachmentResourceType, int attachmentResourceIndex, TextureUVOriginSelection attachmentOrigin) =>
117+
$"TextureUVOrigin `{origin}` is not compatible with existing {attachmentType} attachment `{attachmentType}` of type `{attachmentResourceType}` at index `{attachmentResourceIndex}` with TextureUVOrigin `{attachmentOrigin}`";
118+
119+
internal static string IncompatibleTextureUVOriginUseTexture(TextureUVOriginSelection origin) =>
120+
$"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?";
121+
116122
// RenderGraphPass
117123
internal const string k_MoreThanOneResourceForMRTIndex =
118124
"You can only bind a single texture to a single index in a multiple render texture (MRT). Verify your indexes are correct.";
@@ -141,7 +147,7 @@ internal static string UseTransientTextureInWrongPass(int transientIndex) =>
141147

142148
internal const string k_AttachmentsDoNotMatch =
143149
"Low level rendergraph error: Attachments in renderpass do not match.";
144-
150+
145151
internal const string k_MultisampledShaderResolveInvalidAttachmentSetup =
146152
"Low level rendergraph error: last subpass with shader resolve must have one color attachment.";
147153

@@ -165,6 +171,9 @@ internal static string UsingLegacyRenderGraph(string passName) =>
165171
" You cannot use legacy passes with the Native Render Pass Compiler." +
166172
" The APIs that are compatible with the Native Render Pass Compiler are AddUnsafePass, AddComputePass and AddRasterRenderPass.";
167173

174+
internal static string IncompatibleTextureUVOriginStore(string firstAttachmentName, TextureUVOriginSelection firstAttachmentOrigin, string secondAttachmentName, TextureUVOriginSelection secondAttachmentOrigin) =>
175+
$"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.";
176+
168177
internal static string GetExceptionMessage(RenderGraphState state)
169178
{
170179
string caller = GetHigherCaller();

0 commit comments

Comments
 (0)