Esempio n. 1
0
        internal static bool AreAttachmentIndicesCompatible(ScriptableRenderPass lastSubPass, ScriptableRenderPass currentSubPass)
        {
            uint lastSubPassAttCount    = GetSubPassAttachmentIndicesCount(lastSubPass);
            uint currentSubPassAttCount = GetSubPassAttachmentIndicesCount(currentSubPass);

            if (currentSubPassAttCount > lastSubPassAttCount)
            {
                return(false);
            }

            uint numEqualAttachments = 0;

            for (int currPassIdx = 0; currPassIdx < currentSubPassAttCount; ++currPassIdx)
            {
                for (int lastPassIdx = 0; lastPassIdx < lastSubPassAttCount; ++lastPassIdx)
                {
                    if (currentSubPass.m_ColorAttachmentIndices[currPassIdx] == lastSubPass.m_ColorAttachmentIndices[lastPassIdx])
                    {
                        numEqualAttachments++;
                    }
                }
            }

            return(numEqualAttachments == currentSubPassAttCount);
        }
Esempio n. 2
0
 internal static RTHandle GetFirstAllocatedRTHandle(ScriptableRenderPass pass)
 {
     for (int i = 0; i < pass.colorAttachmentHandles.Length; ++i)
     {
         if (pass.colorAttachmentHandles[i].rt != null)
         {
             return(pass.colorAttachmentHandles[i]);
         }
     }
     return(pass.colorAttachmentHandles[0]);
 }
Esempio n. 3
0
        internal void UpdateFinalStoreActions(int[] currentMergeablePasses, CameraData cameraData)
        {
            for (int i = 0; i < m_FinalColorStoreAction.Length; ++i)
            {
                m_FinalColorStoreAction[i] = RenderBufferStoreAction.Store;
            }
            m_FinalDepthStoreAction = RenderBufferStoreAction.Store;

            foreach (var passIdx in currentMergeablePasses)
            {
                if (!m_UseOptimizedStoreActions)
                {
                    break;
                }

                if (passIdx == -1)
                {
                    break;
                }

                ScriptableRenderPass pass = m_ActiveRenderPassQueue[passIdx];

                var samples = pass.renderTargetSampleCount != -1
                    ? pass.renderTargetSampleCount
                    : cameraData.cameraTargetDescriptor.msaaSamples;

                // only override existing non destructive actions
                for (int i = 0; i < m_FinalColorStoreAction.Length; ++i)
                {
                    if (m_FinalColorStoreAction[i] == RenderBufferStoreAction.Store || m_FinalColorStoreAction[i] == RenderBufferStoreAction.StoreAndResolve || pass.overriddenColorStoreActions[i])
                    {
                        m_FinalColorStoreAction[i] = pass.colorStoreActions[i];
                    }

                    if (samples > 1)
                    {
                        if (m_FinalColorStoreAction[i] == RenderBufferStoreAction.Store)
                        {
                            m_FinalColorStoreAction[i] = RenderBufferStoreAction.StoreAndResolve;
                        }
                        else if (m_FinalColorStoreAction[i] == RenderBufferStoreAction.DontCare)
                        {
                            m_FinalColorStoreAction[i] = RenderBufferStoreAction.Resolve;
                        }
                    }
                }

                // only override existing store
                if (m_FinalDepthStoreAction == RenderBufferStoreAction.Store || (m_FinalDepthStoreAction == RenderBufferStoreAction.StoreAndResolve && pass.depthStoreAction == RenderBufferStoreAction.Resolve) || pass.overriddenDepthStoreAction)
                {
                    m_FinalDepthStoreAction = pass.depthStoreAction;
                }
            }
        }
Esempio n. 4
0
        internal static uint GetSubPassAttachmentIndicesCount(ScriptableRenderPass pass)
        {
            uint numValidAttachments = 0;

            foreach (var attIdx in pass.m_ColorAttachmentIndices)
            {
                if (attIdx >= 0)
                {
                    ++numValidAttachments;
                }
            }

            return(numValidAttachments);
        }
Esempio n. 5
0
        internal void SetupInputAttachmentIndices(ScriptableRenderPass pass)
        {
            var validInputBufferCount = GetValidInputAttachmentCount(pass);

            pass.m_InputAttachmentIndices = new NativeArray <int>(validInputBufferCount, Allocator.Temp);
            for (int i = 0; i < validInputBufferCount; i++)
            {
                pass.m_InputAttachmentIndices[i] = FindAttachmentDescriptorIndexInList(pass.m_InputAttachments[i], m_ActiveColorAttachmentDescriptors);
                if (pass.m_InputAttachmentIndices[i] == -1)
                {
                    Debug.LogWarning("RenderPass Input attachment not found in the current RenderPass");
                    continue;
                }

                // Assume input attachment has to be transient as ScriptableRenderPass currently has only setters for StoreAction
                m_ActiveColorAttachmentDescriptors[pass.m_InputAttachmentIndices[i]].loadAction  = RenderBufferLoadAction.DontCare;
                m_ActiveColorAttachmentDescriptors[pass.m_InputAttachmentIndices[i]].storeAction = RenderBufferStoreAction.DontCare;
            }
        }
Esempio n. 6
0
        internal static int GetValidInputAttachmentCount(ScriptableRenderPass renderPass)
        {
            var length = renderPass.m_InputAttachments.Length;

            if (length != 8) // overriden, there are attachments
            {
                return(length);
            }
            else
            {
                for (int i = 0; i < length; ++i)
                {
                    if (renderPass.m_InputAttachments[i] == null)
                    {
                        return(i);
                    }
                }
                return(length);
            }
        }
Esempio n. 7
0
        internal void SetupInputAttachmentIndices(ScriptableRenderPass pass)
        {
            var validInputBufferCount = GetValidInputAttachmentCount(pass);

            pass.m_InputAttachmentIndices = new NativeArray <int>(validInputBufferCount, Allocator.Temp);
            for (int i = 0; i < validInputBufferCount; i++)
            {
                pass.m_InputAttachmentIndices[i] = FindAttachmentDescriptorIndexInList(pass.m_InputAttachments[i], m_ActiveColorAttachmentDescriptors);
                if (pass.m_InputAttachmentIndices[i] == -1)
                {
                    Debug.LogWarning("RenderPass Input attachment not found in the current RenderPass");
                    continue;
                }

                // Only update it as long as it has default value - if it was changed once, we assume it'll be memoryless in the whole RenderPass
                if (!m_IsActiveColorAttachmentTransient[pass.m_InputAttachmentIndices[i]])
                {
                    m_IsActiveColorAttachmentTransient[pass.m_InputAttachmentIndices[i]] = pass.IsInputAttachmentTransient(i);
                }
            }
        }
Esempio n. 8
0
        internal void SetupInputAttachmentIndices(ScriptableRenderPass pass)
        {
            var validInputBufferCount = GetValidInputAttachmentCount(pass);

            pass.m_InputAttachmentIndices = new NativeArray <int>(validInputBufferCount, Allocator.Temp);
            for (int i = 0; i < validInputBufferCount; i++)
            {
                pass.m_InputAttachmentIndices[i] = FindAttachmentDescriptorIndexInList(pass.m_InputAttachments[i], m_ActiveColorAttachmentDescriptors);
                if (pass.m_InputAttachmentIndices[i] == -1)
                {
                    Debug.LogWarning("RenderPass Input attachment not found in the current RenderPass");
                    continue;
                }

                // Assume input attachment has to be transient as ScriptableRenderPass currently has only setters for StoreAction
                // We also change the target of the descriptor for it to be initialized engine-side as a transient resource.
                m_ActiveColorAttachmentDescriptors[pass.m_InputAttachmentIndices[i]].loadAction      = RenderBufferLoadAction.DontCare;
                m_ActiveColorAttachmentDescriptors[pass.m_InputAttachmentIndices[i]].storeAction     = RenderBufferStoreAction.DontCare;
                m_ActiveColorAttachmentDescriptors[pass.m_InputAttachmentIndices[i]].loadStoreTarget = BuiltinRenderTextureType.None;
            }
        }
        internal void ConfigureNativeRenderPass(CommandBuffer cmd, ScriptableRenderPass renderPass, CameraData cameraData)
        {
            using (new ProfilingScope(null, Profiling.configure))
            {
                int     currentPassIndex       = renderPass.renderPassQueueIndex;
                Hash128 currentPassHash        = m_PassIndexToPassHash[currentPassIndex];
                int[]   currentMergeablePasses = m_MergeableRenderPassesMap[currentPassHash];

                // If it's the first pass, configure the whole merge block
                if (currentMergeablePasses.First() == currentPassIndex)
                {
                    foreach (var passIdx in currentMergeablePasses)
                    {
                        if (passIdx == -1)
                        {
                            break;
                        }
                        ScriptableRenderPass pass = m_ActiveRenderPassQueue[passIdx];
                        pass.Configure(cmd, cameraData.cameraTargetDescriptor);
                    }
                }
            }
        }
Esempio n. 10
0
        internal void ExecuteNativeRenderPass(ScriptableRenderContext context, ScriptableRenderPass renderPass, CameraData cameraData, ref RenderingData renderingData)
        {
            using (new ProfilingScope(null, Profiling.execute))
            {
                int     currentPassIndex       = renderPass.renderPassQueueIndex;
                Hash128 currentPassHash        = m_PassIndexToPassHash[currentPassIndex];
                int[]   currentMergeablePasses = m_MergeableRenderPassesMap[currentPassHash];

                int validColorBuffersCount = m_RenderPassesAttachmentCount[currentPassHash];

                var  depthOnly = (renderPass.colorAttachmentHandle.rt != null && IsDepthOnlyRenderTexture(renderPass.colorAttachmentHandle.rt)) || (cameraData.targetTexture != null && IsDepthOnlyRenderTexture(cameraData.targetTexture));
                bool useDepth  = depthOnly || (!renderPass.overrideCameraTarget || (renderPass.overrideCameraTarget && renderPass.depthAttachmentHandle.nameID != BuiltinRenderTextureType.CameraTarget));// &&

                var attachments =
                    new NativeArray <AttachmentDescriptor>(useDepth && !depthOnly ? validColorBuffersCount + 1 : 1, Allocator.Temp);

                for (int i = 0; i < validColorBuffersCount; ++i)
                {
                    attachments[i] = m_ActiveColorAttachmentDescriptors[i];
                }

                if (useDepth && !depthOnly)
                {
                    attachments[validColorBuffersCount] = m_ActiveDepthAttachmentDescriptor;
                }

                var rpDesc = InitializeRenderPassDescriptor(cameraData, renderPass);

                int validPassCount = GetValidPassIndexCount(currentMergeablePasses);

                var attachmentIndicesCount = GetSubPassAttachmentIndicesCount(renderPass);

                var attachmentIndices = new NativeArray <int>(!depthOnly ? (int)attachmentIndicesCount : 0, Allocator.Temp);
                if (!depthOnly)
                {
                    for (int i = 0; i < attachmentIndicesCount; ++i)
                    {
                        attachmentIndices[i] = renderPass.m_ColorAttachmentIndices[i];
                    }
                }

                if (validPassCount == 1 || currentMergeablePasses[0] == currentPassIndex) // Check if it's the first pass
                {
                    if (PassHasInputAttachments(renderPass))
                    {
                        Debug.LogWarning("First pass in a RenderPass should not have input attachments.");
                    }

                    context.BeginRenderPass(rpDesc.w, rpDesc.h, Math.Max(rpDesc.samples, 1), attachments,
                                            useDepth ? (!depthOnly ? validColorBuffersCount : 0) : -1);
                    attachments.Dispose();

                    context.BeginSubPass(attachmentIndices);

                    m_LastBeginSubpassPassIndex = currentPassIndex;
                }
                else
                {
                    // Regarding input attachments, currently we always recreate a new subpass if it contains input attachments
                    // This might not the most optimal way though and it should be investigated in the future
                    // Whether merging subpasses with matching input attachments is a more viable option
                    if (!AreAttachmentIndicesCompatible(m_ActiveRenderPassQueue[m_LastBeginSubpassPassIndex], m_ActiveRenderPassQueue[currentPassIndex]))
                    {
                        context.EndSubPass();
                        if (PassHasInputAttachments(m_ActiveRenderPassQueue[currentPassIndex]))
                        {
                            context.BeginSubPass(attachmentIndices, m_ActiveRenderPassQueue[currentPassIndex].m_InputAttachmentIndices);
                        }
                        else
                        {
                            context.BeginSubPass(attachmentIndices);
                        }

                        m_LastBeginSubpassPassIndex = currentPassIndex;
                    }
                    else if (PassHasInputAttachments(m_ActiveRenderPassQueue[currentPassIndex]))
                    {
                        context.EndSubPass();
                        context.BeginSubPass(attachmentIndices, m_ActiveRenderPassQueue[currentPassIndex].m_InputAttachmentIndices);

                        m_LastBeginSubpassPassIndex = currentPassIndex;
                    }
                }

                attachmentIndices.Dispose();

                renderPass.Execute(context, ref renderingData);

                if (validPassCount == 1 || currentMergeablePasses[validPassCount - 1] == currentPassIndex) // Check if it's the last pass
                {
                    context.EndSubPass();
                    context.EndRenderPass();

                    m_LastBeginSubpassPassIndex = 0;
                }

                for (int i = 0; i < m_ActiveColorAttachmentDescriptors.Length; ++i)
                {
                    m_ActiveColorAttachmentDescriptors[i] = RenderingUtils.emptyAttachment;
                    m_IsActiveColorAttachmentTransient[i] = false;
                }

                m_ActiveDepthAttachmentDescriptor = RenderingUtils.emptyAttachment;
            }
        }
Esempio n. 11
0
        internal void SetNativeRenderPassMRTAttachmentList(ScriptableRenderPass renderPass, ref CameraData cameraData, bool needCustomCameraColorClear, ClearFlag cameraClearFlag)
        {
            using (new ProfilingScope(null, Profiling.setMRTAttachmentsList))
            {
                int     currentPassIndex       = renderPass.renderPassQueueIndex;
                Hash128 currentPassHash        = m_PassIndexToPassHash[currentPassIndex];
                int[]   currentMergeablePasses = m_MergeableRenderPassesMap[currentPassHash];

                // Not the first pass
                if (currentMergeablePasses.First() != currentPassIndex)
                {
                    return;
                }

                m_RenderPassesAttachmentCount[currentPassHash] = 0;

                UpdateFinalStoreActions(currentMergeablePasses, cameraData);

                int  currentAttachmentIdx = 0;
                bool hasInput             = false;
                foreach (var passIdx in currentMergeablePasses)
                {
                    if (passIdx == -1)
                    {
                        break;
                    }
                    ScriptableRenderPass pass = m_ActiveRenderPassQueue[passIdx];

                    for (int i = 0; i < pass.m_ColorAttachmentIndices.Length; ++i)
                    {
                        pass.m_ColorAttachmentIndices[i] = -1;
                    }

                    for (int i = 0; i < pass.m_InputAttachmentIndices.Length; ++i)
                    {
                        pass.m_InputAttachmentIndices[i] = -1;
                    }

                    uint validColorBuffersCount = RenderingUtils.GetValidColorBufferCount(pass.colorAttachmentHandles);

                    for (int i = 0; i < validColorBuffersCount; ++i)
                    {
                        AttachmentDescriptor currentAttachmentDescriptor =
                            new AttachmentDescriptor(pass.renderTargetFormat[i] != GraphicsFormat.None ? pass.renderTargetFormat[i] : GetDefaultGraphicsFormat(cameraData));

                        var colorHandle = pass.overrideCameraTarget ? pass.colorAttachmentHandles[i] : m_CameraColorTarget.handle;

                        int existingAttachmentIndex = FindAttachmentDescriptorIndexInList(colorHandle.nameID, m_ActiveColorAttachmentDescriptors);

                        if (m_UseOptimizedStoreActions)
                        {
                            currentAttachmentDescriptor.storeAction = m_FinalColorStoreAction[i];
                        }

                        if (existingAttachmentIndex == -1)
                        {
                            // add a new attachment
                            m_ActiveColorAttachmentDescriptors[currentAttachmentIdx] = currentAttachmentDescriptor;
                            bool passHasClearColor = (pass.clearFlag & ClearFlag.Color) != 0;
                            m_ActiveColorAttachmentDescriptors[currentAttachmentIdx].ConfigureTarget(colorHandle.nameID, !passHasClearColor, true);

                            if (pass.colorAttachmentHandles[i] == m_CameraColorTarget.handle && needCustomCameraColorClear && (cameraClearFlag & ClearFlag.Color) != 0)
                            {
                                m_ActiveColorAttachmentDescriptors[currentAttachmentIdx].ConfigureClear(cameraData.backgroundColor, 1.0f, 0);
                            }
                            else if (passHasClearColor)
                            {
                                m_ActiveColorAttachmentDescriptors[currentAttachmentIdx].ConfigureClear(CoreUtils.ConvertSRGBToActiveColorSpace(pass.clearColor), 1.0f, 0);
                            }

                            pass.m_ColorAttachmentIndices[i] = currentAttachmentIdx;
                            currentAttachmentIdx++;
                            m_RenderPassesAttachmentCount[currentPassHash]++;
                        }
                        else
                        {
                            // attachment was already present
                            pass.m_ColorAttachmentIndices[i] = existingAttachmentIndex;
                        }
                    }

                    if (PassHasInputAttachments(pass))
                    {
                        hasInput = true;
                        SetupInputAttachmentIndices(pass);
                    }

                    // TODO: this is redundant and is being setup for each attachment. Needs to be done only once per mergeable pass list (we need to make sure mergeable passes use the same depth!)
                    m_ActiveDepthAttachmentDescriptor = new AttachmentDescriptor(SystemInfo.GetGraphicsFormat(DefaultFormat.DepthStencil));
                    bool passHasClearDepth = (cameraClearFlag & ClearFlag.DepthStencil) != 0;
                    m_ActiveDepthAttachmentDescriptor.ConfigureTarget(pass.overrideCameraTarget ? pass.depthAttachmentHandle.nameID : m_CameraDepthTarget.nameID, !passHasClearDepth, true);

                    if (passHasClearDepth)
                    {
                        m_ActiveDepthAttachmentDescriptor.ConfigureClear(Color.black, 1.0f, 0);
                    }

                    if (m_UseOptimizedStoreActions)
                    {
                        m_ActiveDepthAttachmentDescriptor.storeAction = m_FinalDepthStoreAction;
                    }
                }

                if (hasInput)
                {
                    SetupTransientInputAttachments(m_RenderPassesAttachmentCount[currentPassHash]);
                }
            }
        }
        private static RenderPassDescriptor InitializeRenderPassDescriptor(CameraData cameraData, ScriptableRenderPass renderPass)
        {
            var w       = (renderPass.renderTargetWidth != -1) ? renderPass.renderTargetWidth : cameraData.cameraTargetDescriptor.width;
            var h       = (renderPass.renderTargetHeight != -1) ? renderPass.renderTargetHeight : cameraData.cameraTargetDescriptor.height;
            var samples = (renderPass.renderTargetSampleCount != -1) ? renderPass.renderTargetSampleCount : cameraData.cameraTargetDescriptor.msaaSamples;
            var depthID = renderPass.depthOnly ? renderPass.colorAttachment.GetHashCode() : renderPass.depthAttachment.GetHashCode();

            return(new RenderPassDescriptor(w, h, samples, depthID));
        }
        internal void ExecuteNativeRenderPass(ScriptableRenderContext context, ScriptableRenderPass renderPass, CameraData cameraData, ref RenderingData renderingData)
        {
            using (new ProfilingScope(null, Profiling.execute))
            {
                int     currentPassIndex       = renderPass.renderPassQueueIndex;
                Hash128 currentPassHash        = m_PassIndexToPassHash[currentPassIndex];
                int[]   currentMergeablePasses = m_MergeableRenderPassesMap[currentPassHash];

                int validColorBuffersCount = m_RenderPassesAttachmentCount[currentPassHash];

                bool isLastPass = renderPass.isLastPass;
                // TODO: review the lastPassToBB logic to mak it work with merged passes
                // keep track if this is the current camera's last pass and the RT is the backbuffer (BuiltinRenderTextureType.CameraTarget)
                bool isLastPassToBB = isLastPass && (m_ActiveColorAttachmentDescriptors[0].loadStoreTarget ==
                                                     BuiltinRenderTextureType.CameraTarget);
                var  depthOnly = renderPass.depthOnly || (cameraData.targetTexture != null && cameraData.targetTexture.graphicsFormat == GraphicsFormat.DepthAuto);
                bool useDepth  = depthOnly || (!renderPass.overrideCameraTarget || (renderPass.overrideCameraTarget && renderPass.depthAttachment != BuiltinRenderTextureType.CameraTarget)) &&
                                 (!(isLastPassToBB || (isLastPass && cameraData.camera.targetTexture != null)));

                var attachments =
                    new NativeArray <AttachmentDescriptor>(useDepth && !depthOnly ? validColorBuffersCount + 1 : 1,
                                                           Allocator.Temp);

                for (int i = 0; i < validColorBuffersCount; ++i)
                {
                    attachments[i] = m_ActiveColorAttachmentDescriptors[i];
                }

                if (useDepth && !depthOnly)
                {
                    attachments[validColorBuffersCount] = m_ActiveDepthAttachmentDescriptor;
                }

                var rpDesc = InitializeRenderPassDescriptor(cameraData, renderPass);

                int validPassCount = GetValidPassIndexCount(currentMergeablePasses);

                var attachmentIndicesCount = GetSubPassAttachmentIndicesCount(renderPass);

                var attachmentIndices = new NativeArray <int>(!depthOnly ? (int)attachmentIndicesCount : 0, Allocator.Temp);
                if (!depthOnly)
                {
                    for (int i = 0; i < attachmentIndicesCount; ++i)
                    {
                        attachmentIndices[i] = renderPass.m_InputAttachmentIndices[i];
                    }
                }

                if (validPassCount == 1 || currentMergeablePasses[0] == currentPassIndex) // Check if it's the first pass
                {
                    context.BeginRenderPass(rpDesc.w, rpDesc.h, Math.Max(rpDesc.samples, 1), attachments,
                                            useDepth ? (!depthOnly ? validColorBuffersCount : 0) : -1);
                    attachments.Dispose();

                    context.BeginSubPass(attachmentIndices);

                    m_LastBeginSubpassPassIndex = currentPassIndex;
                }
                else
                {
                    if (!AreAttachmentIndicesCompatible(m_ActiveRenderPassQueue[m_LastBeginSubpassPassIndex], m_ActiveRenderPassQueue[currentPassIndex]))
                    {
                        context.EndSubPass();
                        context.BeginSubPass(attachmentIndices);

                        m_LastBeginSubpassPassIndex = currentPassIndex;
                    }
                }

                attachmentIndices.Dispose();

                renderPass.Execute(context, ref renderingData);

                if (validPassCount == 1 || currentMergeablePasses[validPassCount - 1] == currentPassIndex) // Check if it's the last pass
                {
                    context.EndSubPass();
                    context.EndRenderPass();

                    m_LastBeginSubpassPassIndex = 0;
                }

                for (int i = 0; i < m_ActiveColorAttachmentDescriptors.Length; ++i)
                {
                    m_ActiveColorAttachmentDescriptors[i] = RenderingUtils.emptyAttachment;
                }

                m_ActiveDepthAttachmentDescriptor = RenderingUtils.emptyAttachment;
            }
        }
        internal void SetNativeRenderPassAttachmentList(ScriptableRenderPass renderPass, ref CameraData cameraData, RenderTargetIdentifier passColorAttachment, RenderTargetIdentifier passDepthAttachment, ClearFlag finalClearFlag, Color finalClearColor)
        {
            using (new ProfilingScope(null, Profiling.setAttachmentList))
            {
                int     currentPassIndex       = renderPass.renderPassQueueIndex;
                Hash128 currentPassHash        = m_PassIndexToPassHash[currentPassIndex];
                int[]   currentMergeablePasses = m_MergeableRenderPassesMap[currentPassHash];

                // Skip if not the first pass
                if (currentMergeablePasses.First() != currentPassIndex)
                {
                    return;
                }

                m_RenderPassesAttachmentCount[currentPassHash] = 0;

                int currentAttachmentIdx = 0;
                foreach (var passIdx in currentMergeablePasses)
                {
                    if (passIdx == -1)
                    {
                        break;
                    }
                    ScriptableRenderPass pass = m_ActiveRenderPassQueue[passIdx];

                    for (int i = 0; i < pass.m_InputAttachmentIndices.Length; ++i)
                    {
                        pass.m_InputAttachmentIndices[i] = -1;
                    }

                    AttachmentDescriptor currentAttachmentDescriptor;
                    var usesTargetTexture = cameraData.targetTexture != null;
                    var depthOnly         = renderPass.depthOnly || (usesTargetTexture && cameraData.targetTexture.graphicsFormat == GraphicsFormat.DepthAuto);
                    // Offscreen depth-only cameras need this set explicitly
                    if (depthOnly && usesTargetTexture)
                    {
                        if (cameraData.targetTexture.graphicsFormat == GraphicsFormat.DepthAuto && !pass.overrideCameraTarget)
                        {
                            passColorAttachment = new RenderTargetIdentifier(cameraData.targetTexture);
                        }
                        else
                        {
                            passColorAttachment = renderPass.colorAttachment;
                        }
                        currentAttachmentDescriptor = new AttachmentDescriptor(GraphicsFormat.DepthAuto);
                    }
                    else
                    {
                        currentAttachmentDescriptor =
                            new AttachmentDescriptor(cameraData.cameraTargetDescriptor.graphicsFormat);
                    }

                    if (pass.overrideCameraTarget)
                    {
                        currentAttachmentDescriptor = new AttachmentDescriptor(pass.renderTargetFormat[0] != GraphicsFormat.None ? pass.renderTargetFormat[0] : GetDefaultGraphicsFormat(cameraData));
                    }

                    var samples = pass.renderTargetSampleCount != -1
                        ? pass.renderTargetSampleCount
                        : cameraData.cameraTargetDescriptor.msaaSamples;

                    var colorAttachmentTarget =
                        (depthOnly || passColorAttachment != BuiltinRenderTextureType.CameraTarget)
                        ? passColorAttachment : (usesTargetTexture
                            ? new RenderTargetIdentifier(cameraData.targetTexture.colorBuffer)
                            : BuiltinRenderTextureType.CameraTarget);

                    var depthAttachmentTarget = (passDepthAttachment != BuiltinRenderTextureType.CameraTarget) ?
                                                passDepthAttachment : (usesTargetTexture
                            ? new RenderTargetIdentifier(cameraData.targetTexture.depthBuffer)
                            : BuiltinRenderTextureType.Depth);

                    // TODO: review the lastPassToBB logic to mak it work with merged passes
                    // keep track if this is the current camera's last pass and the RT is the backbuffer (BuiltinRenderTextureType.CameraTarget)
                    // knowing isLastPassToBB can help decide the optimal store action as it gives us additional information about the current frame
                    bool isLastPassToBB = pass.isLastPass && (colorAttachmentTarget == BuiltinRenderTextureType.CameraTarget);
                    currentAttachmentDescriptor.ConfigureTarget(colorAttachmentTarget, ((uint)finalClearFlag & (uint)ClearFlag.Color) == 0, !(samples > 1 && isLastPassToBB));

                    // TODO: this is redundant and is being setup for each attachment. Needs to be done only once per mergeable pass list (we need to make sure mergeable passes use the same depth!)
                    m_ActiveDepthAttachmentDescriptor = new AttachmentDescriptor(GraphicsFormat.DepthAuto);
                    m_ActiveDepthAttachmentDescriptor.ConfigureTarget(depthAttachmentTarget,
                                                                      ((uint)finalClearFlag & (uint)ClearFlag.Depth) == 0, !isLastPassToBB);

                    if (finalClearFlag != ClearFlag.None)
                    {
                        // We don't clear color for Overlay render targets, however pipeline set's up depth only render passes as color attachments which we do need to clear
                        if ((cameraData.renderType != CameraRenderType.Overlay || depthOnly && ((uint)finalClearFlag & (uint)ClearFlag.Color) != 0))
                        {
                            currentAttachmentDescriptor.ConfigureClear(finalClearColor, 1.0f, 0);
                        }
                        if (((uint)finalClearFlag & (uint)ClearFlag.Depth) != 0)
                        {
                            m_ActiveDepthAttachmentDescriptor.ConfigureClear(Color.black, 1.0f, 0);
                        }
                    }

                    // resolving to the implicit color target's resolve surface TODO: handle m_CameraResolveTarget if present?
                    if (samples > 1)
                    {
                        currentAttachmentDescriptor.ConfigureResolveTarget(colorAttachmentTarget);
                    }

                    int existingAttachmentIndex = FindAttachmentDescriptorIndexInList(currentAttachmentIdx,
                                                                                      currentAttachmentDescriptor, m_ActiveColorAttachmentDescriptors);

                    if (existingAttachmentIndex == -1)
                    {
                        // add a new attachment
                        pass.m_InputAttachmentIndices[0] = currentAttachmentIdx;
                        m_ActiveColorAttachmentDescriptors[currentAttachmentIdx] = currentAttachmentDescriptor;
                        currentAttachmentIdx++;
                        m_RenderPassesAttachmentCount[currentPassHash]++;
                    }
                    else
                    {
                        // attachment was already present
                        pass.m_InputAttachmentIndices[0] = existingAttachmentIndex;
                    }
                }
            }
        }
        internal void SetNativeRenderPassMRTAttachmentList(ScriptableRenderPass renderPass, ref CameraData cameraData, uint validColorBuffersCount, bool needCustomCameraColorClear, ClearFlag clearFlag)
        {
            using (new ProfilingScope(null, Profiling.setMRTAttachmentsList))
            {
                int     currentPassIndex       = renderPass.renderPassQueueIndex;
                Hash128 currentPassHash        = m_PassIndexToPassHash[currentPassIndex];
                int[]   currentMergeablePasses = m_MergeableRenderPassesMap[currentPassHash];

                // Not the first pass
                if (currentMergeablePasses.First() != currentPassIndex)
                {
                    return;
                }

                m_RenderPassesAttachmentCount[currentPassHash] = 0;

                int currentAttachmentIdx = 0;
                foreach (var passIdx in currentMergeablePasses)
                {
                    if (passIdx == -1)
                    {
                        break;
                    }
                    ScriptableRenderPass pass = m_ActiveRenderPassQueue[passIdx];

                    for (int i = 0; i < pass.m_InputAttachmentIndices.Length; ++i)
                    {
                        pass.m_InputAttachmentIndices[i] = -1;
                    }

                    // TODO: review the lastPassToBB logic to mak it work with merged passes
                    bool isLastPassToBB = false;

                    for (int i = 0; i < validColorBuffersCount; ++i)
                    {
                        AttachmentDescriptor currentAttachmentDescriptor =
                            new AttachmentDescriptor(pass.renderTargetFormat[i] != GraphicsFormat.None ? pass.renderTargetFormat[i] : GetDefaultGraphicsFormat(cameraData));

                        // if this is the current camera's last pass, also check if one of the RTs is the backbuffer (BuiltinRenderTextureType.CameraTarget)
                        isLastPassToBB |= pass.isLastPass && (pass.colorAttachments[i] == BuiltinRenderTextureType.CameraTarget);

                        int existingAttachmentIndex = FindAttachmentDescriptorIndexInList(currentAttachmentIdx,
                                                                                          currentAttachmentDescriptor, m_ActiveColorAttachmentDescriptors);

                        if (existingAttachmentIndex == -1)
                        {
                            // add a new attachment
                            m_ActiveColorAttachmentDescriptors[currentAttachmentIdx] = currentAttachmentDescriptor;

                            m_ActiveColorAttachmentDescriptors[currentAttachmentIdx].ConfigureTarget(pass.colorAttachments[i], (clearFlag & ClearFlag.Color) == 0, true);

                            if ((clearFlag & ClearFlag.Color) != 0)
                            {
                                var clearColor = (needCustomCameraColorClear && pass.colorAttachments[i] == m_CameraColorTarget) ? cameraData.camera.backgroundColor : renderPass.clearColor;
                                m_ActiveColorAttachmentDescriptors[currentAttachmentIdx].ConfigureClear(CoreUtils.ConvertSRGBToActiveColorSpace(clearColor), 1.0f, 0);
                            }

                            pass.m_InputAttachmentIndices[i] = currentAttachmentIdx;

                            currentAttachmentIdx++;
                            m_RenderPassesAttachmentCount[currentPassHash]++;
                        }
                        else
                        {
                            // attachment was already present
                            pass.m_InputAttachmentIndices[i] = existingAttachmentIndex;
                        }
                    }

                    // TODO: this is redundant and is being setup for each attachment. Needs to be done only once per mergeable pass list (we need to make sure mergeable passes use the same depth!)
                    m_ActiveDepthAttachmentDescriptor = new AttachmentDescriptor(GraphicsFormat.DepthAuto);
                    m_ActiveDepthAttachmentDescriptor.ConfigureTarget(pass.depthAttachment, (clearFlag & ClearFlag.DepthStencil) == 0, !isLastPassToBB);
                    if ((clearFlag & ClearFlag.DepthStencil) != 0)
                    {
                        m_ActiveDepthAttachmentDescriptor.ConfigureClear(Color.black, 1.0f, 0);
                    }
                }
            }
        }
Esempio n. 16
0
 internal static bool PassHasInputAttachments(ScriptableRenderPass renderPass)
 {
     return(renderPass.m_InputAttachments.Length != 8 || renderPass.m_InputAttachments[0] != null);
 }
Esempio n. 17
0
        private RenderPassDescriptor InitializeRenderPassDescriptor(CameraData cameraData, ScriptableRenderPass renderPass)
        {
            RenderTextureDescriptor targetRT;

            if (!renderPass.overrideCameraTarget || (renderPass.colorAttachmentHandle.rt == null && renderPass.depthAttachmentHandle.rt == null))
            {
                targetRT = cameraData.cameraTargetDescriptor;

                // In this case we want to rely on the pixelWidth/Height as the texture could be scaled from a script later and etc.
                // and it's new dimensions might not be reflected on the targetTexture. This also applies to camera stacks rendering to a target texture.
                if (cameraData.targetTexture != null)
                {
                    targetRT.width  = cameraData.pixelWidth;
                    targetRT.height = cameraData.pixelHeight;
                }
            }
            else
            {
                var handle = GetFirstAllocatedRTHandle(renderPass);
                targetRT = handle.rt != null ? handle.rt.descriptor : renderPass.depthAttachmentHandle.rt.descriptor;
            }

            var depthTarget = renderPass.overrideCameraTarget ? renderPass.depthAttachmentHandle : cameraDepthTargetHandle;
            var depthID     = (targetRT.graphicsFormat == GraphicsFormat.None && targetRT.depthStencilFormat != GraphicsFormat.None) ? renderPass.colorAttachmentHandle.GetHashCode() : depthTarget.GetHashCode();

            return(new RenderPassDescriptor(targetRT.width, targetRT.height, targetRT.msaaSamples, depthID));
        }
Esempio n. 18
0
        internal void SetNativeRenderPassAttachmentList(ScriptableRenderPass renderPass, ref CameraData cameraData, RTHandle passColorAttachment, RTHandle passDepthAttachment, ClearFlag finalClearFlag, Color finalClearColor)
        {
            using (new ProfilingScope(null, Profiling.setAttachmentList))
            {
                int     currentPassIndex       = renderPass.renderPassQueueIndex;
                Hash128 currentPassHash        = m_PassIndexToPassHash[currentPassIndex];
                int[]   currentMergeablePasses = m_MergeableRenderPassesMap[currentPassHash];

                // Skip if not the first pass
                if (currentMergeablePasses.First() != currentPassIndex)
                {
                    return;
                }

                m_RenderPassesAttachmentCount[currentPassHash] = 0;

                UpdateFinalStoreActions(currentMergeablePasses, cameraData);

                int currentAttachmentIdx = 0;
                foreach (var passIdx in currentMergeablePasses)
                {
                    if (passIdx == -1)
                    {
                        break;
                    }
                    ScriptableRenderPass pass = m_ActiveRenderPassQueue[passIdx];

                    for (int i = 0; i < pass.m_ColorAttachmentIndices.Length; ++i)
                    {
                        pass.m_ColorAttachmentIndices[i] = -1;
                    }

                    AttachmentDescriptor currentAttachmentDescriptor;
                    var usesTargetTexture = cameraData.targetTexture != null;
                    var depthOnly         = (pass.colorAttachmentHandle.rt != null && IsDepthOnlyRenderTexture(pass.colorAttachmentHandle.rt)) || (usesTargetTexture && IsDepthOnlyRenderTexture(cameraData.targetTexture));

                    int samples;
                    RenderTargetIdentifier colorAttachmentTarget;
                    // We are not rendering to Backbuffer so we have the RT and the information with it
                    // while also creating a new RenderTargetIdentifier to ignore the current depth slice (which might get bypassed in XR setup eventually)
                    if (new RenderTargetIdentifier(passColorAttachment.nameID, 0, depthSlice: 0) != BuiltinRenderTextureType.CameraTarget)
                    {
                        currentAttachmentDescriptor = new AttachmentDescriptor(depthOnly ? passColorAttachment.rt.descriptor.depthStencilFormat : passColorAttachment.rt.descriptor.graphicsFormat);
                        samples = passColorAttachment.rt.descriptor.msaaSamples;
                        colorAttachmentTarget = passColorAttachment.nameID;
                    }
                    else // In this case we might be rendering the the targetTexture or the Backbuffer, so less information is available
                    {
                        currentAttachmentDescriptor = new AttachmentDescriptor(GetDefaultGraphicsFormat(cameraData, depthOnly));
                        samples = cameraData.cameraTargetDescriptor.msaaSamples;
                        colorAttachmentTarget = usesTargetTexture ? new RenderTargetIdentifier(cameraData.targetTexture) : BuiltinRenderTextureType.CameraTarget;
                    }

                    currentAttachmentDescriptor.ConfigureTarget(colorAttachmentTarget, ((uint)finalClearFlag & (uint)ClearFlag.Color) == 0, true);

                    if (PassHasInputAttachments(pass))
                    {
                        SetupInputAttachmentIndices(pass);
                    }

                    // TODO: this is redundant and is being setup for each attachment. Needs to be done only once per mergeable pass list (we need to make sure mergeable passes use the same depth!)
                    m_ActiveDepthAttachmentDescriptor = new AttachmentDescriptor(SystemInfo.GetGraphicsFormat(DefaultFormat.DepthStencil));
                    m_ActiveDepthAttachmentDescriptor.ConfigureTarget(passDepthAttachment.nameID != BuiltinRenderTextureType.CameraTarget ? passDepthAttachment.nameID :
                                                                      (usesTargetTexture ? new RenderTargetIdentifier(cameraData.targetTexture.depthBuffer) : BuiltinRenderTextureType.Depth),
                                                                      ((uint)finalClearFlag & (uint)ClearFlag.Depth) == 0, true);

                    if (finalClearFlag != ClearFlag.None)
                    {
                        // We don't clear color for Overlay render targets, however pipeline set's up depth only render passes as color attachments which we do need to clear
                        if ((cameraData.renderType != CameraRenderType.Overlay || depthOnly && ((uint)finalClearFlag & (uint)ClearFlag.Color) != 0))
                        {
                            currentAttachmentDescriptor.ConfigureClear(finalClearColor, 1.0f, 0);
                        }
                        if (((uint)finalClearFlag & (uint)ClearFlag.Depth) != 0)
                        {
                            m_ActiveDepthAttachmentDescriptor.ConfigureClear(Color.black, 1.0f, 0);
                        }
                    }

                    // resolving to the implicit color target's resolve surface TODO: handle m_CameraResolveTarget if present?
                    if (samples > 1)
                    {
                        currentAttachmentDescriptor.ConfigureResolveTarget(colorAttachmentTarget);
                        if (RenderingUtils.MultisampleDepthResolveSupported())
                        {
                            m_ActiveDepthAttachmentDescriptor.ConfigureResolveTarget(m_ActiveDepthAttachmentDescriptor.loadStoreTarget);
                        }
                    }


                    if (m_UseOptimizedStoreActions)
                    {
                        currentAttachmentDescriptor.storeAction       = m_FinalColorStoreAction[0];
                        m_ActiveDepthAttachmentDescriptor.storeAction = m_FinalDepthStoreAction;
                    }

                    int existingAttachmentIndex = FindAttachmentDescriptorIndexInList(currentAttachmentIdx,
                                                                                      currentAttachmentDescriptor, m_ActiveColorAttachmentDescriptors);

                    if (existingAttachmentIndex == -1)
                    {
                        // add a new attachment
                        pass.m_ColorAttachmentIndices[0] = currentAttachmentIdx;
                        m_ActiveColorAttachmentDescriptors[currentAttachmentIdx] = currentAttachmentDescriptor;
                        currentAttachmentIdx++;
                        m_RenderPassesAttachmentCount[currentPassHash]++;
                    }
                    else
                    {
                        // attachment was already present
                        pass.m_ColorAttachmentIndices[0] = existingAttachmentIndex;
                    }
                }
            }
        }