post processing
[WindSway-HDRP.git] / Library / PackageCache / com.unity.render-pipelines.high-definition@4.10.0-preview / Runtime / Core / Textures / RTHandleSystem.cs
blob142fc57c5440f89a3bece4c0b980e45e291101db
1 using System;
2 using System.Collections.Generic;
3 using UnityEngine.Assertions;
4 using UnityEngine.Rendering;
6 namespace UnityEngine.Experimental.Rendering
8 public delegate Vector2Int ScaleFunc(Vector2Int size);
10 public partial class RTHandleSystem : IDisposable
12 public enum ResizeMode
14 Auto,
15 OnDemand
18 // Parameters for auto-scaled Render Textures
19 bool m_ScaledRTSupportsMSAA = false;
20 MSAASamples m_ScaledRTCurrentMSAASamples = MSAASamples.None;
21 HashSet<RTHandle> m_AutoSizedRTs;
22 RTHandle[] m_AutoSizedRTsArray; // For fast iteration
23 HashSet<RTHandle> m_ResizeOnDemandRTs;
25 int m_MaxWidths = 0;
26 int m_MaxHeights = 0;
28 public RTHandleSystem()
30 m_AutoSizedRTs = new HashSet<RTHandle>();
31 m_ResizeOnDemandRTs = new HashSet<RTHandle>();
32 m_MaxWidths = 1;
33 m_MaxHeights = 1;
36 public void Dispose()
38 Dispose(true);
41 // Call this once to set the initial size and allow msaa targets or not.
42 public void Initialize(int width, int height, bool scaledRTsupportsMSAA, MSAASamples scaledRTMSAASamples)
44 Debug.Assert(m_AutoSizedRTs.Count == 0, "RTHandle.Initialize should only be called once before allocating any Render Texture.");
46 m_MaxWidths = width;
47 m_MaxHeights = height;
49 m_ScaledRTSupportsMSAA = scaledRTsupportsMSAA;
50 m_ScaledRTCurrentMSAASamples = scaledRTMSAASamples;
53 public void Release(RTHandle rth)
55 if (rth != null)
57 Assert.AreEqual(this, rth.m_Owner);
58 rth.Release();
62 public void SetReferenceSize(int width, int height, MSAASamples msaaSamples)
64 width = Mathf.Max(width, 1);
65 height = Mathf.Max(height, 1);
67 bool sizeChanged = width > GetMaxWidth() || height > GetMaxHeight();
68 bool msaaSamplesChanged = (msaaSamples != m_ScaledRTCurrentMSAASamples);
70 if (sizeChanged || msaaSamplesChanged)
72 Resize(width, height, msaaSamples, sizeChanged, msaaSamplesChanged);
76 public void ResetReferenceSize(int width, int height, MSAASamples msaaSamples)
78 width = Mathf.Max(width, 1);
79 height = Mathf.Max(height, 1);
81 bool sizeChanged = width > GetMaxWidth() || height > GetMaxHeight();
82 bool msaaSamplesChanged = (msaaSamples != m_ScaledRTCurrentMSAASamples);
84 if (sizeChanged || msaaSamplesChanged)
86 Resize(width, height, msaaSamples, sizeChanged, msaaSamplesChanged);
90 public void SwitchResizeMode(RTHandle rth, ResizeMode mode)
92 switch (mode)
94 case ResizeMode.OnDemand:
95 m_AutoSizedRTs.Remove(rth);
96 m_ResizeOnDemandRTs.Add(rth);
97 break;
98 case ResizeMode.Auto:
99 // Resize now so it is consistent with other auto resize RTHs
100 if (m_ResizeOnDemandRTs.Contains(rth))
101 DemandResize(rth);
102 m_ResizeOnDemandRTs.Remove(rth);
103 m_AutoSizedRTs.Add(rth);
104 break;
108 public void DemandResize(RTHandle rth)
110 Assert.IsTrue(m_ResizeOnDemandRTs.Contains(rth), "The RTHandle is not an resize on demand handle in this RTHandleSystem. Please call SwitchToResizeOnDemand(rth, true) before resizing on demand.");
112 // Grab the render texture
113 var rt = rth.m_RT;
114 rth.referenceSize = new Vector2Int(m_MaxWidths, m_MaxHeights);
115 var scaledSize = rth.GetScaledSize(rth.referenceSize);
116 scaledSize = Vector2Int.Max(Vector2Int.one, scaledSize);
118 // Did the size change?
119 var sizeChanged = rt.width != scaledSize.x || rt.height != scaledSize.y;
120 // If this is an MSAA texture, did the sample count change?
121 var msaaSampleChanged = rth.m_EnableMSAA && rt.antiAliasing != (int)m_ScaledRTCurrentMSAASamples;
123 if (sizeChanged || msaaSampleChanged)
125 // Free this render texture
126 rt.Release();
128 // Update the antialiasing count
129 if (rth.m_EnableMSAA)
130 rt.antiAliasing = (int)m_ScaledRTCurrentMSAASamples;
132 // Update the size
133 rt.width = scaledSize.x;
134 rt.height = scaledSize.y;
136 // Generate a new name
137 rt.name = CoreUtils.GetRenderTargetAutoName(
138 rt.width,
139 rt.height,
140 rt.volumeDepth,
141 rt.format,
142 rth.m_Name,
143 mips: rt.useMipMap,
144 enableMSAA: rth.m_EnableMSAA,
145 msaaSamples: m_ScaledRTCurrentMSAASamples
148 // Create the new texture
149 rt.Create();
153 public int GetMaxWidth() { return m_MaxWidths; }
154 public int GetMaxHeight() { return m_MaxHeights; }
156 void Dispose(bool disposing)
158 if (disposing)
160 Array.Resize(ref m_AutoSizedRTsArray, m_AutoSizedRTs.Count);
161 m_AutoSizedRTs.CopyTo(m_AutoSizedRTsArray);
162 for (int i = 0, c = m_AutoSizedRTsArray.Length; i < c; ++i)
164 var rt = m_AutoSizedRTsArray[i];
165 Release(rt);
167 m_AutoSizedRTs.Clear();
169 Array.Resize(ref m_AutoSizedRTsArray, m_ResizeOnDemandRTs.Count);
170 m_ResizeOnDemandRTs.CopyTo(m_AutoSizedRTsArray);
171 for (int i = 0, c = m_AutoSizedRTsArray.Length; i < c; ++i)
173 var rt = m_AutoSizedRTsArray[i];
174 Release(rt);
176 m_ResizeOnDemandRTs.Clear();
177 m_AutoSizedRTsArray = null;
181 void Resize(int width, int height, MSAASamples msaaSamples, bool sizeChanged, bool msaaSampleChanged)
183 m_MaxWidths = Math.Max(width, m_MaxWidths);
184 m_MaxHeights = Math.Max(height, m_MaxHeights);
185 m_ScaledRTCurrentMSAASamples = msaaSamples;
187 var maxSize = new Vector2Int(m_MaxWidths, m_MaxHeights);
189 Array.Resize(ref m_AutoSizedRTsArray, m_AutoSizedRTs.Count);
190 m_AutoSizedRTs.CopyTo(m_AutoSizedRTsArray);
192 for (int i = 0, c = m_AutoSizedRTsArray.Length; i < c; ++i)
194 // Grab the RT Handle
195 var rth = m_AutoSizedRTsArray[i];
197 // If we are only processing MSAA sample count change, make sure this RT is an MSAA one
198 if (!sizeChanged && msaaSampleChanged && !rth.m_EnableMSAA)
200 continue;
203 // Force its new reference size
204 rth.referenceSize = maxSize;
206 // Grab the render texture
207 var renderTexture = rth.m_RT;
209 // Free the previous version
210 renderTexture.Release();
212 // Get the scaled size
213 var scaledSize = rth.GetScaledSize(maxSize);
215 renderTexture.width = Mathf.Max(scaledSize.x, 1);
216 renderTexture.height = Mathf.Max(scaledSize.y, 1);
218 // If this is a msaa texture, make sure to update its msaa count
219 if (rth.m_EnableMSAA)
221 renderTexture.antiAliasing = (int)m_ScaledRTCurrentMSAASamples;
224 // Regenerate the name
225 renderTexture.name = CoreUtils.GetRenderTargetAutoName(renderTexture.width, renderTexture.height, renderTexture.volumeDepth, renderTexture.format, rth.m_Name, mips: renderTexture.useMipMap, enableMSAA: rth.m_EnableMSAA, msaaSamples: m_ScaledRTCurrentMSAASamples);
227 // Create the render texture
228 renderTexture.Create();
232 // This method wraps around regular RenderTexture creation.
233 // There is no specific logic applied to RenderTextures created this way.
234 public RTHandle Alloc(
235 int width,
236 int height,
237 int slices = 1,
238 DepthBits depthBufferBits = DepthBits.None,
239 RenderTextureFormat colorFormat = RenderTextureFormat.Default,
240 FilterMode filterMode = FilterMode.Point,
241 TextureWrapMode wrapMode = TextureWrapMode.Repeat,
242 TextureDimension dimension = TextureDimension.Tex2D,
243 bool sRGB = true,
244 bool enableRandomWrite = false,
245 bool useMipMap = false,
246 bool autoGenerateMips = true,
247 int anisoLevel = 1,
248 float mipMapBias = 0f,
249 MSAASamples msaaSamples = MSAASamples.None,
250 bool bindTextureMS = false,
251 bool useDynamicScale = false,
252 VRTextureUsage vrUsage = VRTextureUsage.None,
253 RenderTextureMemoryless memoryless = RenderTextureMemoryless.None,
254 string name = ""
257 bool enableMSAA = msaaSamples != MSAASamples.None;
258 if (!enableMSAA && bindTextureMS == true)
260 Debug.LogWarning("RTHandle allocated without MSAA but with bindMS set to true, forcing bindMS to false.");
261 bindTextureMS = false;
264 var rt = new RenderTexture(width, height, (int)depthBufferBits, colorFormat, sRGB ? RenderTextureReadWrite.sRGB : RenderTextureReadWrite.Linear)
266 hideFlags = HideFlags.HideAndDontSave,
267 volumeDepth = slices,
268 filterMode = filterMode,
269 wrapMode = wrapMode,
270 dimension = dimension,
271 enableRandomWrite = enableRandomWrite,
272 useMipMap = useMipMap,
273 autoGenerateMips = autoGenerateMips,
274 anisoLevel = anisoLevel,
275 mipMapBias = mipMapBias,
276 antiAliasing = (int)msaaSamples,
277 bindTextureMS = bindTextureMS,
278 useDynamicScale = useDynamicScale,
279 vrUsage = vrUsage,
280 memorylessMode = memoryless,
281 name = CoreUtils.GetRenderTargetAutoName(width, height, slices, colorFormat, name, mips: useMipMap, enableMSAA: enableMSAA, msaaSamples: msaaSamples)
283 rt.Create();
285 RTCategory category = enableMSAA ? RTCategory.MSAA : RTCategory.Regular;
286 var newRT = new RTHandle(this);
287 newRT.SetRenderTexture(rt, category);
288 newRT.useScaling = false;
289 newRT.m_EnableRandomWrite = enableRandomWrite;
290 newRT.m_EnableMSAA = enableMSAA;
291 newRT.m_Name = name;
293 newRT.referenceSize = new Vector2Int(width, height);
295 return newRT;
298 // Next two methods are used to allocate RenderTexture that depend on the frame settings (resolution and msaa for now)
299 // RenderTextures allocated this way are meant to be defined by a scale of camera resolution (full/half/quarter resolution for example).
300 // The idea is that internally the system will scale up the size of all render texture so that it amortizes with time and not reallocate when a smaller size is required (which is what happens with TemporaryRTs).
301 // Since MSAA cannot be changed on the fly for a given RenderTexture, a separate instance will be created if the user requires it. This instance will be the one used after the next call of SetReferenceSize if MSAA is required.
302 public RTHandle Alloc(
303 Vector2 scaleFactor,
304 int slices = 1,
305 DepthBits depthBufferBits = DepthBits.None,
306 RenderTextureFormat colorFormat = RenderTextureFormat.Default,
307 FilterMode filterMode = FilterMode.Point,
308 TextureWrapMode wrapMode = TextureWrapMode.Repeat,
309 TextureDimension dimension = TextureDimension.Tex2D,
310 bool sRGB = true,
311 bool enableRandomWrite = false,
312 bool useMipMap = false,
313 bool autoGenerateMips = true,
314 int anisoLevel = 1,
315 float mipMapBias = 0f,
316 bool enableMSAA = false,
317 bool bindTextureMS = false,
318 bool useDynamicScale = false,
319 VRTextureUsage vrUsage = VRTextureUsage.None,
320 RenderTextureMemoryless memoryless = RenderTextureMemoryless.None,
321 string name = ""
324 // If an MSAA target is requested, make sure the support was on
325 if (enableMSAA)
326 Debug.Assert(m_ScaledRTSupportsMSAA);
328 int width = Mathf.Max(Mathf.RoundToInt(scaleFactor.x * GetMaxWidth()), 1);
329 int height = Mathf.Max(Mathf.RoundToInt(scaleFactor.y * GetMaxHeight()), 1);
331 var rth = AllocAutoSizedRenderTexture(width,
332 height,
333 slices,
334 depthBufferBits,
335 colorFormat,
336 filterMode,
337 wrapMode,
338 dimension,
339 sRGB,
340 enableRandomWrite,
341 useMipMap,
342 autoGenerateMips,
343 anisoLevel,
344 mipMapBias,
345 enableMSAA,
346 bindTextureMS,
347 useDynamicScale,
348 vrUsage,
349 memoryless,
350 name
353 rth.referenceSize = new Vector2Int(width, height);
355 rth.scaleFactor = scaleFactor;
356 return rth;
360 // You can provide your own scaling function for advanced scaling schemes (e.g. scaling to
361 // the next POT). The function takes a Vec2 as parameter that holds max width & height
362 // values for the current manager context and returns a Vec2 of the final size in pixels.
364 // var rth = Alloc(
365 // size => new Vector2Int(size.x / 2, size.y),
366 // [...]
367 // );
369 public RTHandle Alloc(
370 ScaleFunc scaleFunc,
371 int slices = 1,
372 DepthBits depthBufferBits = DepthBits.None,
373 RenderTextureFormat colorFormat = RenderTextureFormat.Default,
374 FilterMode filterMode = FilterMode.Point,
375 TextureWrapMode wrapMode = TextureWrapMode.Repeat,
376 TextureDimension dimension = TextureDimension.Tex2D,
377 bool sRGB = true,
378 bool enableRandomWrite = false,
379 bool useMipMap = false,
380 bool autoGenerateMips = true,
381 int anisoLevel = 1,
382 float mipMapBias = 0f,
383 bool enableMSAA = false,
384 bool bindTextureMS = false,
385 bool useDynamicScale = false,
386 VRTextureUsage vrUsage = VRTextureUsage.None,
387 RenderTextureMemoryless memoryless = RenderTextureMemoryless.None,
388 string name = ""
391 var scaleFactor = scaleFunc(new Vector2Int(GetMaxWidth(), GetMaxHeight()));
392 int width = Mathf.Max(scaleFactor.x, 1);
393 int height = Mathf.Max(scaleFactor.y, 1);
395 var rth = AllocAutoSizedRenderTexture(width,
396 height,
397 slices,
398 depthBufferBits,
399 colorFormat,
400 filterMode,
401 wrapMode,
402 dimension,
403 sRGB,
404 enableRandomWrite,
405 useMipMap,
406 autoGenerateMips,
407 anisoLevel,
408 mipMapBias,
409 enableMSAA,
410 bindTextureMS,
411 useDynamicScale,
412 vrUsage,
413 memoryless,
414 name
417 rth.referenceSize = new Vector2Int(width, height);
419 rth.scaleFunc = scaleFunc;
420 return rth;
423 // Internal function
424 RTHandle AllocAutoSizedRenderTexture(
425 int width,
426 int height,
427 int slices,
428 DepthBits depthBufferBits,
429 RenderTextureFormat colorFormat,
430 FilterMode filterMode,
431 TextureWrapMode wrapMode,
432 TextureDimension dimension,
433 bool sRGB,
434 bool enableRandomWrite,
435 bool useMipMap,
436 bool autoGenerateMips,
437 int anisoLevel,
438 float mipMapBias,
439 bool enableMSAA,
440 bool bindTextureMS,
441 bool useDynamicScale,
442 VRTextureUsage vrUsage,
443 RenderTextureMemoryless memoryless,
444 string name
447 // Here user made a mistake in setting up msaa/bindMS, hence the warning
448 if (!enableMSAA && bindTextureMS == true)
450 Debug.LogWarning("RTHandle allocated without MSAA but with bindMS set to true, forcing bindMS to false.");
451 bindTextureMS = false;
454 bool allocForMSAA = m_ScaledRTSupportsMSAA ? enableMSAA : false;
455 // Here we purposefully disable MSAA so we just force the bindMS param to false.
456 if (!allocForMSAA)
458 bindTextureMS = false;
461 // MSAA Does not support random read/write.
462 bool UAV = enableRandomWrite;
463 if (allocForMSAA && (UAV == true))
465 Debug.LogWarning("RTHandle that is MSAA-enabled cannot allocate MSAA RT with 'enableRandomWrite = true'.");
466 UAV = false;
469 int msaaSamples = allocForMSAA ? (int)m_ScaledRTCurrentMSAASamples : 1;
470 RTCategory category = allocForMSAA ? RTCategory.MSAA : RTCategory.Regular;
472 var rt = new RenderTexture(width, height, (int)depthBufferBits, colorFormat, sRGB ? RenderTextureReadWrite.sRGB : RenderTextureReadWrite.Linear)
474 hideFlags = HideFlags.HideAndDontSave,
475 volumeDepth = slices,
476 filterMode = filterMode,
477 wrapMode = wrapMode,
478 dimension = dimension,
479 enableRandomWrite = UAV,
480 useMipMap = useMipMap,
481 autoGenerateMips = autoGenerateMips,
482 anisoLevel = anisoLevel,
483 mipMapBias = mipMapBias,
484 antiAliasing = msaaSamples,
485 bindTextureMS = bindTextureMS,
486 useDynamicScale = useDynamicScale,
487 vrUsage = vrUsage,
488 memorylessMode = memoryless,
489 name = CoreUtils.GetRenderTargetAutoName(width, height, slices, colorFormat, name, mips: useMipMap, enableMSAA: allocForMSAA, msaaSamples: m_ScaledRTCurrentMSAASamples)
491 rt.Create();
493 var rth = new RTHandle(this);
494 rth.SetRenderTexture(rt, category);
495 rth.m_EnableMSAA = enableMSAA;
496 rth.m_EnableRandomWrite = enableRandomWrite;
497 rth.useScaling = true;
498 rth.m_Name = name;
499 m_AutoSizedRTs.Add(rth);
500 return rth;
503 public string DumpRTInfo()
505 string result = "";
506 Array.Resize(ref m_AutoSizedRTsArray, m_AutoSizedRTs.Count);
507 m_AutoSizedRTs.CopyTo(m_AutoSizedRTsArray);
508 for (int i = 0, c = m_AutoSizedRTsArray.Length; i < c; ++i)
510 var rt = m_AutoSizedRTsArray[i].rt;
511 result = string.Format("{0}\nRT ({1})\t Format: {2} W: {3} H {4}\n", result, i, rt.format, rt.width, rt.height);
514 return result;