248 lines
10 KiB
C#
248 lines
10 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
using NVStreamline;
|
|
|
|
namespace NVStreamline
|
|
{
|
|
[AddComponentMenu("NVIDIA/Streamline DLSS-G Builtin")]
|
|
public class StreamlineDLSSG : MonoBehaviour
|
|
{
|
|
private CommandBuffer m_cmdCopyDepthAndMVecs;
|
|
private CommandBuffer m_cmdCopyHudlessColor;
|
|
private Camera m_camera;
|
|
private uint m_id;
|
|
public bool DLSSGFeatureAvailable { get; private set; } = false;
|
|
|
|
|
|
#if false
|
|
//Put 5x3Compute shader in test project and drag onto this in editor
|
|
public ComputeShader TESTcs5x3 = null;
|
|
#endif
|
|
private void AttachCamera()
|
|
{
|
|
m_camera.AddCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, m_cmdCopyDepthAndMVecs);
|
|
m_camera.AddCommandBuffer(CameraEvent.AfterEverything, m_cmdCopyHudlessColor);
|
|
ClearCommandLists();
|
|
}
|
|
|
|
private void DetachCamera()
|
|
{
|
|
ClearCommandLists();
|
|
m_camera.RemoveCommandBuffer(CameraEvent.BeforeImageEffectsOpaque, m_cmdCopyDepthAndMVecs);
|
|
m_camera.RemoveCommandBuffer(CameraEvent.AfterEverything, m_cmdCopyHudlessColor);
|
|
}
|
|
|
|
private void CreateCommandLists()
|
|
{
|
|
m_cmdCopyDepthAndMVecs = new CommandBuffer();
|
|
m_cmdCopyDepthAndMVecs.name = "Streamline DLSSG CopyDepthMVecs";
|
|
|
|
//Command list still required for sending Null tag
|
|
m_cmdCopyHudlessColor = new CommandBuffer();
|
|
m_cmdCopyHudlessColor.name = "Streamline DLSSG CopyHudlessColor";
|
|
|
|
}
|
|
|
|
private void DestroyCommandLists()
|
|
{
|
|
|
|
}
|
|
|
|
void ClearCommandLists()
|
|
{
|
|
m_cmdCopyDepthAndMVecs.Clear();
|
|
|
|
m_cmdCopyHudlessColor.Clear();
|
|
|
|
#if !UNITY_EDITOR && UNITY_2019_1_OR_NEWER
|
|
// On DX12 up until 2020.2 command lists that are being generated do not get flushed.
|
|
// This causes incorrect ordering of plugin side command lists.
|
|
// i.e. After submitted lists but before currently being generated lists.
|
|
// We can force a flush in non-editor mode by creating a fence but never waiting for it.
|
|
// Editor mode does not support GPUFence.
|
|
GraphicsFence fence1 = m_cmdCopyDepthAndMVecs.CreateGraphicsFence(GraphicsFenceType.AsyncQueueSynchronisation, SynchronisationStageFlags.AllGPUOperations);
|
|
GraphicsFence fence2 = m_cmdCopyHudlessColor.CreateGraphicsFence(GraphicsFenceType.AsyncQueueSynchronisation, SynchronisationStageFlags.AllGPUOperations);
|
|
#endif
|
|
}
|
|
|
|
|
|
void SetupTextureBlits()
|
|
{
|
|
uint frameIndex = (uint)Time.frameCount;
|
|
if (StreamlineDLSSGCore.DLSSGEnabled)
|
|
{
|
|
// Using this scale and bias rather than the draw&view rects as they were only relevant for editor rendering and Unity2019.4
|
|
// doesn't have the same Blit commands as 2021 (src and dest bias/scale)
|
|
Vector2 scale = new Vector2(1.0f, -1.0f);
|
|
Vector2 offset = new Vector2(0.0f, 1.0f);
|
|
|
|
RenderTexture targetDepth = StreamlineDLSSGCore.GetTargetDepthTexture();
|
|
RenderTexture targetMVecs = StreamlineDLSSGCore.GetTargetMVecsTexture();
|
|
RenderTexture targetHudlessColor = StreamlineDLSSGCore.GetTargetHudlessColorTexture();
|
|
|
|
// Copy flipped textures
|
|
bool deferred = m_camera.actualRenderingPath == RenderingPath.DeferredShading;
|
|
RenderTargetIdentifier srcRtid = new RenderTargetIdentifier(deferred ? BuiltinRenderTextureType.ResolvedDepth : BuiltinRenderTextureType.Depth);
|
|
m_cmdCopyDepthAndMVecs.Blit(srcRtid, targetDepth.colorBuffer, scale, offset);
|
|
m_cmdCopyDepthAndMVecs.Blit(new RenderTargetIdentifier(BuiltinRenderTextureType.MotionVectors), targetMVecs, scale, offset);
|
|
|
|
if (StreamlineDLSSGCore.UseHudlessColor)
|
|
{
|
|
m_cmdCopyHudlessColor.Blit(new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget), targetHudlessColor, scale, offset);
|
|
}
|
|
#if false
|
|
if (TESTcs5x3)
|
|
{
|
|
int kernel = TESTcs5x3.FindKernel("Font5x3Draw");
|
|
|
|
int w = (4 * 6 * 32);
|
|
int h = (5 * 32);
|
|
|
|
Vector4 offsetsh = new Vector4(targetDepth.width / 3, targetDepth.height / 2, 0, 0);
|
|
|
|
m_cmdCopyDepthAndMVecs.SetComputeTextureParam(TESTcs5x3, kernel, "_OutputDTexture", targetDepth, 0, RenderTextureSubElement.Color);
|
|
m_cmdCopyDepthAndMVecs.SetComputeIntParam(TESTcs5x3, "_InputValue", (int)frameIndex);
|
|
m_cmdCopyDepthAndMVecs.SetComputeIntParam(TESTcs5x3, "_Phase", 0);
|
|
m_cmdCopyDepthAndMVecs.SetComputeVectorParam(TESTcs5x3, "_Offset", offsetsh);
|
|
m_cmdCopyDepthAndMVecs.DispatchCompute(TESTcs5x3, kernel, w, h, 1);
|
|
|
|
m_cmdCopyDepthAndMVecs.SetComputeTextureParam(TESTcs5x3, kernel, "_OutputMTexture", targetMVecs, 0, RenderTextureSubElement.Color);
|
|
m_cmdCopyDepthAndMVecs.SetComputeIntParam(TESTcs5x3, "_InputValue", (int)frameIndex);
|
|
m_cmdCopyDepthAndMVecs.SetComputeIntParam(TESTcs5x3, "_Phase", 1);
|
|
m_cmdCopyDepthAndMVecs.SetComputeVectorParam(TESTcs5x3, "_Offset", offsetsh);
|
|
m_cmdCopyDepthAndMVecs.DispatchCompute(TESTcs5x3, kernel, w, h, 1);
|
|
|
|
if (StreamlineDLSSGCore.UseHudlessColor)
|
|
{
|
|
m_cmdCopyHudlessColor.SetComputeTextureParam(TESTcs5x3, kernel, "_OutputHTexture", targetHudlessColor, 0, RenderTextureSubElement.Color);
|
|
m_cmdCopyHudlessColor.SetComputeIntParam(TESTcs5x3, "_InputValue", (int)frameIndex);
|
|
m_cmdCopyHudlessColor.SetComputeIntParam(TESTcs5x3, "_Phase", 2);
|
|
m_cmdCopyHudlessColor.SetComputeVectorParam(TESTcs5x3, "_Offset", offsetsh);
|
|
m_cmdCopyHudlessColor.DispatchCompute(TESTcs5x3, kernel, w, h, 1);
|
|
}
|
|
|
|
}
|
|
#endif
|
|
|
|
}
|
|
}
|
|
|
|
public void SetupDepthAndMVecTextureTags(CommandBuffer cmd)
|
|
{
|
|
uint frameIndex = (uint)Time.frameCount;
|
|
if (StreamlineDLSSGCore.DLSSGEnabled)
|
|
{
|
|
RenderTexture targetDepth = StreamlineDLSSGCore.GetTargetDepthTexture();
|
|
RenderTexture targetMVecs = StreamlineDLSSGCore.GetTargetMVecsTexture();
|
|
|
|
StreamlineCore.SetTag(cmd, frameIndex, m_id, targetDepth, StreamlineCore.BufferType.eBufferTypeDepth, 0);
|
|
StreamlineCore.SetTag(cmd, frameIndex, m_id, targetMVecs, StreamlineCore.BufferType.eBufferTypeMVec, 0);
|
|
}
|
|
else
|
|
{
|
|
StreamlineCore.SetTag(cmd, frameIndex, m_id, null, StreamlineCore.BufferType.eBufferTypeDepth, 0);
|
|
StreamlineCore.SetTag(cmd, frameIndex, m_id, null, StreamlineCore.BufferType.eBufferTypeMVec, 0);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public void SetupHudlessColorTextureTags(CommandBuffer cmd)
|
|
{
|
|
uint frameIndex = (uint)Time.frameCount;
|
|
if (StreamlineDLSSGCore.DLSSGEnabled && StreamlineDLSSGCore.UseHudlessColor)
|
|
{
|
|
RenderTexture targetHudlessColor = StreamlineDLSSGCore.GetTargetHudlessColorTexture();
|
|
|
|
StreamlineCore.SetTag(cmd, frameIndex, m_id, targetHudlessColor, StreamlineCore.BufferType.eBufferTypeHUDLessColor, 0);
|
|
//StreamlineCore.SetTag(cmd, frameIndex, m_id, null, StreamlineCore.BufferType.eBufferTypeHUDLessColor, 0);
|
|
}
|
|
else
|
|
{
|
|
StreamlineCore.SetTag(cmd, frameIndex, m_id, null, StreamlineCore.BufferType.eBufferTypeHUDLessColor, 0);
|
|
}
|
|
}
|
|
|
|
|
|
void Awake()
|
|
{
|
|
DLSSGFeatureAvailable = false;
|
|
|
|
if (!StreamlineCore.IsFeatureSupported(StreamlineCore.Feature.eFeatureDLSS_G))
|
|
{
|
|
Debug.Log("DLSSG is not supported");
|
|
return;
|
|
}
|
|
|
|
int id = StreamlineCore.CreateFeature(StreamlineCore.Feature.eFeatureDLSS_G);
|
|
if (id != 0) //CreateFeature must return 0 for DLSSG
|
|
{
|
|
Debug.LogError("DLSSG Awake FAILED to get feature id");
|
|
return;
|
|
}
|
|
|
|
m_id = (uint)id;
|
|
DLSSGFeatureAvailable = true;
|
|
m_camera = GetComponent<Camera>();
|
|
m_camera.depthTextureMode |= DepthTextureMode.Depth | DepthTextureMode.MotionVectors;
|
|
CreateCommandLists();
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
if (DLSSGFeatureAvailable && m_id == 0)
|
|
{
|
|
StreamlineCore.DestroyFeature((int)m_id);
|
|
}
|
|
}
|
|
|
|
void OnEnable()
|
|
{
|
|
if (DLSSGFeatureAvailable)
|
|
{
|
|
AttachCamera();
|
|
}
|
|
}
|
|
|
|
void OnDisable()
|
|
{
|
|
if (DLSSGFeatureAvailable)
|
|
{
|
|
DetachCamera();
|
|
}
|
|
}
|
|
|
|
// Update is called once per frame
|
|
void LateUpdate()
|
|
{
|
|
if (DLSSGFeatureAvailable)
|
|
{
|
|
StreamlineDLSSGCore.ProcessDisposals();
|
|
|
|
if (StreamlineDLSSGCore.UpdateDrawRects(m_camera))
|
|
{
|
|
//reallocate tagged textures
|
|
StreamlineDLSSGCore.TaggedTextureDimensions tdd = StreamlineDLSSGCore.GetTaggedTextureDimensionsRef();
|
|
|
|
StreamlineDLSSGCore.AllocateTextures(tdd.m_currentDrawRect, tdd.m_currentViewRect, false, tdd.m_desktopScale, StreamlineDLSSGCore.UseHudlessColor);
|
|
}
|
|
|
|
if (GraphicsSettings.defaultRenderPipeline == null) //Built in only
|
|
{
|
|
ClearCommandLists();
|
|
SetupTextureBlits();
|
|
SetupDepthAndMVecTextureTags(m_cmdCopyDepthAndMVecs);
|
|
SetupHudlessColorTextureTags(m_cmdCopyHudlessColor);
|
|
|
|
StreamlineDLSSGCore.SetupDLSSGFeatureConstants(m_cmdCopyDepthAndMVecs, m_camera, m_id, (uint)Time.frameCount);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|